/// <summary> /// when server haven't receive the guf feedback in time, then do this action /// </summary> /// <param name="source"></param> /// <param name="e"></param> public void OnTimedShow(object source, ElapsedEventArgs e) { isGufFeedBack = false; LogerHelper2.ToLog("Server doesn't receive the guf feedback in time", 3); Server.stationList[stationId - 1].errorInfo = "Server doesn't receive the guf feedback in time"; ClientGUFStatus.UpdateStationsData(stationId, 4, ClientStatusType.Error); }
/// <summary> /// when server haven't receive the client in time, then do this action /// </summary> /// <param name="source"></param> /// <param name="e"></param> public void OnTimedShow(object source, ElapsedEventArgs e) { hertbeatCount = 0; LogerHelper2.ToLog("Server doesn't receive the Client Heartbeat in time from station" + stationId.ToString(), 3); Server.stationList[stationId - 1].errorInfo = "Server doesn't receive the Client Heartbeat in time"; ClientGUFStatus.UpdateStationsData(stationId, 1, ClientStatusType.Error); ClientGUFStatus.UpdateStationsData(stationId, 4, ClientStatusType.Error); }
/// <summary> /// the message is about register for station client /// </summary> /// <param name="msg"></param> /// <param name="pos"></param> public void AH_Register(Message msg, string pos) { if (pos == "r") { stationList[int.Parse(msg.stationId) - 1].stationNo = int.Parse(msg.Info); stationList[int.Parse(msg.stationId) - 1].isAvaliable = true; stationList[int.Parse(msg.stationId) - 1].errorInfo = ""; // after stationList[int.Parse(msg.stationId) - 1].aTimer.Enabled = true; //timer可用 //UpdateStation(msg.stationId, ClientStatusType.Idle); LogerHelper2.ToAutoTestLogFile(DateTime.Now.ToString() + ": Tester " + msg.stationId + " register to server"); } else if (pos == "g") { gufList[int.Parse(msg.stationId) - 1].stationNo = int.Parse(msg.Info); if (gufList[int.Parse(msg.stationId) - 1].stationId == -1) { // first time to register GUF gufList[int.Parse(msg.stationId) - 1].gufStatus = 0; //0-OK gufList[int.Parse(msg.stationId) - 1].stationId = int.Parse(msg.stationId); UpdateStation(msg.stationId, ClientStatusType.Idle); } else { //recover the GUF int stid = int.Parse(msg.stationId); // if (gufList[stid - 1].gufStatus == 1 && (stationList[stid - 1].errorInfo.ToLower().Contains("heartbeat") && stationList[stid - 1].errorInfo.ToLower().Contains("guf"))) // exception { gufList[int.Parse(msg.stationId) - 1].gufStatus = 0; //0-OK stationList[stid - 1].errorInfo = ""; ClientGUFStatus.UpdateStationsData(stid, 3, ClientStatusType.Pass); ClientGUFStatus.UpdateStationsData(stid, 4, ClientStatusType.Unknown); if (stationList[stid - 1].clientStatusType == ClientStatusType.Idle && stationList[stid - 1].isAvaliable == true) { QueryMessageListAndRunFirstMessage("DUTID"); } } } LogerHelper2.ToAutoTestLogFile(DateTime.Now.ToString() + ": GUF " + msg.stationId + " register to server"); } else if (pos == "x") { gufList[int.Parse(msg.stationId) - 1].stationNo = int.Parse(msg.Info); gufList[int.Parse(msg.stationId) - 1].gufStatus = 0; //0-OK gufList[int.Parse(msg.stationId) - 1].stationId = int.Parse(msg.stationId); stationList[int.Parse(msg.stationId) - 1].errorInfo = ""; // after stationList[int.Parse(msg.stationId) - 1].stationNo = int.Parse(msg.Info); stationList[int.Parse(msg.stationId) - 1].isAvaliable = true; stationList[int.Parse(msg.stationId) - 1].aTimer.Enabled = true; //timer可用 UpdateStation(msg.stationId, ClientStatusType.Idle); LogerHelper2.ToAutoTestLogFile(DateTime.Now.ToString() + ": Tester & GUF " + msg.stationId + " register to server"); } //server.SendMsg(new Message(msg.stationId, msg.MsgId, MsgType.Ack, "ack ok"), stationList[int.Parse(msg.stationId) - 1].ahaddress); }
void SendMsgToServer_ManuallyRestest(int stationNo, string dutid) { //if (PlCisbusy == false) { gufList[stationNo - 1].gufStatus = 0; ClientGUFStatus.UpdateStationsData(stationNo, 3, ClientStatusType.Pass); //PlcMessageQueue.DeleteMsg(stationNo.ToString()); server.SendMsg(new Message(stationNo.ToString(), 1, MsgType.NewDut, dutid), stationList[stationNo - 1].ahaddress);//dutid LogerHelper2.ToLog("Manually Retest DUT " + dutid + " on T" + stationNo, 2); } //else //{ // RobotPLCStatus.UpdateRobotPLCStatus("busy"); //} }
/// <summary> /// open the timer for moniter the station client heartbeat, if receiver the hearbeat then reset the timer /// </summary> /// <param name="stationId"></param> public void CheckHeartbeat(string stationId) { if (stationList[int.Parse(stationId) - 1].hertbeatCount == 0) { stationList[int.Parse(stationId) - 1].aTimer.Enabled = true; //timer可用 stationList[int.Parse(stationId) - 1].hertbeatCount++; if (stationList[int.Parse(stationId) - 1].errorInfo.ToLower().Contains("heartbeat") && stationList[int.Parse(stationId) - 1].errorInfo.ToLower().Contains("client")) // only update the timeout warning, other warning should kept { stationList[int.Parse(stationId) - 1].errorInfo = ""; ClientGUFStatus.UpdateStationsData(int.Parse(stationId), 1, ClientStatusType.Pass); ClientGUFStatus.UpdateStationsData(int.Parse(stationId), 4, ClientStatusType.Unknown); } } else { stationList[int.Parse(stationId) - 1].aTimer.Stop(); stationList[int.Parse(stationId) - 1].aTimer.Start(); } }
public static void delegateforDebug() { // add deleget here ClientGUFStatus.UpdateStationsData(1, 1, ClientStatusType.Unknown); }
/// <summary> /// after reveiver the TM status , updatesation status according /// </summary> /// <param name="StationId"></param> /// <param name="ClientStatusType"></param> public void UpdateStation(string StationId, ClientStatusType ClientStatusType) { if (StationId == null || ClientStatusType == null) { LogerHelper2.ToLog("station id is null ", 3); return; } int id = int.Parse(StationId); int what = 0; // 1- test station; 2- dut test; 3-GUF ; 4- warning switch (ClientStatusType) { case ClientStatusType.Error: stationList[id - 1].clientStatusType = ClientStatusType.Error; //ClientGUFStatus.UpdateStationsData(id, 2, stationList[id - 1].clientStatusType); ClientGUFStatus.UpdateStationsData(id, 4, stationList[id - 1].clientStatusType); if (stationList[id - 1].errorInfo.ToLower().Contains("guf")) // just GUF error { gufList[id - 1].gufStatus = 1; what = 3; } else if (stationList[id - 1].errorInfo.ToLower().Contains("crashed") && stationList[id - 1].errorInfo.ToLower().Contains("tm")) // TM crashed { what = 2; } else if (stationList[id - 1].errorInfo.ToLower().Contains("pop-up") && stationList[id - 1].errorInfo.ToLower().Contains("window")) // detect pop-up windows during test { what = 4; } else // test staton error { stationList[id - 1].isAvaliable = false; ClientGUFStatus.UpdateStationsData(id, 2, stationList[id - 1].clientStatusType); what = 1; } break; case ClientStatusType.Pass: stationList[id - 1].clientStatusType = ClientStatusType.Pass; stationList[id - 1].timeoutTimer.Stop(); what = 2; break; case ClientStatusType.Fail: stationList[id - 1].clientStatusType = ClientStatusType.Fail; stationList[id - 1].timeoutTimer.Stop(); what = 2; break; case ClientStatusType.Idle: stationList[id - 1].clientStatusType = ClientStatusType.Idle; stationList[id - 1].onTestingSerialNumber = ""; ClientGUFStatus.UpdateStationsData(id, 1, ClientStatusType.Pass); // use Pass to on behalf of avaliable or normal //LogerHelper2.ToLog("stationId is " + id + "," + "what = " + 1 , 0); if (stationList[id - 1].errorInfo.Length == 0) { ClientGUFStatus.UpdateStationsData(id, 4, ClientStatusType.Unknown); // use Pass to on behalf of avaliable or normal //LogerHelper2.ToLog("stationId is " + id + "," + "what = " + 4, 0); } if (gufList[id - 1].gufStatus == 0) { ClientGUFStatus.UpdateStationsData(id, 3, ClientStatusType.Pass); // use Pass to on behalf of avaliable or normal //QueryMessageListAndRunFirstMessage("DUTID"); //LogerHelper2.ToLog("stationId is " + id + "," + "what = " + 3, 0); } what = 2; // set the test status to idle, so that could test the rest tasks QueryMessageListAndRunFirstMessage("DUTID"); break; case ClientStatusType.Unknown: stationList[id - 1].clientStatusType = ClientStatusType.Unknown; what = 2; break; case ClientStatusType.Run: stationList[id - 1].clientStatusType = ClientStatusType.Run; if (stationTimeoutTime > 0) { stationList[id - 1].timeoutTimer.Interval = stationTimeoutTime; stationList[id - 1].timeoutTimer.Enabled = true; //stationList[id - 1].timeoutTimer.Start(); } what = 2; break; case ClientStatusType.Abort: stationList[id - 1].clientStatusType = ClientStatusType.Abort; stationList[id - 1].timeoutTimer.Stop(); what = 2; break; default: return; } // add deleget here ClientGUFStatus.UpdateStationsData(id, what, stationList[id - 1].clientStatusType); //LogerHelper2.ToLog("*********stationId is " + id + "," + "what = " + what, 0); }
/// <summary> /// the message is about guf status feedback when server send the query to station client /// </summary> /// <param name="msg"></param> public void AH_GufFeedback(Message msg) { if (msg.Info == "E") { stationList[int.Parse(msg.stationId) - 1].errorInfo = msg.ErrorInfo; //re-load the FetchFreeStation, to avoid the station that just with GUF abnormal will not be used forever int freeStationID = FetchFreeStation(int.Parse(msg.stationId)); if (freeStationID >= 1 && freeStationID <= 6) { stationList[freeStationID - 1].clientStatusType = ClientStatusType.Wait; //server.SendMsg(new Message(freeStationID.ToString(), 1, MsgType.QueryClientStatus, ""), stationList[freeStationID - 1].ahaddress); } else { //idMessageQueue.sendMsg("DUTID", newDutNm, System.Messaging.MessagePriority.Normal); // if there is no idle station, send the id message to messagequeue //LogerHelper2.ToLog("NO freestation, add newdutid <" + newDutNm + "> to queue. idqueue number is: " + idMessageQueue.messageNum, 2); } return; } string[] strmsg2 = msg.Info.Split('|'); string ifgufopen = strmsg2[0]; string ifdut = strmsg2[1]; if (ifdut == "H" || ifgufopen == "C") { //stationList[int.Parse(msg.stationId) - 1].isAvaliable = false; //stationList[int.Parse(msg.stationId) - 1].clientStatusType = ClientStatusType.Error; //IF fixture is not abnormal, then show the warning, but station is still avaliable, or else this station will always unavaliable gufList[int.Parse(msg.stationId) - 1].gufStatus = 1; // 1-NOK stationList[int.Parse(msg.stationId) - 1].errorInfo = "Have Dut or the fixture is connect"; // msg.ErrorInfo; stationList[int.Parse(msg.stationId) - 1].clientStatusType = ClientStatusType.Idle; ClientGUFStatus.UpdateStationsData(int.Parse(msg.stationId), 3, ClientStatusType.Error); ClientGUFStatus.UpdateStationsData(int.Parse(msg.stationId), 4, ClientStatusType.Error); //re-load the FetchFreeStation, to avoid the station that just with GUF abnormal will not be used forever int freeStationID = FetchFreeStation(int.Parse(msg.stationId)); if (freeStationID >= 1 && freeStationID <= 6) { stationList[freeStationID - 1].clientStatusType = ClientStatusType.Wait; //server.SendMsg(new Message(freeStationID.ToString(), 1, MsgType.QueryClientStatus, ""), stationList[freeStationID - 1].ahaddress); } else { //idMessageQueue.sendMsg("DUTID", newDutNm, System.Messaging.MessagePriority.Normal); // if there is no idle station, send the id message to messagequeue //LogerHelper2.ToLog("NO freestation, add newdutid <" + newDutNm + "> to queue. idqueue number is: " + idMessageQueue.messageNum, 2); } } else if (ifdut == "N" && ifgufopen == "O") { if (PlCisbusy == false && plcserver.isPLConLine == true) {//update the GUI if it was abnormal before stationList[int.Parse(msg.stationId) - 1].errorInfo = ""; gufList[int.Parse(msg.stationId) - 1].gufStatus = 0; ClientGUFStatus.UpdateStationsData(int.Parse(msg.stationId), 3, ClientStatusType.Pass); ClientGUFStatus.UpdateStationsData(int.Parse(msg.stationId), 4, ClientStatusType.Unknown); //MoveToStationID = freeStationID; stationList[int.Parse(msg.stationId) - 1].onTestingSerialNumber = newDutNm; //newSerailNumber.Dequeue().ToString(); plcserver.MoveDUTtoTester(msg.stationId); PlCisbusy = true; } else if (PlCisbusy == true) { stationList[int.Parse(msg.stationId) - 1].clientStatusType = ClientStatusType.Idle; //idMessageQueue.sendMsg("DUTID", newDutNm, System.Messaging.MessagePriority.Normal); //LogerHelper2.ToLog("plc is busy, add <" + newDutNm + "> to idqueue again, id queue number is:" + idMessageQueue.messageNum, 2); } else { //idMessageQueue.sendMsg("DUTID", newDutNm, System.Messaging.MessagePriority.Normal); //LogerHelper2.ToLog("plc is offline, add <" + newDutNm + "> to idqueue again, id queue number is:" + idMessageQueue.messageNum, 2); } } }
/// <summary> /// the message is about TM test states, like pass,fail, abort, error,idle and running /// </summary> /// <param name="msg"></param> public void AH_Status(Message msg) { if (msg.Info == "P") { stationList[int.Parse(msg.stationId) - 1].DUTTestConsecutiveFailedTimes = 0; UpdateStation(msg.stationId, ClientStatusType.Pass); ControlPLCMoveDUTAwayStation(msg); //record test result for test yield statistics TestStationData.RecordTesterYieldData(msg.stationId, ClientStatusType.Pass); //record dut test result to system log LogerHelper2.RecordDutTestResultToSystemLog(msg.stationId, msg.DutID.Split('|')[0], ClientStatusType.Pass); } else if (msg.Info == "F" || msg.Info == "A") { string[] strmsg = msg.DutID.Split('|'); string DutId = strmsg[0]; if (strmsg.Length > 1) //print the fail infromation in windows { stationList[int.Parse(msg.stationId) - 1].errorInfo = strmsg[1]; ClientGUFStatus.UpdateStationsData(int.Parse(msg.stationId), 4, ClientStatusType.Fail); } stationList[int.Parse(msg.stationId) - 1].currentDUTtestedCount++; UpdateStation(msg.stationId, msg.Info == "F" ? ClientStatusType.Fail : ClientStatusType.Abort); if (DUTReTest.isNeedReTest(int.Parse(msg.stationId), DutId) && isKill[int.Parse(msg.stationId) - 1] == false) // check whether need retest { server.SendMsg(new Message(msg.stationId, 1, MsgType.NewDut, DutId), stationList[int.Parse(msg.stationId) - 1].ahaddress); //dutid } else { if (isKill[int.Parse(msg.stationId) - 1] == true) { isKill[int.Parse(msg.stationId) - 1] = false; } else { stationList[int.Parse(msg.stationId) - 1].DUTTestConsecutiveFailedTimes++; } ControlPLCMoveDUTAwayStation(msg); //record test result for test yield statistics TestStationData.RecordTesterYieldData(msg.stationId, ClientStatusType.Fail); //record dut test result to system log LogerHelper2.RecordDutTestResultToSystemLog(msg.stationId, DutId, ClientStatusType.Fail); if (stationList[int.Parse(msg.stationId) - 1].DUTTestConsecutiveFailedTimes >= DUTReTest.alarmWhenDUTTestFailTimes) { stationList[int.Parse(msg.stationId) - 1].isAvaliable = false; stationList[int.Parse(msg.stationId) - 1].errorInfo = "DUT test consecutive failures"; UpdateStation(msg.stationId, ClientStatusType.Error); } } // ControlPLCMoveDUTAwayStation(msg); } else if (msg.Info == "I") { UpdateStation(msg.stationId, ClientStatusType.Idle); } else if (msg.Info == "R") { UpdateStation(msg.stationId, ClientStatusType.Run); } else if (msg.Info == "E") { //stationList[int.Parse(msg.stationId) - 1].isAvaliable = false; stationList[int.Parse(msg.stationId) - 1].errorInfo = msg.ErrorInfo; UpdateStation(msg.stationId, ClientStatusType.Error); } else { LogerHelper2.ToLog("Client " + msg.stationId + "sends strange status", 4); } }
/// <summary> /// the event of server receive message from PLC, different messagetype do different action /// </summary> /// <param name="sender">plc ip&port</param> /// <param name="msg">plc message</param> public void plcserver_MessageReceived(object sender, MainPLCMessage msg) { if (msg.InvalidMessage == true) { LogerHelper2.ToLog("error format PLC commond" + msg.Info, 3); return; } string msgTemp = null; try { msgTemp = string.Format("From PLC: MessageHead: {0}\t Info:{1}", msg.MsgHead.ToString(), msg.Info.ToString()); } catch (Exception e) { LogerHelper2.ToLog(e.Message, 2); } //LogerHelper2.ToLog(msg.MsgType + " " + msg.MsgHead + " " + msg.StationId + " " + msg.Info, 0); if (msg.MsgType != PLCMsgType.Heartbead) { LogerHelper2.ToLog(msgTemp, 0); } else { LogerHelper2.ToLog(msgTemp, 4); } int freeStationID; string MessageHead = msg.MsgHead; string MessageInfo = msg.Info; //LogerHelper2.ToLog(msg.MsgType + " " , 0); switch (msg.MsgType) { case PLCMsgType.ReportMsg: if (MessageHead == MainPLCMessage.DUTIdToServer) { plcserver.NewSNFeedback(); //feedback plc F020 //check the dutid, if it same as the current test duts? ignore it if yes if (!check_DUTID_Valid(msg.Info)) { LogerHelper2.ToLog("Found new Dut Id <" + msg.Info + "> is same as current testing Duts' Id, will ignore this new Dut Id ", 2); LogerHelper2.ToAutoTestLogFile(DateTime.Now.ToString() + ": Dut ID: " + msg.Info + " duplicated with the current testing Duts' Id, will ignore it."); return; } freeStationID = FetchFreeStation(); int loop = 0; while (loop < stationList.Length) { newDutNm = msg.Info; //newSerailNumber.Enqueue(msg.Info); // when coming a new sn, add to qu if (freeStationID >= 1 && freeStationID <= 6) { stationList[freeStationID - 1].clientStatusType = ClientStatusType.Wait; //if (server.SendMsg(new Message(freeStationID.ToString(), 1, MsgType.QueryClientStatus, ""), stationList[freeStationID - 1].ahaddress)) //{ // break; //} freeStationID = FetchFreeStation(freeStationID); } else { //idMessageQueue.sendMsg("DUTID", msg.Info, System.Messaging.MessagePriority.Normal); // if there is no idle station, send the id message to messagequeue //LogerHelper2.ToLog("NO freestation, add newdutid <" + msg.Info + "> to queue. idqueue number is: " + idMessageQueue.messageNum, 2); break; } loop++; } if (loop >= stationList.Length) { //idMessageQueue.sendMsg("DUTID", msg.Info, System.Messaging.MessagePriority.Normal); // if there is no idle station, send the id message to messagequeue //LogerHelper2.ToLog("NO freestation, add newdutid <" + msg.Info + "> to queue. idqueue number is: " + idMessageQueue.messageNum, 2); } } break; case PLCMsgType.Feedback: plcserver.stopPlcCommandTimer(); System.Threading.Thread.Sleep(1000); //sleep wait PLC ready if (MessageHead == MainPLCMessage.MoveDUTToStationACK) { //PlCisbusy = false; RobotPLCStatus.UpdateRobotPLCStatus("Idle"); server.SendMsg(new Message(msg.StationId.ToString(), 1, MsgType.NewDut, stationList[msg.StationId - 1].onTestingSerialNumber), stationList[msg.StationId - 1].ahaddress); //dutid UpdateStation(msg.StationId.ToString(), ClientStatusType.Run); //PlcMessageQueue.DeleteMsg(msg.StationId.ToString()); PlCisbusy = false; } else if (MessageHead == MainPLCMessage.MoveDUTFromStationACK) { isOutBufferFree = false; // here add if to check whether the tester is set to offline? if ((stationList[msg.StationId - 1].isForcedOffLine == true) || (stationList[msg.StationId - 1].DUTTestConsecutiveFailedTimes >= DUTReTest.alarmWhenDUTTestFailTimes)) { stationList[msg.StationId - 1].isAvaliable = false; stationList[msg.StationId - 1].isForcedOffLine = false; stationList[msg.StationId - 1].errorInfo = "This station was forced offline by admin or DUT test consecutive failures"; UpdateStation((msg.StationId).ToString(), ClientStatusType.Error); ClientGUFStatus.UpdateStationsData(msg.StationId, 2, ClientStatusType.Unknown); ClientGUFStatus.UpdateStationsData(msg.StationId, 3, ClientStatusType.Unknown); } else { //PlCisbusy = false; RobotPLCStatus.UpdateRobotPLCStatus("Idle"); stationList[msg.StationId - 1].isAvaliable = true; stationList[msg.StationId - 1].currentDUTtestedCount = 0; stationList[msg.StationId - 1].onTestingSerialNumber = ""; UpdateStation((msg.StationId).ToString(), ClientStatusType.Idle); } PlCisbusy = false; } else if (MessageHead == MainPLCMessage.queryPLCStateACK) { PlCisbusy = msg.PLCIsBusy; } if (PlCisbusy == false) { QueryMessageListAndRunFirstMessage("DUTSTATUS"); } break; case PLCMsgType.Heartbead: // RobotPLCStatus.UpdateRobotPLCStatus("Connected"); plcserver.CheckHeartbeat(); break; case PLCMsgType.Ack: plcserver.plcResendCommandTimer.Stop(); plcserver.lastAction = string.Empty; break; default: break; } }
void timeoutTimer_Elapsed(object sender, ElapsedEventArgs e) { LogerHelper2.ToLog("Station " + stationId.ToString() + " has Started over " + timeoutTimer.Interval / 60000 + " Mins", 3); Server.stationList[stationId - 1].errorInfo = "Station " + stationId.ToString() + " has started over " + timeoutTimer.Interval / 60000 + " Mins"; ClientGUFStatus.UpdateStationsData(stationId, 4, ClientStatusType.Error); }