123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- 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)
- {
- EV.PostWarningLog(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("EPD not connected, call recipe start ignored");
- return;
- }
- EV.PostInfoLog(Module, $"{Module} {Name}, Notify EPD recipe {recipeName} start");
- EPDClient.Instance.Service.RecipeStart(_channel, recipeName);
- }
- public void RecipeStop()
- {
- if (!IsConnected)
- {
- LOG.Write("EPD not connected, call recipe start ignored");
- return;
- }
- EV.PostInfoLog(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("EPD not connected, call step start ignored");
- return;
- }
- EV.PostInfoLog(Module, $"{Module} {Name}, Notify EPD recipe step {index+1} start");
- EV.PostInfoLog(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(ex);
- EV.PostInfoLog(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("EPD not connected, call step stop ignored");
- return;
- }
- EV.PostInfoLog(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();
- EV.PostInfoLog(Module, $"{Module} {Name}, EPD Connected");
- }
- if (_triggerConnected.M)
- {
- _channelStatus = EPDClient.Instance.Service.QueryState(_channel).ToString();
- }
- if (_triggerNotConnected.Q)
- {
- EPDCallbackClient.Instance.Stop();
- EV.PostWarningLog(Module, $"{Module} {Name}, EPD disconnected");
- }
- }
- }
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- return true;
- }
- private void Instance_Notify(int channel, string e)
- {
- if (_channel != channel)
- return;
- EV.PostInfoLog(Module, $"{Module} {Name}, EPD Feedback:{e}");
- }
- private void Instance_Trigger(int channel, TriggerEventArgs e)
- {
- if (_channel != channel)
- return;
- _isEnd = true;
- EV.PostInfoLog(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));
- }
- }
- }
|