using Aurora.Api; using AuroraCellTracker; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using WeldingCommon.Sequences; using WeldingCommon; using AuroraLaserScanner; using WeldingCommon.Settings; using WeldingCommon.Utils; using AuroraLaser; using AuroraOCT; using AuroraPLC; using AuroraIO; using VisionCommon; using CoreUnit.Scanner.UserControl.ScannerCanvas; using Aurora.Api.Manager; using AuroraLBAD; using CoreUnit.Control.UserControl.Canvas; using Matrox.MatroxImagingLibrary; using WeldingCommon.Vision.WeldingObjectGenerator; using OpenCvSharp; using System.Diagnostics; using ILSOS_PrismaticRD_PTOP.Models; using Aurora; using DB.Recipe; using System.Runtime.Remoting.Contexts; using System.IO; using System.Text.RegularExpressions; using WeldingCommon.Utils; using System.Threading; using OpenCvSharp.Dnn; using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo; using DB; using System.Configuration; using System.Runtime.InteropServices.ComTypes; using System.Windows.Media.Imaging; using OpenCvSharp.WpfExtensions; using System.Windows; using Aurora.View; using System.Drawing; using System.Collections.ObjectModel; using WeldingCommon.Views; using WeldingCommon.Data; using Hermes; using System.CodeDom.Compiler; using static Aurora.Api.SequenceBuilder; using WeldingCommon.Devices; using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP; using System.Windows.Forms.VisualStyles; using static AuroraIO.Vendor.PAIX.PAIXIO; using WeldingCommon.Alarm; using ILSOS_PrismaticRD_PTOP.Device; namespace ILSOS_PrismaticRD_PTOP.Sequences { class SeqAutoRunComponentWeld { static readonly Logger Log = new Logger("SeqAutoRunPrismatic"); const string SEQ_ENTER = "SEQ_ENTER"; // inputParam 으로 받자. const string SEQ_CHECK_INIT_CONDITION = "Check Init Condition"; // Check Init Condition const string SEQ_GET_PLC_WELD_TRIGGER_REQ_ON = "Get PLC Weld Ready Request On"; // PLC 용접 준비 요청 수신 const string SEQ_CHECK_CELL_INFO_RECEIVE = "Check Cell Info Receive"; // 셀 정보 수신 확인 const string SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ = "Get Sequence Result (ReceiveCellInfo Seq)"; const string SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ = "Process (ReceiveCellInfo Seq)"; const string SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ = "Set Sequence Param (ReceiveCellInfo Seq)"; const string SEQ_SET_PC_WELD_TRIGGER_ACK_ON_WITH_CELL = "Set PC Weld Ready Ack On With Cell"; // 셀과 함께 PC 용접 준비 확인 const string SEQ_MEASURE_CELL_POSITION = "Measure Cell Position"; // 셀 위치 측정 const string SEQ_SET_MIL_MODEL_FINDER_SEQ = "Set MIL Model Finder Seq"; // MIL 모델 찾기 시퀀스 설정 const string SEQ_DO_ID_MIL_MODEL_FINDER_SEQ = "Process (MIL Model Finder Seq)"; // MIL 모델 찾기 시퀀스 처리 const string SEQ_GET_MIL_MODEL_FINDER_SEQ = "Get MIL Model Finder Seq"; // MIL 모델 찾기 시퀀스 가져오기 const string SEQ_GENERATE_WELDING_OBJECT = "Generate Welding Object"; // 용접 객체 생성 const string SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ = "Set Params Upload Welding List Seq"; // 용접 리스트 업로드 파라미터 설정 const string SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ = "Process (Upload Welding List Seq)"; // 용접 리스트 업로드 시퀀스 처리 const string SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ = "Get Result Upload Welding List Seq"; // 용접 리스트 업로드 결과 가져오기 const string SEQ_GET_PLC_WELD_TRIGGER_REQ_OFF = "Get PLC Weld Ready Request Off"; // PLC 용접 준비 요청 종료 const string SEQ_SET_PC_WELD_TRIGGER_ACK_OFF = "Set PC Weld Ready Ack Off"; // PC 용접 준비 확인 종료 const string SEQ_WAIT_WELDING_START = "Wait Welding Start"; // 용접 시작 대기 const string SEQ_EXECUTE_WELDING = "Execute Welding"; // 용접 실행 const string SEQ_CHECK_VISION_COMPENSION_USE = "Check Vision Compensation Use"; // 비전 보상 사용 확인 const string SEQ_CHECK_PLC_WELDING_COMPLETE = "Check Rewelding Request"; // 재용접 요청 확인 const string SEQ_SET_PC_WELD_COMPLETE_ON = "Set PC Weld Complete On"; // PC 용접 완료 설정 const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END = "Set PC Weld Complete Off With End"; // 종료와 함께 PC 용접 완료 설정 const string SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF = "Set PLC Weld Complete Ack Off"; // PLC 용접 완료 확인 종료 const string SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY = "Set PC Weld Complete Off With Retry"; // 재시도와 함께 PC 용접 완료 설정 const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON = "Set PC Page Change Complete On"; // PC 페이지 변경 완료 설정 const string SEQ_GET_PLC_PAGE_REQ_OFF = "Get PLC Page Request Off"; // PLC 페이지 요청 종료 const string SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF = "Set PC Page Change Complete Off"; // PC 페이지 변경 완료 종료 const string SEQ_SAVE_RESULT_DATA = "Save Result Data"; // 결과 데이터 저장 const string SEQ_COMPLETE = "SEQ_COMPLETE"; // 완료 static class ContextKey { public const string KEY_SEQUENCE_RESULT = "KEY_SEQUENCE_RESULT_SeqAutoRunPrismatic"; public const string KEY_SEQUENCE_START_TIME = "KEY_SEQUENCE_START_TIME_SeqAutoRunPrismatic"; } const int PLC_TIMEOUT = 60; // sec, Timeout은 시퀀스 정지가 아니라 타임아웃 시간마다 로그만 남기도록 한다 #region 변수 정의 // 디바이스 정의 private Scanner _Scanner; private Laser _Laser; private PLCControllerPTOP _PLC; private IODevice _IO; // 비전 정의 private FovRecipe _FovRecipe; private CameraAgentBase _CameraAgent; private ICameraDisplay _CameraDisplay; private CamConfig _CamConfig; private MIL_ID _GrabImage = MIL.M_NULL; private int _Raduis_Pixel; // 시스템 및 용접 파라미터 정의 private SystemParameter _SystemParameter; private ScannerCanvasUserCtrl _ScannerCanvasUserCtrl; //스캐너 동작관련 객체 선언 private List _SelectedDrawObjectList; private SeqAutoRunPrismatic_InitParam _InitParam; // 생산 데이터 정의 private uint _TodayProduct; private uint _TotalProduct; private DateTime _AutoRunStartTime; private DateTime _WeldStartTime; private DateTime _WeldEndTime; private TimeSpan _WeldSpanTime; private TimeSpan _InterfaceSpanTime; private DateTime _InterfaceStartTime; private string _LotId = "N/A"; private string _CellId = "N/A"; const int timeoutSeconds = 10; #endregion public SequenceBuilder Builder() { var sb = new SequenceBuilder(1000, true); ////var sb = new SequenceBuilder(1000, false); // With log sb.AddAction(SEQ_ENTER, Sequence_Enter); sb.AddDecision(SEQ_CHECK_INIT_CONDITION, CheckInitCondition); //분기 ////// PLC_WELD_TRIGGER_REQ ON Check & Cell Load sb.AddAction(SEQ_GET_PLC_WELD_TRIGGER_REQ_ON, GetPlcWeldReadyReqOn); sb.AddDecision(SEQ_CHECK_CELL_INFO_RECEIVE, CheckCellInfoReceive); sb.AddAction(SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ, SetReceiveCellInfo_SeqParams); sb.AddSubsequence(SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ, SequenceManager.GetSeqBuilder_SeqReceiveCellInfo()); sb.AddAction(SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ, GetReceiveCellInfo_SeqResult); ////// PC_WELD_TRIGGER_ACK ON & PLC_WELD_TRIGGER_REQ OFF Check & Use Model Finder sb.AddAction(SEQ_SET_PC_WELD_TRIGGER_ACK_ON_WITH_CELL, SetPcWeldReadyAckOnWithCell); sb.AddAction(SEQ_GET_PLC_WELD_TRIGGER_REQ_OFF, GetPlcWeldReadyReqOff); sb.AddDecision(SEQ_CHECK_VISION_COMPENSION_USE, CheckVisionCompensationUse); sb.AddAction(SEQ_MEASURE_CELL_POSITION, MeasureCellPosition); sb.AddAction(SEQ_SET_MIL_MODEL_FINDER_SEQ, SetMilModelFinder_SeqParams); ///* 반드시 변경 필요함. FlyingVision은 아님. */// sb.AddSubsequence(SEQ_DO_ID_MIL_MODEL_FINDER_SEQ, SequenceManager.GetSeqBuilder_SeqScoutFlyingVision()); sb.AddAction(SEQ_GET_MIL_MODEL_FINDER_SEQ, GetMilModelFinder_SeqResult); sb.AddAction(SEQ_GENERATE_WELDING_OBJECT, GenerateWeldingObject); ////// PC_WELD_TRIGGER_ACK OFF & Weld Start / Complete sb.AddAction(SEQ_SET_PC_WELD_TRIGGER_ACK_OFF, SetPcWeldReadyAckOff); sb.AddAction(SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ, SetUploadWeldingList_SeqParams); sb.AddSubsequence(SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ, CommonSequenceManager.GetSeqBuilder_SeqUploadWeldingList()); sb.AddAction(SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ, GetUploadWeldingList_SeqResult); sb.AddAction(SEQ_WAIT_WELDING_START, WaitWeldingStart); sb.AddAction(SEQ_EXECUTE_WELDING, ExecuteWelding); /////// Check Welding Retry Request sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_ON, SetPcWeldCompleteOn); sb.AddDecision(SEQ_CHECK_PLC_WELDING_COMPLETE, SeqCheckPlcWeldingComplete); sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END, SetPcWeldCompleteOffWithEnd); sb.AddAction(SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF, GetPlcWeldCompleteAckOff); sb.AddAction(SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY, SetPcWeldCompleteOffWithRetry); sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON, SetPcPageChangeCompleteOn); sb.AddAction(SEQ_GET_PLC_PAGE_REQ_OFF, GetPlcPageReqOff); sb.AddAction(SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF, SetPcPageChangeCompleteOff); sb.AddAction(SEQ_SAVE_RESULT_DATA, SaveResultData); // 해당 공정의 정보를 기록 함. sb.AddAction(SEQ_COMPLETE, Complete); sb.Flows(sb.Init > sb[SEQ_ENTER] > sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_GET_PLC_WELD_TRIGGER_REQ_ON] > sb[SEQ_CHECK_CELL_INFO_RECEIVE] > sb[SEQ_SET_PARAMS_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_DO_ID_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_GET_PARAMS_RECEIVE_CELL_INFO_SEQ] > sb[SEQ_SET_PC_WELD_TRIGGER_ACK_ON_WITH_CELL] > sb[SEQ_GET_PLC_WELD_TRIGGER_REQ_OFF] > sb[SEQ_CHECK_VISION_COMPENSION_USE] > sb[SEQ_MEASURE_CELL_POSITION] > sb[SEQ_SET_MIL_MODEL_FINDER_SEQ] > sb[SEQ_DO_ID_MIL_MODEL_FINDER_SEQ] > sb[SEQ_GET_MIL_MODEL_FINDER_SEQ] > sb[SEQ_GENERATE_WELDING_OBJECT] > sb[SEQ_SET_PC_WELD_TRIGGER_ACK_OFF] > sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_DO_ID_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_GET_RESULT_UPLOAD_WELDING_LIST_SEQ] > sb[SEQ_WAIT_WELDING_START] > sb[SEQ_EXECUTE_WELDING] > sb[SEQ_SET_PC_WELD_COMPLETE_ON] > sb[SEQ_CHECK_PLC_WELDING_COMPLETE] > sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END] > sb[SEQ_GET_PLC_WELD_COMPLETE_ACK_OFF] > sb[SEQ_SAVE_RESULT_DATA] > sb[SEQ_COMPLETE]); // SEQ_CHECK_INIT_CONDITION sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_COMPLETE] > sb.Final); // SEQ_CHECK_CELL_INFO_RECEIVE sb.Flows(sb[SEQ_CHECK_CELL_INFO_RECEIVE] > sb[SEQ_SET_PC_WELD_TRIGGER_ACK_ON_WITH_CELL]); // SEQ_CHECK_VISION_COMPENSION_USE sb.Flows(sb[SEQ_CHECK_VISION_COMPENSION_USE] > sb[SEQ_SET_PC_WELD_TRIGGER_ACK_OFF]); // SEQ_CHECK_PLC_WELDING_COMPLETE sb.Flows(sb[SEQ_CHECK_PLC_WELDING_COMPLETE] > sb[SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY] > sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_ON] > sb[SEQ_GET_PLC_PAGE_REQ_OFF] > sb[SEQ_SET_PC_PAGE_CHANGE_COMPLETE_OFF] > sb[SEQ_CHECK_VISION_COMPENSION_USE]); sb.OnStopped(OnStopped); sb.OnForceError(OnForceError); //sb.Draw("SeqAutoRunComponentWeld.pdf"); return sb; } #region 시퀸스 함수 private SequenceActionResult Sequence_Enter(SequenceContext context, string id, SequenceActionResult param) { Log.I("SeqAutoRunPrismatic Start"); _InitParam = param.Param as SeqAutoRunPrismatic_InitParam; _SystemParameter = context.GetSetting(CommonSettingIds.SystemParameter); InitDev(context); if (!CheckDeviceReady(context)) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_DeviceNotReady); Log.E("The devices are not active."); return null; } if (InitSequenceVariable(context) == false) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_InitVariableError); return null; } return SequenceAction.Ok(); } private string CheckInitCondition(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (!CheckCondition(context)) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_CheckInitCondition); Log.E("Condition is not in state to start sequence."); context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, false); return SEQ_COMPLETE; } var startTime = DateTime.Now; context.PutValue(ContextKey.KEY_SEQUENCE_START_TIME, startTime); return SEQ_SAVE_RESULT_DATA; } private SequenceActionResult GetPlcWeldReadyReqOn(SequenceContext context, string id, SequenceActionResult param) { // while context가 적절한지 고민이 됨. while (!context.Stopped) { if (_PLC.ReadBit(eBitInput.PLC_WELD_TRIGGER_REQ).data){ Log.I(string.Format("PLC Weld Ready Request ON")); break; } } return SequenceAction.Ok(); } private string CheckCellInfoReceive(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset) { Log.I(string.Format("Check Cell Info Receive")); return SEQ_CHECK_CELL_INFO_RECEIVE; } else { Log.I(string.Format("Pass Cell Info Receive")); return SEQ_SET_PC_WELD_TRIGGER_ACK_ON_WITH_CELL; } } private SequenceActionResult SetReceiveCellInfo_SeqParams(SequenceContext context, string id, SequenceActionResult param) { SeqReceiveCellInfo_InitParam seqParams = new SeqReceiveCellInfo_InitParam() { }; return SequenceAction.Ok(seqParams); } private SequenceActionResult GetReceiveCellInfo_SeqResult(SequenceContext context, string id, SequenceActionResult param) { var resultOutParam = param.Param as SeqReceiveCellInfo_OutParam; if (resultOutParam.Success == false) { return null; } return SequenceAction.Ok(); } private SequenceActionResult SetPcWeldReadyAckOnWithCell(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_WELD_TRIGGER_ACK, true); // Cell ID를 PLC에 적어줄지 고민해볼 것. Log.I(string.Format("Set PC Weld Ready Ack On With Cell")); return SequenceAction.Ok(); } private SequenceActionResult GetPlcWeldReadyReqOff(SequenceContext context, string id, SequenceActionResult param) { // Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess Func plcResponse = () => _PLC.ReadBit(eBitInput.PLC_WELD_TRIGGER_REQ).data; var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000); if (res == E2.TIMEOUT) { Log.FuncE("Get PLC Weld Ready Request OFF Timeout !"); return null; } else Log.I(string.Format("Get PLC Weld Ready Request Complete")); return SequenceAction.Ok(); } private string CheckVisionCompensationUse(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { if (_SystemParameter.SequenceType == eSequenceType.CellCenterOffset) { Log.I(string.Format("Use Vision Compensation")); return SEQ_MEASURE_CELL_POSITION; } else { Log.I(string.Format("Unuse Vision Compensation")); return SEQ_SET_PC_WELD_TRIGGER_ACK_OFF; } } private SequenceActionResult MeasureCellPosition(SequenceContext context, string id, SequenceActionResult param) { double ScannerPosX = 0, ScannerPosY = 0; // 처음 객체 기반의 중앙 기반 FindFirstObjectCenter(out ScannerPosX, out ScannerPosY); Log.I(string.Format($"Move Scanner - ScannerPosX : {ScannerPosX},ScannerPosY : {ScannerPosY} ")); _Scanner.JumpAbs(ScannerPosX, ScannerPosY); return SequenceAction.Ok(); } private SequenceActionResult SetMilModelFinder_SeqParams(SequenceContext context, string id, SequenceActionResult param) { throw new NotImplementedException(); } private SequenceActionResult GetMilModelFinder_SeqResult(SequenceContext context, string id, SequenceActionResult param) { throw new NotImplementedException(); } private SequenceActionResult GenerateWeldingObject(SequenceContext context, string id, SequenceActionResult param) { throw new NotImplementedException(); } private SequenceActionResult SetPcWeldReadyAckOff(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_WELD_TRIGGER_ACK, false); Log.I(string.Format("Set PC Weld Ready Ack Off")); return SequenceAction.Ok(); } private SequenceActionResult SetUploadWeldingList_SeqParams(SequenceContext context, string id, SequenceActionResult param) { _WeldStartTime = DateTime.Now; Status.GetProcessingWeldingData().WeldingStartTime = _WeldStartTime; throw new NotImplementedException(); } private SequenceActionResult GetUploadWeldingList_SeqResult(SequenceContext context, string id, SequenceActionResult param) { throw new NotImplementedException(); } private SequenceActionResult WaitWeldingStart(SequenceContext context, string id, SequenceActionResult param) { throw new NotImplementedException(); } private SequenceActionResult ExecuteWelding(SequenceContext context, string id, SequenceActionResult param) { _WeldEndTime = DateTime.Now; _WeldSpanTime = _WeldEndTime.Subtract(_WeldStartTime); UpdateProductCount(context); UpdateProductInfoForView(); throw new NotImplementedException(); } private SequenceActionResult SetPcWeldCompleteOn(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, true); Log.I(string.Format("Set PC Weld Complete On")); return SequenceAction.Ok(); } private string SeqCheckPlcWeldingComplete(SequenceContext context, string id, ICollection branches, SequenceActionResult param) { // Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess Func plcResponse = () => _PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data || _PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data; var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000); if (res == E2.TIMEOUT) { Log.FuncE("Get PLC Welding Complete or Page Change Request Timeout !"); return null; } else { if (_PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data) { Log.I(string.Format("Get PLC Weld Complete Ack On")); return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_END; } else if (_PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data) { Log.I(string.Format("Get PLC Page Change Request On")); return SEQ_SET_PC_WELD_COMPLETE_OFF_WITH_RETRY; } else { Log.I(string.Format("Unexpected Situation.")); return null; } } } private SequenceActionResult SetPcWeldCompleteOffWithEnd(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, false); Log.I(string.Format("Set PC Weld Complete Off For End")); return SequenceAction.Ok(); } private SequenceActionResult GetPlcWeldCompleteAckOff(SequenceContext context, string id, SequenceActionResult param) { // Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess Func plcResponse = () => !_PLC.ReadBit(eBitInput.PLC_WELD_COMPLETE_ACK).data; var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000); if (res == E2.TIMEOUT) { Log.FuncE("Get PLC Welding Complete ACK Off Timeout !"); return null; } else { Log.I(string.Format("Get PLC Weld Complete Ack Off")); } return SequenceAction.Ok(); } private SequenceActionResult SetPcWeldCompleteOffWithRetry(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_WELD_COMPLETE, false); Log.I(string.Format("Set PC Weld Complete On For Retry")); return SequenceAction.Ok(); } private SequenceActionResult SetPcPageChangeCompleteOn(SequenceContext context, string id, SequenceActionResult param) { short pageNo = _PLC.ReadWord(eWordInput.PLC_PAGE_NO).data; ChangeRecipes(pageNo); _PLC.WriteBit(eBitOutput.PC_PAGE_CHANGE_COMPLETE, true); Log.I(string.Format("Set PC Page Change Complete On")); return SequenceAction.Ok(); } private SequenceActionResult GetPlcPageReqOff(SequenceContext context, string id, SequenceActionResult param) { // Retry에 대해서 어떤 부분이 좋을지 고민됨.. while(!context.Stopped) or RetryUntilSuccess Func plcResponse = () => !_PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data; var res = context.RetryUntilSuccess(plcResponse, timeoutSeconds * 1000); if (res == E2.TIMEOUT) { Log.FuncE("Get PLC Page Change Request Off Timeout !"); return null; } else { Log.I(string.Format("Get PLC Page Change Request Off")); } return SequenceAction.Ok(); } private SequenceActionResult SetPcPageChangeCompleteOff(SequenceContext context, string id, SequenceActionResult param) { _PLC.WriteBit(eBitOutput.PC_PAGE_CHANGE_COMPLETE, false); Log.I(string.Format("Set PC Page Change Complete Off")); return SequenceAction.Ok(); } private SequenceActionResult SaveResultData(SequenceContext context, string id, SequenceActionResult param) { context.PutValue(ContextKey.KEY_SEQUENCE_RESULT, true); return SequenceAction.Ok(); } private SequenceActionResult Complete(SequenceContext context, string id, SequenceActionResult param) { RestoreDeviceStatus(); context.TryGetValue(ContextKey.KEY_SEQUENCE_RESULT, out bool seqResult); SeqAutoRunPrismatic_OutParam result = new SeqAutoRunPrismatic_OutParam() { Success = seqResult }; if (seqResult == false) { AlarmManager.Alarm(AlarmCode.ALARM_SEQUENCE_AutoRun_ResultFailed); } Status.SetWorkingPosition(eWorkingPosition.DONE); return SequenceAction.Ok(result); } #endregion #region 구동 함수 private bool InitSequenceVariable(SequenceContext context) { // TODO: [장비구현필요] Initialize Variable 추가 return true; } private void InitDev(SequenceContext context) { //Device Init _Scanner = context.GetLaserScanner(); _Laser = context.GetLaser(); _PLC = context.GetPLC() as PLCControllerPTOP; } private bool CheckDeviceReady(SequenceContext context) { List deviceListToCheck = new List() { CommonDeviceIds.Scanner, CommonDeviceIds.Laser }; bool isAllDeviceActivated = true; foreach (string item in deviceListToCheck) { if (!context.Devices[item].IsActivated) { isAllDeviceActivated = isAllDeviceActivated && false; } } return isAllDeviceActivated; } private bool CheckCondition(SequenceContext context) { if (CheckCondition_Interlock()) { if (InitializeDeviceStatus(context)) { return true; } } return false; } private bool CheckCondition_Interlock() { // PLC, Data, IO 등 Interlock checking return true; } private bool InitializeDeviceStatus(SequenceContext context) { return true; } private void FindFirstObjectCenter(out double x, out double y) { // 구현 필요 x = 0; y = 0; } private void ChangeRecipes(short pageNo) { } #endregion private bool RestoreDeviceStatus() { return true; } private void OnForceError(SequenceContext arg1, string arg2) { OnSeqActionStop(); Log.I("SequenceAction Ok : OnForceError"); } private void OnStopped(SequenceContext obj) { OnSeqActionStop(); Log.I("SequenceAction Ok : OnStopped"); } private void OnSeqActionStop() { } private void UpdateProductCount(SequenceContext context) { //SystemParameter의 Today, Total Product Count를 어디선간 Reset을 해줘야 함..추가해주고 주석 제거하자 _TodayProduct = _SystemParameter.TodayProductCount; _TotalProduct = _SystemParameter.TotalProductCount; if (_TodayProduct < uint.MaxValue) { _TodayProduct++; } if (_TotalProduct < uint.MaxValue) { _TotalProduct++; } _SystemParameter.TodayProductCount = _TodayProduct; _SystemParameter.TotalProductCount = _TotalProduct; //Systemparameter Save context.Settings.Save(CommonSettingIds.SystemParameter, _SystemParameter, "SeqAutoRunLHS_New"); } private void UpdateProductInfoForView() { Status.GetProcessingWeldingData().TotalProduct = _TotalProduct; Status.GetProcessingWeldingData().TodayProduct = _TodayProduct; Status.GetProcessingWeldingData().WeldingStartTime = _WeldStartTime; Status.GetProcessingWeldingData().WeldingEndTime = _WeldEndTime; Status.GetProcessingWeldingData().WeldingSpanTimeMilliseconds = _WeldSpanTime.TotalMilliseconds.ToString(); Status.GetProcessingWeldingData().LotId = _LotId; Status.GetProcessingWeldingData().CellId = _CellId; } } }