using System; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using MECF.Framework.Simulator.Core.Driver; using Aitex.Core.Util; using Virgo_DCommon; namespace Virgo_DSimulator.Devices { class EfemSimulatorServer : SocketDeviceSimulator { private const string CMD_PATTERN = "^MOV|^SET|^GET"; private const string SCMD = @"(?<=\:)(.*?)(?=\/)"; private const string SFOUP = @"(?<=P)(\d{1})(?=[\;\/])"; private const string ACK = "ACK"; private string[] _slotMap = new string[25]; private PeriodicJob _HwThread; private bool _bCommReady; public string SlotMap { get { return string.Join("", _slotMap); } } public EfemSimulatorServer() : base(13000, -1, "\r", ' ') { for (int i = 0; i < _slotMap.Length; i++) _slotMap[i] = "0"; _HwThread = new PeriodicJob(5000, OnSendEvent, "EfemHardware", true); } private bool OnSendEvent() { if (!_bCommReady) { OnWriteMessage("INF:READY/COMM;"); } return true; } protected override void ProcessUnsplitMessage(string str) { if (!_bCommReady && str.Contains("ACK:READY/COMM")) { _bCommReady = true; } if (!Regex.IsMatch(str, CMD_PATTERN)) return; // 发送ACK 表示收到 string ack = Regex.Replace(str, CMD_PATTERN, ACK); OnWriteMessage(ack); // 处理INF var a = OnWork(ack); } private async Task OnWork(string strACK) { // match basic Match m1 = Regex.Match(strACK, SCMD); // get mock delay time string sBasic = m1.Groups[1].Value; EfemOperation op = EfemConstant.ToOperation(sBasic); ushort sec = this.SimuOperationTime(op); // Sleep await Task.Run(() => Thread.Sleep(sec * 1000)); // build the INF string string strINF = string.Empty; switch (EfemConstant.ToOperation(sBasic)) { case EfemOperation.GetWaferInfo: strINF = strACK.Replace(ACK, "INF"); strINF = strINF.TrimEnd(';'); strINF += "/1111111111111110001111111;"; break; case EfemOperation.Home: string s1 = "EVT:SIGSTAT/P1/00000381/00000000;\rEVT:SIGSTAT/P2/00000381/00000000;\rEVT:SIGSTAT/System/00000000/00000000;\r"; strINF = s1 + strACK.Replace(ACK, "INF"); break; case EfemOperation.Map: Match m2 = Regex.Match(strACK, SFOUP); if (m2.Success) { string s2 = $"EVT:MAPDT/P{m2.Groups[1].Value}/1111111100000000000000000;\r"; strINF = s2 + strACK.Replace(ACK, "INF"); } break; case EfemOperation.Align: case EfemOperation.Pick: case EfemOperation.Place: case EfemOperation.Orgsh: case EfemOperation.Light: case EfemOperation.SigStatus: default: strINF = strACK.Replace(ACK, "INF"); break; } OnWriteMessage(strINF); } private ushort SimuOperationTime(EfemOperation op) { ushort sec = 0; switch (op) { case EfemOperation.Map: case EfemOperation.GetWaferInfo: case EfemOperation.Align: sec = 3; break; case EfemOperation.Pick: case EfemOperation.Place: case EfemOperation.Orgsh: sec = 4; break; case EfemOperation.Light: case EfemOperation.SigStatus: sec = 2; break; default: sec = 1; break; } return sec; } public void PlaceCarrier() { string msg = "EVT:SIGSTAT/P1/00000381/00000000;"; OnWriteMessage(msg); //_state[6] = "1"; } public void RemoveCarrier() { //_state[6] = "0"; string msg = "EVT:SIGSTAT/P1/00000202/00000000;"; OnWriteMessage(msg); } public void ClearWafer() { for (int i = 0; i < _slotMap.Length; i++) { _slotMap[i] = "0"; } } public void SetAllWafer() { for (int i = 0; i < _slotMap.Length; i++) { _slotMap[i] = "1"; } } public void SetUpWafer() { for (int i = 0; i < _slotMap.Length; i++) { _slotMap[i] = i > 15 ? "1" : "0"; } } public void SetLowWafer() { for (int i = 0; i < _slotMap.Length; i++) { _slotMap[i] = i < 10 ? "1" : "0"; } } public void RandomWafer() { Random _rd = new Random(); for (int i = 0; i < _slotMap.Length; i++) { _slotMap[i] = _rd.Next(0, 10) < 6 ? "0" : "1"; } } } }