using System.Text; using System.Collections.Generic; using System.Diagnostics; using Venus_RT.Modules; using MECF.Framework.Common.Communications; using MECF.Framework.Common.Equipment; using Venus_Core; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Event; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.Util; using EPD.Data; using Venus_RT.Devices; using System.Text.RegularExpressions; namespace Venus_RT.Devices.EPD { public class EPDClient : JetEPDBase { private EPDSocketClient _socketClient; private string _ip; private int _port; private int _channel; private Stopwatch _heartBeatTimer = new Stopwatch(); private bool _isHeartBeatReceived=true; private readonly R_TRIG _epdIdle = new R_TRIG(); private bool _captured; public override bool Captured { get { return _captured; }} private bool _connected = false; public override bool IsEPDConnected { get { return _connected; } } private EDPStatus _status; public override EDPStatus Status { get { return _status; } } private List<string> _cfgFileList; public override List<string> CFGFileList { get { return _cfgFileList; } } public string EPDVersion { get; private set; } public string EPDState { get; private set; } public string SensorStatus { get; private set; } public string EPDRunStatus { get; private set; } public string EPDMode { get; private set; } public EPDClient(ModuleName mod) { Name = VenusDevice.EndPoint.ToString(); Module = mod.ToString(); var ipaddress= SC.GetStringValue($"{mod.ToString()}.EPD.IPAddress"); var ipaddressValue = ipaddress.Split(':'); if (ipaddressValue.Length == 2) { _ip = ipaddressValue[0]; _port = System.Convert.ToInt32(ipaddressValue[1]); } _channel = SC.GetValue<int>($"{Module}.EPD.ChannelNumber"); _socketClient = new EPDSocketClient(); _socketClient.OnConnect += OnConnect; _socketClient.OnDisconnect += OnDisConnect; _socketClient.OnSocketSend += OnEPDSocketSend; _socketClient.OnSocketReceive += OnEPDSocketReceive; _socketClient.OnEPDReply += OnEPDReply; _socketClient.OnError += OnError; } public override bool Initialize() { _socketClient.Connect(_ip, _port); _socketClient.ConnectEPD(); _socketClient.SetMode(2); // 1 local; 2 remote _socketClient.SetRunStatus(4); // 1 Monitor; 2 Save; 3:Capture; 4:Process _socketClient.QueryConfigList(); return true; } public override void Monitor() { HeartBeat(); } public override void Reset() { } public override void Terminate() { _status = EDPStatus.Idle; _socketClient.DisconnectEPD(); _socketClient.Disconnect(); } public override void RecipeStart(string recipe) { _captured = false; _socketClient.RecipeStart(_channel, recipe); _status = EDPStatus.Running; } public override void RecipeStop() { _socketClient.RecipeStop(_channel); _status = EDPStatus.Idle; } public override void StepStart(string cfgName, int Index) { _socketClient.Start((byte)_channel, cfgName); _status = EDPStatus.Running; } public override void StepStop() { _socketClient.Stop((byte)_channel); } private void HeartBeat() { //_socketClient.SendHeartBeat(); _epdIdle.CLK = Status == EDPStatus.Idle; if (_epdIdle.Q) { _socketClient.SendHeartBeat(); _heartBeatTimer.Restart(); _isHeartBeatReceived = false; } else if(_epdIdle.M) { if(_heartBeatTimer.ElapsedMilliseconds > 30000) { if (!_isHeartBeatReceived && !SC.GetValue<bool>("System.IsSimulatorMode")) { LOG.Write(eEvent.ERR_ENDPOINT, Module, "HeartBeat Error, EndPoint Device did not response in 5 seconds"); } _socketClient.SendHeartBeat(); _heartBeatTimer.Restart(); _isHeartBeatReceived = false; } } else { _heartBeatTimer.Stop(); } } private void OnConnect() { LOG.Write(eEvent.INFO_ENDPOINT, Module, "Endpoint connected"); } private void OnDisConnect() { LOG.Write(eEvent.INFO_ENDPOINT, Module, "Endpoint disconnected"); } private void OnEPDSocketReceive(string type, byte[] data, int length) { var content = StringJoin(" ", data, length); //LOG.Write(eEvent.INFO_ENDPOINT, Module, $"Endpoint Receive: {content}"); } private void OnEPDSocketSend(string type, byte[] data) { var content = StringJoin(" ", data, data.Length); if(type != "HeartBeat") { LOG.Write(eEvent.INFO_ENDPOINT, Module, $"Endpoint Send=> Type:{type}, Data:{content}"); } } private void OnError(int command, int errorCode) { var strError = errorCode.ToString(); if (EPDDefine.ErrorMap.ContainsKey(errorCode)) strError = EPDDefine.ErrorMap[errorCode]; string ErrorInfo = $"EndPoint Command {(EPDCommand)command} Failed: {strError}"; LOG.Write(eEvent.ERR_ENDPOINT, Module, ErrorInfo); } private void OnEPDReply(EPDCommand cmd, object obj) { switch (cmd) { case EPDCommand.SetWaferInfo: break; case EPDCommand.QueryCfgList: if (obj is List<string>) _cfgFileList = (List<string>)obj; break; case EPDCommand.QueryState: if (obj is ushort state && EPDDefine.StateMap.ContainsKey(state)) EPDState = EPDDefine.StateMap[state]; break; case EPDCommand.QueryVer: EPDVersion = obj.ToString(); break; case EPDCommand.Connect: _connected = true; break; case EPDCommand.HeartBeat: _isHeartBeatReceived = true; break; case EPDCommand.QueryRunStatus: if (obj is ushort sta && EPDDefine.RunStatusMap.ContainsKey(sta)) { EPDRunStatus = EPDDefine.RunStatusMap[sta]; } break; case EPDCommand.QueryOperateMode: if (obj is ushort mode && EPDDefine.ModeMap.ContainsKey(mode)) { EPDMode = EPDDefine.ModeMap[mode]; } break; case EPDCommand.GetSensorStatus: if (obj is List<string> statusLst && statusLst.Count >= 2) { SensorStatus = statusLst[0]; } break; case EPDCommand.GetRecipesList: if (obj is List<string> objs) { _cfgFileList = objs.GetRange(3, objs.Count - 3); SensorStatus = objs[0]; } break; case EPDCommand.Event: var lst = obj as List<object>; //LOG.Write(0,"test11111111111111111111111XX"+lst[0].ToString()); if (lst[0] is int type && type == 7) _captured = true; break; case EPDCommand.AsciiEvent: if (obj.ToString() == "ENDPOINT") _captured = true; break; case EPDCommand.QueryChannelCount: case EPDCommand.QueryChannalNames: case EPDCommand.RecipeStart: case EPDCommand.RecipeStop: case EPDCommand.Start: case EPDCommand.Stop: default: break; } } private string StringJoin(string separator, byte[] values, int length) { if (values == null || values.Length == 0) return string.Empty; if (separator == null) separator = string.Empty; var sb = new StringBuilder($"{values[0]:X2}"); for (int i = 1; i < length; i++) sb.Append($"{separator}{values[i]:X2}"); return sb.ToString(); } public override void QueryConfigList() { _socketClient.QueryConfigList(); } } }