secs4net

 


FROM https://skyhappyblog.wordpress.com/2021/07/20/c-secs/

範例
if (msg.F == 33)//
{
var item = msg.SecsItem;
if (item.Format == SecsFormat.ASCII) {
var kk = item.GetString();

}
else if (item.Format == SecsFormat.Binary)
{

// var kk = item.GetVue();

}
else if (item.Format == SecsFormat.List)
{
foreach (var data in item.Items) {
var list = data.GetValues();

}
//OK

}
}





FROM https://csharp.hotexamples.com/examples/Secs4Net/SecsMessage/-/php-secsmessage-class-examples.html

 public SecsMessageViewModel(SecsMessage secsMsg)
     : base(null, false)
 {
     _secsMsg = secsMsg;
     if (secsMsg.SecsItem != null)
         base.Children.Add(new SecsItemViewModel(secsMsg.SecsItem, this));
 }

        void EQP_WaferStatusChange(SecsMessage msg) {
            Item dataList = msg.SecsItem.Items[2].Items[0].Items[1];
            string pjId = dataList.Items[0].GetValue<string>();

            string carrier_slot_port = (string)dataList.Items[1];
            int i = carrier_slot_port.IndexOf('.');
            string carrierId = carrier_slot_port.Substring(0, i); 
            byte slotNo = Convert.ToByte(carrier_slot_port.Substring(i + 1, 2));

            string state = dataList.Items[2].GetValue<string>();
            switch (state) {
                case "SubstLocChamber":
                    EAP.Report(new WaferStartReport {
                        ProcessJobId = GetProcessJob(carrierId,slotNo).Id,
                        CarrierId = carrierId,
                        SlotNo = slotNo
                    });
                    break;
                case "SubstLocLowerArm":
                    EAP.Report(new WaferEndReport {
                        ProcessJobId = GetProcessJob(carrierId,slotNo).Id,
                        CarrierId = carrierId,
                        SlotNo = slotNo
                    });
                    break;
            }
        }

 internal SecsEventSubscription(string toolId, SecsMessage filter, bool recoverable, Action<SecsMessage> callback) {
     this.Id = (toolId + filter.Name + callback.Method.DeclaringType + callback.Method.Name).Replace('\\', '-').Replace('+', '-').Replace(';', '-').Replace(',', '_').Replace('"', '|');
     this.ToolId = toolId;
     this.Recoverable = recoverable;
     this._handler = callback;
     this.Filter = filter;
 }
EXAMPLE #4
0
 void EQP_CarrierIDRead(SecsMessage msg) {
     byte portNo = (byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
     string carrierID = msg.SecsItem.Items[2].Items[0].Items[1].Items[1].GetValue<string>().Trim();
     EAP.Report(new CarrierIDReport {
         LoadPortId = GetPortID(portNo),
         CarrierId = carrierID
     });
 }
EXAMPLE #5
0
        void EQP_UnloadComplete(SecsMessage msg) {
            string portId = GetPortID((byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0]);
            EAP.Report(new UnloadCompleteReport {
                PortID = portId
            });

            //清除相關Loadport上的ProcessJob物件
            _ProcessingJobs.RemoveAll(pj => pj.Carriers.First().LoadPortId == portId);
        }
EXAMPLE #6
0
        async void EQP_LoadComplete(SecsMessage msg) {
            byte portNo = (byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
            string portId = GetPortID(portNo);
            EAP.Report(new LoadCompReport {
                PortID = portId
            });

            // Wait CarrierIDRead Event 10 sec.
            {
                // Method 1:
                //ThreadPool.QueueUserWorkItem(delegate {
                //    EapLogger.Notice(portId + " StartAsync CarrierIDRead Timer");
                //    using (var ev = new ManualResetEvent(false)) {
                //        var callback = new Action<SecsMessage>(secsMsg => {
                //            if (portNo == (byte)secsMsg.SecsItem.Items[2].Items[0].Items[1].Items[0])
                //                ev.Set();
                //        });
                //        using (EAP.SubscribeS6F11("CarrierIDRead", callback))
                //        using (EAP.SubscribeS6F11("CarrierIDReadFail", callback)) {
                //            if (!ev.WaitOne(10000)) {
                //                EapLogger.Error(portId + " CarrierIDRead Timeout!!");
                //                EAP.Report(new CarrierIDReport {
                //                    LoadPortId = portId
                //                });
                //            }
                //        }
                //    }
                //});
            }
            {
                // Method 2:
                //EapLogger.Notice(portId + " StartAsync CarrierIDRead Timer");
                //var ev = new ManualResetEvent(false);
                //var callback = new Action<SecsMessage>(secsMsg => {
                //    if (portNo == (byte)secsMsg.SecsItem.Items[2].Items[0].Items[1].Items[0])
                //        ev.Set();
                //});
                //var read = EAP.SubscribeS6F11("CarrierIDRead", callback);
                //var readfail = EAP.SubscribeS6F11("CarrierIDReadFail", callback);
                //ThreadPool.RegisterWaitForSingleObject(ev, (state, timeout) => {
                //    if (read != null)
                //        read.Dispose();
                //    if (readfail != null)
                //        readfail.Dispose();
                //    if (timeout) {
                //        EapLogger.Error(portId + " CarrierIDRead Timeout!!");
                //        EAP.Report(new CarrierIDReport {
                //            LoadPortId = portId
                //        });
                //    }
                //}, null, 10000, true);
            }
        }
EXAMPLE #7
0
 void EQP_SlotMapReport(SecsMessage msg) {
     byte portNo = (byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
     string carrierId = (string)msg.SecsItem.Items[2].Items[0].Items[1].Items[1];
     string map = (string)msg.SecsItem.Items[2].Items[0].Items[1].Items[1 + portNo];
     EAP.Report(new SlotMapReport {
         LoadPortID = GetPortID(portNo),
         CarrierID = carrierId,
         Slots = from i in Enumerable.Range(0, map.Length)
                 where map[i] == '1'
                 select (byte)(i + 1)
     });
 }
EXAMPLE #8
0
 void EQP_SlotMapReport(SecsMessage msg) {
     byte portNo = (byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
     string carrierID = msg.SecsItem.Items[2].Items[0].Items[1].Items[1].GetValue<string>().Trim();
     var mapItem = msg.SecsItem.Items[2].Items[0].Items[1].Items[2].Items;
     EAP.Report(new SlotMapReport {
         LoadPortID = GetPortID(portNo),
         CarrierID = carrierID,
         Slots = from i in Enumerable.Range(0, mapItem.Count)
                 where mapItem[i].GetValue<byte>() == 4
                 select (byte)(i + 1)
     });
 }
        async Task ChangeAccessMode(AccessMode changeAccessMode, byte portNo) {
            var S3F23 = new SecsMessage(3, 23, "ChangeAccessMode",
                Item.L(
                    Item.A(),
                    Item.U1((byte)changeAccessMode),
                    Item.L(
                        Item.U1(portNo))));

            var S3F24 = await EAP.SendAsync(S3F23);
            byte returnCode = (byte)S3F24.SecsItem.Items[0];
            if (returnCode != 0 && returnCode != 4)
                throw new ScenarioException("Change Loadport[" + portNo + "] access mode fial. " + S3F24.SecsItem.Items[1].Items[1].GetValue<string>());
        }
        /// <summary>
        /// Each PrimaryMessageWrapper can invoke Reply method once.
        /// Since message replied, method return false.
        /// </summary>
        /// <param name="replyMessage"></param>
        /// <returns>ture, if reply message sent.</returns>
        public bool Reply(SecsMessage replyMessage)
        {
            if (Interlocked.Exchange(ref _isReplied, 1) == 1)
                return false;

            if (!Message.ReplyExpected)
                return true;

            replyMessage = replyMessage ?? new SecsMessage(9, 7, false, "Unknown Message", Item.B(_header.Bytes));
            replyMessage.ReplyExpected = false;

            _secsGem.SendDataMessageAsync(replyMessage, replyMessage.S == 9 ? _secsGem.NewSystemId : _header.SystemBytes);

            return true;
        }
EXAMPLE #11
0
        void EQP_WaferProcessData_PVD(SecsMessage msg) {
            Item tempList = msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
            string pjID = tempList.Items[1].GetValue<string>();
            byte slotNo = (byte)tempList.Items[4].Items[0].Items[1];

            tempList = tempList.Items[4].Items[0].Items[2].Items[0];
            string chamber = tempList.Items[0].Items[1].GetValue<string>();

            var dc = new DataCollectionReport(GetProcessJob(pjID));
            try {
                dc.AddLotData("CIWW", chamber);

                
            } finally {
                EAP.Report(dc);
            }
        }
EXAMPLE #12
0
 void EQP_DataCollection(SecsMessage msg) {
     Item dataList = msg.SecsItem.Items[2].Items[0].Items[1];
     string pjId = dataList.Items[0].GetValue<string>();
     string carrier_slot_port = (string)dataList.Items[1];
     int i = carrier_slot_port.IndexOf('.');
     byte slotNo = Convert.ToByte(carrier_slot_port.Substring(i + 1, 2));
     string carrierId = carrier_slot_port.Substring(0, i); 
     var dc = new DataCollectionReport(GetProcessJob(carrierId,slotNo));
     try {
         dc.AddWaferData("SNW0", slotNo, slotNo);
         dc.AddWaferData("PTW0", slotNo, dataList.Items[2]);
         dc.AddWaferData("TXW0", slotNo, (uint)dataList.Items[3] / 100);
         dc.AddWaferData("TIW0", slotNo, (uint)dataList.Items[4] / 100);
         dc.AddWaferData("TAW0", slotNo, (uint)dataList.Items[5] / 100);
     } finally {
         EAP.Report(dc);
     }
 }
EXAMPLE #13
0
        void EQP_WaferProcessData_LLH_LHC(SecsMessage msg) {
            Item tempList = msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
            string pjID = tempList.Items[1].GetValue<string>();
            byte slotNo = (byte)tempList.Items[4].Items[0].Items[1];

            tempList = tempList.Items[4].Items[0].Items[2].Items[0];

            var dc = new DataCollectionReport(GetProcessJob(pjID));
            try {
                dc.AddWaferData("CIWD", slotNo, tempList.Items[0].Items[1]);

                tempList = tempList.Items[2].Items[0].Items[2];

                dc.AddWaferData("C1W1", slotNo, tempList.Items[3]);
                dc.AddWaferData("C1W2", slotNo, tempList.Items[6]);
                dc.AddWaferData("C2W1", slotNo, tempList.Items[9]);
                dc.AddWaferData("C2W2", slotNo, tempList.Items[12]);
            } finally {
                EAP.Report(dc);
            }
        }
        void EQP_DataCollectionComplete(SecsMessage msg) {
            Item tmpList = msg.SecsItem.Items[2].Items[0].Items[1];

            string carrier_slot_port = (string)tmpList.Items[1];
            int i = carrier_slot_port.IndexOf('.');
            string carrierId = carrier_slot_port.Substring(0, i);
            byte slotNo = Convert.ToByte(carrier_slot_port.Substring(i + 1, 2));
            char portNo = carrier_slot_port[carrier_slot_port.Length - 1];

            var processJob = GetProcessJob(carrierId, slotNo);
            var dc = new DataCollectionReport(processJob);
            var dcc = new DataCollectionCompleteReport(processJob);
            try {
                dc.AddLotData("PJL0", processJob.Id);
                dc.AddLotData("CJL0", carrierId);
                dc.AddLotData("SNL0", slotNo);
                dc.AddLotData("PIL0", Convert.ToByte(portNo));
                dc.AddLotData("RIL0", tmpList.Items[2]);
                dc.AddLotData("LTL0", (uint)tmpList.Items[3] / 100);
            } finally {
                EAP.Report(dc);
                EAP.Report(dcc);
            }
        }
EXAMPLE #15
0
 static void DefineLinkSuccess(SecsMessage msg) {
     if (msg.SecsItem.GetValue<byte>() != 0)
         throw new ScenarioException("Define Link failed : " + msg.Name);
 }
EXAMPLE #16
0
 void EQP_ProcessJobEnd(SecsMessage msg) {
     EAP.Report(new ProcessJobEndReport {
         ProcessJobID = (string)msg.SecsItem.Items[2].Items[0].Items[1].Items[0]
     });
 }
EXAMPLE #17
0
 protected override void HandleToolAlarm(SecsMessage msg)
 {
 }
EXAMPLE #18
0
 void EQP_ReadyToLoad(SecsMessage msg) {
     EAP.Report(new ReadyToLoadReport {
         PortID = GetPortID((byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0])
     });
 }
EXAMPLE #19
0
 void EQP_ControlJobEnd(SecsMessage msg) {
     EAP.Report(new ControlJobEndReport {
         ControlJobID = msg.SecsItem.Items[2].Items[0].Items[1].Items[1].GetValue<string>().Trim()
     });
 }
EXAMPLE #20
0
 public void MessageOut(SecsMessage msg, int systembyte)
 {
     _form.Invoke((MethodInvoker)delegate {
         _form.richTextBox1.SelectionColor = Color.Black;
         _form.richTextBox1.AppendText($"--> [0x{systembyte:X8}] {msg.ToSML()}\n");
     });
 }
EXAMPLE #21
0
 void EQP_ControlJobStart(SecsMessage msg) {
     EAP.Report(new ControlJobStartReport {
         ControlJobID = (string)msg.SecsItem.Items[2].Items[0].Items[1].Items[0]
     });
 }
EXAMPLE #22
0
 public void MessageOut(SecsMessage msg, int systembyte) {
     Trace.WriteLine($"--> [0x{systembyte:X8}] {msg}");
 }
EXAMPLE #23
0
 public void MessageIn(SecsMessage msg, int systembyte) {
     Trace.WriteLine($"<-- [0x{systembyte:X8}] {msg}");
 }
EXAMPLE #24
0
 public static IDisposable Subscribe(this ISecsDevice device, SecsMessage filter, Action<SecsMessage> callback) 
     => device.Subscribe(filter, false, callback);
EXAMPLE #25
0
 public static IDisposable Subscribe(this ISecsDevice device, SecsMessage filter, bool recoverable, Action<SecsMessage> callback)
 {
     var subscription = new SecsEventSubscription(device.ToolId, filter, recoverable, callback);
     device.Subscribe(subscription);
     return subscription;
 }
 void EQP_CarrierIDReadFail(SecsMessage msg) {
     byte portNo = (byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0];
     EAP.Report(new CarrierIDReport { 
         LoadPortId = GetPortID(portNo)
     });
 }
EXAMPLE #27
0
 void EQP_UnloadComplete(SecsMessage msg) {
     EAP.Report(new UnloadCompleteReport {
         PortID = GetPortID((byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0])
     });
 }
EXAMPLE #28
0
 internal protected abstract void HandleToolAlarm(SecsMessage msg);
EXAMPLE #29
0
 void EQP_ProcessJobEnd(SecsMessage msg) {
     string id = msg.SecsItem.Items[2].Items[0].Items[1].Items[0].GetValue<string>().Trim();
     EAP.Report(new ProcessJobEndReport { ProcessJobID = id });
     EAP.Report(new DataCollectionCompleteReport(GetProcessJob(id)));
 }  

EXAMPLE #30
0
 void EQP_CarrierIdRead(SecsMessage msg) {
     EAP.Report(new CarrierIDReport {
         LoadPortId = GetPortID((byte)msg.SecsItem.Items[2].Items[0].Items[1].Items[0]),
         CarrierId = (string)msg.SecsItem.Items[2].Items[0].Items[1].Items[1]
     });
 }




FROM https://www.nuomiphp.com/github/5f7042aaada65164e8441a7f.html

secs4net

NuGet

Project Description
SECS-II/HSMS-SS/GEM implementation on .NET. This library provide easy way to communicate with SEMI standard compatible device.

1. Send message to device

try
{
    //await secondary message
    var s3f18 = await device.SendAsync(s3f17); 
    
    //access item value
    byte b1 = (byte)s3f18.SecsItem.Items[0]; 
    byte b2 = s3f18.SecsItem.Items[0].GetValue<byte>();
    string str = s3f18.SecsItem.Items[0].GetString();

    // LINQ query
    var query =
        from a in s3f18.SecsItem.Items[3].Items
        select new {
            num = a.GetValue<int>(),
        };
}
catch(SecsException)
{
    // exception  when
    // T3 timeout
    // device reply SxF0
    // device reply S9Fx
}

2. Handle primary message from device

secsGem.PrimaryMessageReceived += async (sender, messageWrapper) => 
{
    try 
    {
        //do something for primaryMsg
        var primaryMsg = messageWrapper.Message;
	   

        // reply secondary msg to device
        await messageWrapper.ReplyAsync( secondaryMsg ); 
    }
    catch (Exception ex) 
    {

    }
};

3. SecsMessage/Item construction is also LINQ friendly

using static Secs4Net.Item;

var s16f15 = 
    new SecsMessage(16, 15, "CreateProcessJob"            
        L(
            U4(0),
            L(from pj in tx.ProcessJobs select
                L(
                    A(pj.Id),
                    B(0x0D),
                    L(from carrier in pj.Carriers select
                    L(
                        A(carrier.Id),
                        L(from slotInfo in carrier.SlotMap select
                            U1(slotInfo.SlotNo)))),
                        L(
                            U1(1),
                            A(pj.RecipeId),
                            L()),
                        Boolean(true),
                        L()))));

留言

熱門文章