|
@@ -1,465 +0,0 @@
|
|
-using System;
|
|
|
|
-using System.Collections.Generic;
|
|
|
|
-using System.Linq;
|
|
|
|
-using System.Security;
|
|
|
|
-using System.ServiceModel;
|
|
|
|
-using System.Text;
|
|
|
|
-using Aitex.Core.RT.DataCenter;
|
|
|
|
-using Aitex.Core.RT.Device;
|
|
|
|
-using Aitex.Core.RT.Event;
|
|
|
|
-using Aitex.Core.RT.Log;
|
|
|
|
-using Aitex.Core.RT.OperationCenter;
|
|
|
|
-using Aitex.Core.RT.SCCore;
|
|
|
|
-using Aitex.Core.Util;
|
|
|
|
-using Aitex.Core.WCF;
|
|
|
|
-using EPInterface;
|
|
|
|
-using EPInterface.Data;
|
|
|
|
-using EPInterface.Datas;
|
|
|
|
-
|
|
|
|
-namespace Aitex.RT.Device.Custom
|
|
|
|
-{
|
|
|
|
- public class EPDDevice : BaseDevice, IDevice
|
|
|
|
- {
|
|
|
|
- private PeriodicJob _monitorThead;
|
|
|
|
-
|
|
|
|
- private R_TRIG _triggerConnected = new R_TRIG();
|
|
|
|
- private R_TRIG _triggerNotConnected = new R_TRIG();
|
|
|
|
-
|
|
|
|
- private int _channel;
|
|
|
|
-
|
|
|
|
- private string _channelStatus;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- //private bool _enableRetry = true;
|
|
|
|
-
|
|
|
|
- private object _lockerTrigger = new object();
|
|
|
|
-
|
|
|
|
- private bool _isEnd = false;
|
|
|
|
-
|
|
|
|
- public bool IsEnd
|
|
|
|
- {
|
|
|
|
- get
|
|
|
|
- {
|
|
|
|
- return _isEnd;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public bool IsConnected
|
|
|
|
- {
|
|
|
|
- get
|
|
|
|
- {
|
|
|
|
- return _triggerConnected.M;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //private bool _isRecipeStarted;
|
|
|
|
- //private bool _isStepStarted;
|
|
|
|
-
|
|
|
|
- private int _connectionCounter = 0;
|
|
|
|
-
|
|
|
|
- public EPDDevice(string module, string name) :
|
|
|
|
- base(module, name, name, name)
|
|
|
|
- {
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public bool Initialize()
|
|
|
|
- {
|
|
|
|
- _channel = SC.GetValue<int>($"{Module}.{Name}.ChannelNumber");
|
|
|
|
-
|
|
|
|
- DATA.Subscribe($"{Module}.{Name}.IsConnected", ()=> IsConnected);
|
|
|
|
- DATA.Subscribe($"{Module}.{Name}.CurrentChannel", () => _channel);
|
|
|
|
- DATA.Subscribe($"{Module}.{Name}.ChannelStatus", () => _channelStatus);
|
|
|
|
-
|
|
|
|
- OP.Subscribe($"{Module}.{Name}.SetConfig", (out string reason, int time, object[] args) => {
|
|
|
|
-
|
|
|
|
- if (!IsConnected)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.WARN_ENDPOINT, Module, $"{Module} {Name} not connected, can not set config");
|
|
|
|
- reason = $"{Module} {Name} not connected, can not set config";
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _isEnd = false;
|
|
|
|
-
|
|
|
|
- StepStart(args[1].ToString(), Convert.ToInt32(args[0]));
|
|
|
|
-
|
|
|
|
- reason = "";
|
|
|
|
- return true;
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
- _monitorThead = new PeriodicJob(100, OnTimer, "EPDMonitor", true);
|
|
|
|
-
|
|
|
|
- EPDCallbackClient.Instance.Notify += Instance_Notify;
|
|
|
|
- EPDCallbackClient.Instance.Trigger += Instance_Trigger;
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void RecipeStart(string recipeName)
|
|
|
|
- {
|
|
|
|
- if (!IsConnected)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, "EPD not connected, call recipe start ignored");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, Notify EPD recipe {recipeName} start");
|
|
|
|
-
|
|
|
|
- EPDClient.Instance.Service.RecipeStart(_channel, recipeName);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void RecipeStop()
|
|
|
|
- {
|
|
|
|
- if (!IsConnected)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, "EPD not connected, call recipe start ignored");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, Notify EPD recipe stopped");
|
|
|
|
-
|
|
|
|
- EPDClient.Instance.Service.RecipeStop(_channel);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * ExposureTime=222;WaveLengthA=2;BinningA=3;WaveLengthB=4;BinningB=6;WaveLengthC=5;BinningC=8;
|
|
|
|
- * WaveLengthD=7;BinningD=9;Fd=1;PrefilterTime=2;PostfilterTime=3;AlgorithmType=Valley;
|
|
|
|
- * Criteria=4;DelayTime=5;ValidationTime=6;ValidationValue=7;
|
|
|
|
- * TimeWindow=8;MinimalTime=9;PostponeTime=10;Control=11;Normalization=12;
|
|
|
|
- * EnablePostponePercent=True;EnableCriterialPercent=True;
|
|
|
|
- * TriggerMode=System.Windows.Controls.ComboBoxItem: Event;IsFaultIfNoTrigger=True;
|
|
|
|
- */
|
|
|
|
- public void StepStart(string config, int index)
|
|
|
|
- {
|
|
|
|
- if (!IsConnected)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, "EPD not connected, call step start ignored");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, Notify EPD recipe step {index+1} start");
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, EPD config {config}");
|
|
|
|
-
|
|
|
|
- try
|
|
|
|
- {
|
|
|
|
- EPDConfig epd = new EPDConfig();
|
|
|
|
-
|
|
|
|
- epd.nParameterCount = 1;
|
|
|
|
-
|
|
|
|
- string[] items = config.Split(';');
|
|
|
|
- foreach (var item in items)
|
|
|
|
- {
|
|
|
|
- if (string.IsNullOrEmpty(item))
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- string[] pairs = item.Split('=');
|
|
|
|
- if (pairs.Length != 2)
|
|
|
|
- continue;
|
|
|
|
-
|
|
|
|
- switch (pairs[0])
|
|
|
|
- {
|
|
|
|
- case "ExposureTime":
|
|
|
|
- epd.Columns[0].nCCDExposureTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "WaveLengthA":
|
|
|
|
- epd.Columns[0].nWaveLength[0] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "BinningA":
|
|
|
|
- epd.Columns[0].nBinning[0] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "WaveLengthB":
|
|
|
|
- epd.Columns[0].nWaveLength[1] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "BinningB":
|
|
|
|
- epd.Columns[0].nBinning[1] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "WaveLengthC":
|
|
|
|
- epd.Columns[0].nWaveLength[2] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "BinningC":
|
|
|
|
- epd.Columns[0].nBinning[2] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "WaveLengthD":
|
|
|
|
- epd.Columns[0].nWaveLength[3] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "BinningD":
|
|
|
|
- epd.Columns[0].nBinning[3] = ushort.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "Fd":
|
|
|
|
- epd.Columns[0].cFunc = pairs[1];
|
|
|
|
- break;
|
|
|
|
- case "PrefilterTime":
|
|
|
|
- epd.Columns[0].nPreFilterTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "PostfilterTime":
|
|
|
|
- epd.Columns[0].nPostFilterTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "AlgorithmType":
|
|
|
|
- epd.Columns[0].algorithmType = MapType(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "Criteria":
|
|
|
|
- epd.Columns[0].nCriteria = float.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "DelayTime":
|
|
|
|
- epd.Columns[0].nDelayTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "ValidationTime":
|
|
|
|
- epd.Columns[0].nValidationTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "ValidationValue":
|
|
|
|
- epd.Columns[0].nValidationValue = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "TimeWindow":
|
|
|
|
- epd.Columns[0].nTimeWindow = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "MinimalTime":
|
|
|
|
- epd.Columns[0].nMinimalTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "PostponeTime":
|
|
|
|
- epd.Columns[0].nPostponeTime = int.Parse(pairs[1]);
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "Control":
|
|
|
|
- epd.Columns[0].bControl = Convert.ToBoolean(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "Normalization":
|
|
|
|
- epd.Columns[0].bNormalization = Convert.ToBoolean(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "EnablePostponePercent":
|
|
|
|
- epd.Columns[0].bPostponePercent = Convert.ToBoolean(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- case "EnableCriterialPercent":
|
|
|
|
- epd.Columns[0].bCriteriaPercent = Convert.ToBoolean(pairs[1]);
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- case "EnableEventTrigger":
|
|
|
|
- epd.Columns[0].bEvtTrigger = Convert.ToBoolean(pairs[1]);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- EPDClient.Instance.Service.StartByConfig(_channel, index, $"step{index}", epd);
|
|
|
|
- }
|
|
|
|
- catch (Exception ex)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, ex.ToString());
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, Step {index + 1} config values not valid, {ex.Message}");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private AlgorithmType MapType(string type)
|
|
|
|
- {
|
|
|
|
- switch (type)
|
|
|
|
- {
|
|
|
|
- case "Unknown": return AlgorithmType.ALG_NONE;
|
|
|
|
- case "Above_ABS_Value": return AlgorithmType.ALG_RISE_VALUE;
|
|
|
|
- case "Below_ABS_Value": return AlgorithmType.ALG_FALL_VALUE;
|
|
|
|
- case "Drop_Percent": return AlgorithmType.ALG_FALL_PERCENT;
|
|
|
|
- case "Up_Percent": return AlgorithmType.ALG_RISE_PERCENT;
|
|
|
|
- case "Range_In": return AlgorithmType.ALG_RANGE_IN;
|
|
|
|
- case "Gradient": return AlgorithmType.ALG_GRADIENT;
|
|
|
|
- case "Peek": return AlgorithmType.ALG_PEAK;
|
|
|
|
- case "Valley": return AlgorithmType.ALG_VALLEY;
|
|
|
|
- case "Min_Drop_Percent": return AlgorithmType.ALG_MIN_FALL_PERCENT;
|
|
|
|
- case "Min_Up_Percent": return AlgorithmType.ALG_MIN_RISE_PERCENT;
|
|
|
|
- case "Max_Drop_Percent": return AlgorithmType.ALG_MAX_FALL_PERCENT;
|
|
|
|
- case "Max_Up_Percent": return AlgorithmType.ALG_MAX_RISE_PERCENT;
|
|
|
|
- case "Rise_Fall": return AlgorithmType.ALG_RISE_FALL;
|
|
|
|
- case "Fall_Rise": return AlgorithmType.ALG_FALL_RISE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return AlgorithmType.ALG_NONE;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void StepStop()
|
|
|
|
- {
|
|
|
|
- if (!IsConnected)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, "EPD not connected, call step stop ignored");
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, Notify EPD recipe step stopped");
|
|
|
|
-
|
|
|
|
- EPDClient.Instance.Service.Stop(_channel);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- private bool OnTimer()
|
|
|
|
- {
|
|
|
|
- try
|
|
|
|
- {
|
|
|
|
- bool retryConnect = false;
|
|
|
|
- lock (_lockerTrigger)
|
|
|
|
- {
|
|
|
|
- retryConnect = _triggerConnected.M;
|
|
|
|
- if (!_triggerConnected.M)
|
|
|
|
- {
|
|
|
|
- //if (_enableRetry)
|
|
|
|
- {
|
|
|
|
- retryConnect = true;
|
|
|
|
- //_enableRetry = false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (retryConnect)
|
|
|
|
- {
|
|
|
|
- _connectionCounter++;
|
|
|
|
- if (_connectionCounter > 10000)
|
|
|
|
- _connectionCounter = 1;
|
|
|
|
-
|
|
|
|
- _triggerConnected.CLK = _connectionCounter== EPDClient.Instance.Service.Heartbeat(_connectionCounter);
|
|
|
|
-
|
|
|
|
- _triggerNotConnected.CLK = !_triggerConnected.M;
|
|
|
|
-
|
|
|
|
- if (_triggerConnected.Q)
|
|
|
|
- {
|
|
|
|
- EPDCallbackClient.Instance.Init();
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, EPD Connected");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (_triggerConnected.M)
|
|
|
|
- {
|
|
|
|
- _channelStatus = EPDClient.Instance.Service.QueryState(_channel).ToString();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if (_triggerNotConnected.Q)
|
|
|
|
- {
|
|
|
|
- EPDCallbackClient.Instance.Stop();
|
|
|
|
- LOG.Write(eEvent.WARN_ENDPOINT, Module, $"{Module} {Name}, EPD disconnected");
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- catch (Exception ex)
|
|
|
|
- {
|
|
|
|
- LOG.Write(eEvent.ERR_ENDPOINT, Module, ex.ToString());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void Instance_Notify(int channel, string e)
|
|
|
|
- {
|
|
|
|
- if (_channel != channel)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, EPD Feedback:{e}");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void Instance_Trigger(int channel, TriggerEventArgs e)
|
|
|
|
- {
|
|
|
|
- if (_channel != channel)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- _isEnd = true;
|
|
|
|
-
|
|
|
|
- LOG.Write(eEvent.INFO_ENDPOINT, Module, $"{Module} {Name}, EPD: {e.Channel}.{e.Name} Triggered");
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Monitor()
|
|
|
|
- {
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Terminate()
|
|
|
|
- {
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Reset()
|
|
|
|
- {
|
|
|
|
- lock (_lockerTrigger)
|
|
|
|
- {
|
|
|
|
- if (!_triggerConnected.M)
|
|
|
|
- {
|
|
|
|
- //_enableRetry = true;
|
|
|
|
-
|
|
|
|
- _triggerConnected.RST = true;
|
|
|
|
- _triggerNotConnected.RST = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public class EPDCallbackClient : Singleton<EPDCallbackClient>, IEPDCallback
|
|
|
|
- {
|
|
|
|
- public event Action<int, string> Notify;
|
|
|
|
-
|
|
|
|
- public event Action<int, TriggerEventArgs> Trigger;
|
|
|
|
-
|
|
|
|
- private EPDCallbackServiceClient _service;
|
|
|
|
-
|
|
|
|
- public EPDCallbackClient()
|
|
|
|
- {
|
|
|
|
- _service = new EPDCallbackServiceClient(this);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Init()
|
|
|
|
- {
|
|
|
|
- _service.Register();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Stop()
|
|
|
|
- {
|
|
|
|
- _service.UnRegister();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- //public void OnNotify(string channel, string message)
|
|
|
|
- //{
|
|
|
|
-
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- //public void OnTrigger(string channel, string name, long ticket)
|
|
|
|
- //{
|
|
|
|
-
|
|
|
|
- //}
|
|
|
|
-
|
|
|
|
- public void OnNotify(int channel, EPDEventType EventType, string message)
|
|
|
|
- {
|
|
|
|
- Notify?.Invoke(channel, $"{EventType}:{message}");
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void OnTrigger(int channel, string name, long ticket)
|
|
|
|
- {
|
|
|
|
- Trigger?.Invoke(channel, new TriggerEventArgs() { Channel = channel, Name = name, Ticket = ticket });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public class TriggerEventArgs
|
|
|
|
- {
|
|
|
|
- public int Channel { get; set; }
|
|
|
|
- public string Name { get; set; }
|
|
|
|
- public long Ticket { get; set; }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public class EPDCallbackServiceClient : DuplexChannelServiceClientWrapper<IEPDCallbackService>
|
|
|
|
- {
|
|
|
|
- private Guid _clientId = Guid.Empty;
|
|
|
|
-
|
|
|
|
- public EPDCallbackServiceClient(IEPDCallback callback) : base(new InstanceContext(callback), "Client_IEPDCallbackService", "IEPDCallbackService")
|
|
|
|
- {
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void Register()
|
|
|
|
- {
|
|
|
|
- if (_clientId != Guid.Empty)
|
|
|
|
- UnRegister();
|
|
|
|
-
|
|
|
|
- _clientId = Guid.NewGuid();
|
|
|
|
- Invoke(x => x.Register(_clientId));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void UnRegister()
|
|
|
|
- {
|
|
|
|
- Invoke(x => x.UnRegister(_clientId));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|