using Aitex.Core.Common; using Aitex.Core.Common.DeviceData; 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.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Xml; using VirgoCommon; using VirgoRT.Devices; using VirgoRT.Devices.EFEM; using VirgoRT.Devices.YASKAWA; using VirgoRT.HostWrapper; using VirgoRT.Modules; namespace VirgoRT.Device { class EfemCommunicationBase { protected readonly AsyncSocket _socket = new AsyncSocket(""); public bool IsConnected { get { return _socket.IsConnected; } } private string _ip; protected EfemCommunicationBase(string sIP) { _ip = sIP; _socket.Connect(_ip); _socket.OnDataChanged += Hardware_OnDataChanged; _socket.OnErrorHappened += Hardware_OnErrorHappened; //if (!_socket.IsConnected) //{ // EV.PostAlarmLog(ModuleName.EFEM.ToString(), "Cannot connect to EFEM"); //} } public void Reconnect() { _socket.Connect(_ip); } private void Hardware_OnDataChanged(string message) { Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.RecHwMsg, message); } private void Hardware_OnErrorHappened(ErrorEventArgs args) { Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } public virtual void SendTo(string str) { } public virtual void SendTo(IEfemMessage yas_msg) { } } } namespace VirgoRT.Device.YASKAWA { sealed class MessageHandler : IMessageHandler { // Fields // private readonly IList _msgQueue = new List(); private readonly EfemBase _efem; // Properties // public bool IsCompleted { get { if (_msgQueue.Count <= 0) return false; return EfemMessage.MsgHead.INF == _msgQueue[_msgQueue.Count - 1].Head; } } public event EventHandler CommandUpdated; public event EventHandler EventUpdated; public event EventHandler ErrorOccurred; // Constructor // public MessageHandler(EfemBase device) { _efem = device; } public void Send(IEfemMessage msg) { _efem.Comm.SendTo(msg); _msgQueue.Add(msg as EfemMessage); } public void ReceiveMessage(string sRec) { string[] msgs = sRec.Split('\r'); foreach (var msg in msgs) { if (string.IsNullOrWhiteSpace(msg)) continue; EfemMessage rec_msg = msg.ToMessage(); switch (rec_msg.Head) { case EfemMessage.MsgHead.ACK: _msgQueue.Add(rec_msg); OnCommandUpdated(new EfemActionArgs { Module = rec_msg.Port, CommandType = rec_msg.Operation, Status = ActionStatus.RecACK }); break; case EfemMessage.MsgHead.INF: OnCommandUpdated(new EfemActionArgs { Module = rec_msg.Port, CommandType = rec_msg.Operation, Status = ActionStatus.RecINF }); // 收到INF之后发送ACK确认 string strACK = rec_msg.RawString.Replace("INF", "ACK"); _efem.Comm.SendTo(strACK); EfemMessage ack_msg = strACK.ToMessage(); ack_msg.Direct = MsgDirection.To; _msgQueue.Add(ack_msg); OnCommandUpdated(new EfemActionArgs { Module = rec_msg.Port, CommandType = rec_msg.Operation, Status = ActionStatus.Completed, Data = rec_msg.Data.Count > 0 ? rec_msg.Data.First() : string.Empty }); break; case EfemMessage.MsgHead.EVT: OnEventUpdated(new EfemEventArgs { EvtStr = rec_msg.ToParamString(), Module = rec_msg.Port, CommandType = rec_msg.Operation, DataList = rec_msg.Data }); break; case EfemMessage.MsgHead.NAK: OnErrorOccurred(new EfemErrorArgs { Factor = rec_msg.Factor, Description = Constant.FactorString[rec_msg.Factor], CommandType = rec_msg.Operation, Module = rec_msg.Port, }); break; case EfemMessage.MsgHead.CAN: OnErrorOccurred(new EfemErrorArgs { Factor = rec_msg.Factor, Description = Constant.FactorString.ContainsKey(rec_msg.Factor) ? Constant.FactorString[rec_msg.Factor] : rec_msg.Factor, Message = rec_msg.Data[0], CommandType = rec_msg.Operation, Module = rec_msg.Port, }); break; case EfemMessage.MsgHead.ABS: OnErrorOccurred(new EfemErrorArgs { Factor = rec_msg.Factor, Description = $"{rec_msg.Data[0]}, {rec_msg.Data[1]}", CommandType = rec_msg.Operation, Module = rec_msg.Port, }); break; } } } private void OnCommandUpdated(EfemActionArgs args) { CommandUpdated?.Invoke(this, args); } private void OnEventUpdated(EfemEventArgs args) { EventUpdated?.Invoke(this, args); } private void OnErrorOccurred(EfemErrorArgs args) { ErrorOccurred?.Invoke(this, args); } } sealed class EfemComm : EfemCommunicationBase { public EfemComm() : base(SC.GetStringValue("EFEM.IPAddress")) { } public override void SendTo(string str) { _socket.Write(str + '\r'); } public override void SendTo(IEfemMessage msg) { if (msg is EfemMessage yas_msg) { //string str = EfemParser.Instance.TranslateBack(yas_msg); string str = yas_msg.ToString(); if (string.IsNullOrEmpty(str)) throw new ApplicationException("Yaskawa message translation error"); yas_msg.RawString = str; SendTo(str); } } } sealed class SignalTower { // Fields // private readonly Dictionary _lights = new Dictionary(5); public SignalTower() { _lights.Add(LightType.RED, LightStatus.OFF); _lights.Add(LightType.YELLOW, LightStatus.OFF); _lights.Add(LightType.BLUE, LightStatus.OFF); _lights.Add(LightType.GREEN, LightStatus.OFF); _lights.Add(LightType.WHITE, LightStatus.OFF); _lights.Add(LightType.BUZZER1, LightStatus.OFF); DATA.Subscribe($"{ModuleName.EFEM}.SignalTower", () => { return new AITSignalTowerData { IsGreenLightOn = _lights[LightType.GREEN] == LightStatus.ON, IsRedLightOn = _lights[LightType.RED] == LightStatus.ON, IsYellowLightOn = _lights[LightType.YELLOW] == LightStatus.ON, IsWhiteLightOn = _lights[LightType.WHITE] == LightStatus.ON, IsBlueLightOn = _lights[LightType.BLUE] == LightStatus.ON, IsBuzzerOn = _lights[LightType.BUZZER1] == LightStatus.ON, }; }); } // Methods // public void ChangeLightStatus(LightType light, LightStatus st) { if (!_lights.ContainsKey(light)) throw new ApplicationException($"NO {light} configured"); _lights[light] = st; } } }