using Aurora; using Aurora.Api; using Aurora.View; // 26.04.09 NDY [Stage X Jog] using 추가 using AuroraACS; using AuroraIO; using AuroraLaser; using AuroraLaserScanner; using AuroraMotor; using CoreUnit.Control.UserControl.Canvas; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reactive.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; using System.Windows.Threading; using VisionCommon; using WeldingCommon.Devices.ACS; using WeldingCommon.Models; using WeldingCommon.Sequences; using WeldingCommon.Settings; using WeldingCommon.Utils; using static AuroraLaser.Ekspla.NL202; using JogDirection = AuroraACS.JogDirection; using Speed = AuroraACS.Speed; namespace WeldingCommon.Views { public class UCScannerObjectTeachingControlBoxViewModel : NotifyPropertyChangedBase { private readonly Logger Log = new Logger("UCScannerObjectTeachingControlBoxViewModel"); #region // 26.04.09 NDY [Stage X Jog] 필드 추가 private ACSMotor _MotorX; // 26.04.09 NDY [Stage X Jog] 프로퍼티 추가 public double StageXJogSpeed { get; set; } = 10.0; public double StageXPos { get => _StageXPos; set => SetProperty(ref _StageXPos, value); } private double _StageXPos; // 26.04.09 NDY [Stage X Jog] 커맨드 선언 추가 public ICommand CMD_StageXJogPlus { get; } public ICommand CMD_StageXJogMinus { get; } public ICommand CMD_StageXJogStop { get; } // 26.04.09 NDY [대면적 MOTF] 토글 프로퍼티 추가 private bool _IsUseLargeMOTF ; public bool IsUseLargeMOTF { get => _IsUseLargeMOTF; set => SetProperty(ref _IsUseLargeMOTF, value); } // 26.04.09 NDY [Stage X Jog] 속도 선택 프로퍼티 기본 속도 M으로 변경 private Speed _StageXJogSpeed = Speed.M; public bool IsJogSpeedL { get => _StageXJogSpeed == Speed.L; } public bool IsJogSpeedM { get => _StageXJogSpeed == Speed.M; } public bool IsJogSpeedH { get => _StageXJogSpeed == Speed.H; } // 26.04.09 NDY [Stage X Jog] null 방어 추가 public double StageXJogSpeedValue { get { if (_MotorX == null || !_MotorX.IsActivated) return 0; return _MotorX.GetJogSpeed(_StageXJogSpeed); } } // 26.04.09 NDY [Stage X Jog] 속도 선택 커맨드 선언 public ICommand CMD_StageXJogSpeed { get; } // // 26.04.09 NDY [대면적 MOTF] 프로퍼티 추가 private int _LargeMOTFPageCount = 1; public int LargeMOTFPageCount { get => _LargeMOTFPageCount; set => SetProperty(ref _LargeMOTFPageCount, value); } private double _LargeMOTFOffsetX = 0.0; public double LargeMOTFOffsetX { get => _LargeMOTFOffsetX; set => SetProperty(ref _LargeMOTFOffsetX, value); } private double _LargeMOTFOffsetY = 0.0; public double LargeMOTFOffsetY { get => _LargeMOTFOffsetY; set => SetProperty(ref _LargeMOTFOffsetY, value); } // 26.04.09 NDY [대면적 MOTF] 커맨드 선언 public ICommand CMD_ApplyPageCount { get; } public ICommand CMD_LargeMOTFStartSet { get; } public ICommand CMD_LargeMOTFEndSet { get; } #endregion public ICommand CMD_VisibleChanged { get; } public ICommand CMD_RunScoutNormal { get; } public ICommand CMD_StopScoutNormal { get; } public ICommand CMD_RunScoutFlyingVision { get; } public ICommand CMD_StopScoutFlyingVision { get; } public ICommand CMD_RunTeachingRun { get; } public ICommand CMD_StopTeachingRun { get; } public ICommand CMD_LaserGuideBeam { get; } public ICommand CMD_LaserReadyCheck { get; } public ICommand CMD_ImportObjectFromDXF { get; } private readonly IAuroraEnvironment _Aurora; private SystemParameter _SystemParameter; //private readonly EquipmentInfo _EquipmentInfo; private readonly Scanner _Scanner; private readonly Laser _Laser; private readonly IODevice _IODevice; private readonly LaserConfig _LaserConfig; private ISequence _SeqScoutNormal; private bool _IsSequenceRunning_ScoutNormal; public bool IsSequenceRunning_ScoutNormal { get => _IsSequenceRunning_ScoutNormal; set => SetProperty(ref _IsSequenceRunning_ScoutNormal, value); } private ISequence _SeqScoutFlyingVision; private bool _IsSequenceRunning_ScoutFlyingVision; public bool IsSequenceRunning_ScoutFlyingVision { get => _IsSequenceRunning_ScoutFlyingVision; set => SetProperty(ref _IsSequenceRunning_ScoutFlyingVision, value); } private ISequence _SeqTeachingRun; private bool _IsSequenceRunning_TeachingRun; public bool IsSequenceRunning_TeachingRun { get => _IsSequenceRunning_TeachingRun; set => SetProperty(ref _IsSequenceRunning_TeachingRun, value); } private bool _IsSelectedScoutNormal; public bool IsSelectedScoutNormal { get => _IsSelectedScoutNormal; set => SetProperty(ref _IsSelectedScoutNormal, value); } private bool _IsGuidBeam; public bool IsGuidBeam { get => _IsGuidBeam; set => SetProperty(ref _IsGuidBeam, value); } private bool _IsLaserReady; public bool IsLaserReady { get => _IsLaserReady; set => SetProperty(ref _IsLaserReady, value); } // Object Select Type private bool _IsObjectSelectAll; public bool IsObjectSelectAll { get => _IsObjectSelectAll; set => SetProperty(ref _IsObjectSelectAll, value); } private readonly DispatcherTimer _MonitorTimer; private SequenceDialog _SequenceDialog; private WinSequenceDiagram _WinSequenceDiagramScoutNormal; private WinSequenceDiagram _WinSequenceDiagramScoutFlyingVision; private WinSequenceDiagram _WinSequenceDiagramTeachingRun; private WinSequenceDiagram _WinSequenceDiagramComponentTeachingRun; public UCScannerObjectTeachingControlBoxViewModel(IAuroraEnvironment aurora) { _Aurora = aurora; _SystemParameter = aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter; _SeqScoutNormal = _Aurora.SequenceEntry[CommonSequenceIds.SeqScoutNormal]; _SeqScoutFlyingVision = _Aurora.SequenceEntry[CommonSequenceIds.SeqScoutFlyingVision]; _Scanner = _Aurora.DeviceManager[CommonDeviceIds.Scanner] as Scanner; _Laser = _Aurora.DeviceManager[CommonDeviceIds.Laser] as Laser; _IODevice = _Aurora.DeviceManager[CommonDeviceIds.IODevice] as IODevice; // Trumpf 레이저인 경우에는 ComponentTeachingRun 실행 _LaserConfig = _Aurora.DeviceManager.GetDeviceConfig(CommonDeviceIds.Laser) as LaserConfig; _SeqTeachingRun = _Aurora.SequenceEntry[CommonSequenceIds.SeqComponentTeachingRun]; InitVariable(); CMD_VisibleChanged = new DelegateCommand(VisibleChanged); CMD_RunScoutNormal = new DelegateCommand(PerformCmdRunScoutNormal); CMD_StopScoutNormal = new DelegateCommand(PerformCmdStopScoutNormal); CMD_RunScoutFlyingVision = new DelegateCommand(PerformCmdRunScoutFlyingVision); CMD_StopScoutFlyingVision = new DelegateCommand(PerformCmdStopScoutFlyingVision); CMD_RunTeachingRun = new DelegateCommand(PerformCmdRunTeachingRun); CMD_StopTeachingRun = new DelegateCommand(PerformCmdStopTeachingRun); CMD_LaserGuideBeam = new DelegateCommand(PerformCmdLaserGuideBeam); CMD_LaserReadyCheck = new DelegateCommand(PerformCmdLaserReadyCheck); CMD_ImportObjectFromDXF = new DelegateCommand(PerformCmdImportObjectFromDXF); _Aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_SETTING_CHANGED) .ObserveOnDispatcher() .Subscribe(OnSettingReloaded); _MonitorTimer = new DispatcherTimer(); _MonitorTimer.Tick += OnMonitoring; _MonitorTimer.Interval = TimeSpan.FromMilliseconds(100); #region // 26.04.09 NDY [Stage X Jog] 생성자 내부 - 디바이스 취득 및 커맨드 등록 try { _MotorX = _Aurora.DeviceManager[CommonDeviceIds.AxisX2] as ACSMotor; } catch { _MotorX = null; } CMD_StageXJogPlus = new DelegateCommand(PerformCmdStageXJogPlus); CMD_StageXJogMinus = new DelegateCommand(PerformCmdStageXJogMinus); CMD_StageXJogStop = new DelegateCommand(PerformCmdStageXJogStop); // 26.04.09 NDY [Stage X Jog] 속도 선택 커맨드 등록 CMD_StageXJogSpeed = new DelegateCommand(GetPerformCmdStageXJogSpeed); // 생성자 커맨드 등록 CMD_ApplyPageCount = new DelegateCommand(PerformCmdApplyPageCount); CMD_LargeMOTFStartSet = new DelegateCommand(PerformCmdLargeMOTFStartSet); CMD_LargeMOTFEndSet = new DelegateCommand(PerformCmdLargeMOTFEndSet); #endregion } #region 26.04.09 NDY [Stage X Jog] // 26.04.09 NDY [대면적 MOTF] 커맨드 구현 // 26.04.09 NDY [대면적 MOTF] 페이지 N개 적용 커맨드 구현 private void PerformCmdApplyPageCount(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("페이지 설정", $"페이지를 {LargeMOTFPageCount}개로 설정하시겠습니까?\n기존 페이지는 유지되고 부족한 페이지만 추가됩니다."); if (result == false) return; var mainPage = CommonHelper.GetMainPage(); if (mainPage == null) return; // 현재 페이지 수 확인 후 부족한 만큼만 추가 int currentPageCount = mainPage.ScannerCanvasCtrlTeaching.Model.Layers.Count(); int needCount = LargeMOTFPageCount - currentPageCount; for (int i = 0; i < needCount; i++) { mainPage.ScannerCanvasCtrlTeaching.Model.CreateLayer(); } mainPage.UpdateLayersInfo(); Log.I($"[대면적 MOTF] 페이지 {LargeMOTFPageCount}개 설정 완료 (추가: {Math.Max(0, needCount)}개)"); } // 26.04.09 NDY [대면적 MOTF] Start Set 시점 모터 위치 저장용 private double _startSetPositionX = 0.0; private double _startSetPositionY = 0.0; private double _startMotorPos = 0.0; // 26.04.09 NDY [대면적 MOTF] Start Set 커맨드 구현 private void PerformCmdLargeMOTFStartSet(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("Large MOTF Start Set", "현재 DrawObject EndPosition을 Start 기준으로 저장하시겠습니까?"); if (result == false) return; // 26.04.09 NDY - 모터 위치는 DrawObject 유무와 무관하게 무조건 저장 _startMotorPos = _MotorX?.GetActualPos() ?? 0.0; Log.I($"[대면적 MOTF] Start Set 완료"); Log.I($" - Stage X 현재 위치 (Motor): {_startMotorPos:F3} mm"); var mainPage = CommonHelper.GetMainPage(); if (mainPage == null) return; var activeLayer = mainPage.ScannerCanvasCtrlTeaching.Model.ActiveLayer as DrawingLayer; var objects = activeLayer?.Objects; if (objects == null || objects.Count == 0) { Log.I($" - DrawObject 없음 (Scanner 기준위치 저장 생략)"); return; } var lastObj = objects.LastOrDefault() as Line; if (lastObj == null) { Log.I($" - 마지막 객체가 Line 타입 아님: {objects.LastOrDefault()?.GetType().Name}"); return; } _startSetPositionX = lastObj.P2.X; _startSetPositionY = lastObj.P2.Y; Log.I($" - DrawObject EndPosition (Scanner): X={_startSetPositionX:F3}, Y={_startSetPositionY:F3}"); } // 26.04.09 NDY [대면적 MOTF] End Set 커맨드 구현 //최종 구현하고자 하는 방향성 //{ // 1. Layer[0] (P1), Layer[1] (P2) 원본 확인 // 2. Layer[2] 생성 = P3(P2 Y플립) // - 플립 기준Y = Layer[1] 마지막 Line PF2.Y // - P2의 Line들을 역순으로 복사 + Y좌표 플립 // 3. Layer[3] 생성 = P4(P1 Y플립) // - 플립 기준Y = Layer[0] 첫 Line PF1.Y // - P1의 Line들을 역순으로 복사 + Y좌표 플립 // 4. 기존 Layer[2],[3] 있으면 삭제 후 재생성 // 5. MessageUtil로 결과 안내 //} private void PerformCmdLargeMOTFEndSet(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("Large MOTF End Set", "현재 Stage X 위치를 End 기준으로 저장하고 Offset을 계산하시겠습니까?"); if (result == false) return; var mainPage = CommonHelper.GetMainPage(); if (mainPage == null) return; // 현재 모터 이동량 → Scanner 좌표계 변환 (방향은 TODO: 이정인 선임 확인 필요) double motorPos = _MotorX?.GetActualPos() ?? 0.0; double motorDelta = motorPos - _startMotorPos; // Start Set 시점의 모터 위치 필요 // TODO: 모션 좌표 → 스캐너 필드 좌표 변환 계수 적용 LargeMOTFOffsetX = motorDelta; // 임시: 1:1 적용, 방향/스케일 확인 후 수정 LargeMOTFOffsetY = 0.0; // 현재 Active Layer에 저장 var activeLayer = mainPage.ScannerCanvasCtrlTeaching.Model.ActiveLayer as DrawingLayer; if (activeLayer != null) { activeLayer.LargeMOTFOffsetX = LargeMOTFOffsetX; activeLayer.LargeMOTFOffsetY = LargeMOTFOffsetY; } Log.I($"[대면적 MOTF] End Set: OffsetX={LargeMOTFOffsetX:F3}, OffsetY={LargeMOTFOffsetY:F3}"); Log.I($"[대면적 MOTF] End Set 완료"); Log.I($" - Stage X 이동량 (Motor Delta): {motorDelta:F3} mm"); Log.I($" - 계산된 Offset X (Scanner): {LargeMOTFOffsetX:F3} mm"); Log.I($" - 계산된 Offset Y (Scanner): {LargeMOTFOffsetY:F3} mm"); Log.I($" - 저장된 Layer: Page {mainPage.ScannerCanvasCtrlTeaching.Model.ActiveLayer.No + 1}"); Log.I($" - TODO: 모션→스캐너 좌표 변환 방향/스케일 이정인 선임 확인 필요"); // 26.04.10 NDY [대면적 MOTF] 플립 페이지 자동 생성 CommonHelper.GetMainPage().GenerateFlippedPages(LargeMOTFOffsetX); } private void GetPerformCmdStageXJogSpeed(object obj) { switch ((string)obj) { case "L": _StageXJogSpeed = Speed.L; break; case "M": _StageXJogSpeed = Speed.M; break; case "H": _StageXJogSpeed = Speed.H; break; } NotifyPropertyChanged(nameof(IsJogSpeedL)); NotifyPropertyChanged(nameof(IsJogSpeedM)); NotifyPropertyChanged(nameof(IsJogSpeedH)); NotifyPropertyChanged(nameof(StageXJogSpeedValue)); } // 26.04.09 NDY [Stage X Jog] 커맨드 구현 추가 private void PerformCmdStageXJogPlus(object obj) { _MotorX?.MoveToSWLimit(JogDirection.plus, _StageXJogSpeed); } private void PerformCmdStageXJogMinus(object obj) { _MotorX?.MoveToSWLimit(JogDirection.minus, _StageXJogSpeed); } private void PerformCmdStageXJogStop(object obj) { _MotorX?.Stop(); } #endregion private void InitVariable() { if (_SystemParameter.ScoutType == eScoutType.Normal) { IsSelectedScoutNormal = true; } else { IsSelectedScoutNormal = false; } IsSequenceRunning_ScoutNormal = false; IsSequenceRunning_ScoutFlyingVision = false; IsSequenceRunning_TeachingRun = false; IsGuidBeam = false; IsLaserReady = false; IsObjectSelectAll = true; } private void VisibleChanged(object obj) { bool visible = (bool)obj; if (visible) { _MonitorTimer.Start(); } else { _MonitorTimer.Stop(); } } private void OnSettingReloaded(object obj) { _SystemParameter = _Aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter; if (_SystemParameter.ScoutType == eScoutType.Normal) { IsSelectedScoutNormal = true; } else { IsSelectedScoutNormal = false; } } private void OnMonitoring(object sender, EventArgs e) { // TODO: Laser Device 에 구현된 내용에 따르면, 일부 Laser Device 는 구현이 되어 있지 않은 상태. 항상 false //if (_Laser.GetPilotLaserStatus()) { // IsGuidBeam = true; //} else { // IsGuidBeam = false; //} //if (_Laser.GetLaserReady()) { // IsLaserReady = true; // // TODO: PRIBAT_L1, PRIBAT_L2 는 IO에 LaserOnLamp 를 켜고 끄는게 필요함. // // TODO: 우선 주석 처리 해 둠. 레이저 Type 별로 달라서 그런건지 확인하고, 어떻게 공통으로 구현할지를 생각해서 추가해 두자 // //_iODevice._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), true); //} else { // IsLaserReady = false; // // TODO: PRIBAT_L1, PRIBAT_L2 는 IO에 LaserOnLamp 를 켜고 끄는게 필요함. // // TODO: 우선 주석 처리 해 둠. 레이저 Type 별로 달라서 그런건지 확인하고, 어떻게 공통으로 구현할지를 생각해서 추가해 두자 // //_iODevice._iOUnit.WriteDoBit(Convert.ToInt32(ePDOAddress.LaserOnLampOn), true); //} // TODO: PRIBAT_L1, PRIBAT_L2 는 Blow 의 상태 check 가 들어 있음. 장비 한정이므로 이를 check 하는 것을 modelItem 이나 setting 으로 빼서 진행되도록 함. #region // 26.04.09 NDY [Stage X Jog] OnMonitoring 내부 - X축 위치 갱신 if (_MotorX != null && _MotorX.IsActivated) { StageXPos = _MotorX.GetActualPos(); } #endregion } private void PerformCmdRunScoutNormal(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("Scanner Scout", "Start Scanner Scout Normal Sequence?"); if (result == false) { return; } if (VisionRecipeManager.GetFovInfos().Count == 0) { MessageUtil.ShowWarningToast(string.Format("Please check the Vision Recipe of the currently active Recipe.")); return; } if (_SeqScoutNormal.RunState == SequenceRunState.Running) { MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqScoutNormal"), Log); return; } var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B); var param = new SeqScoutNormal_InitParam() { IsRealTimeScout = false, ScoutSeqParams = scoutSeqParams, }; PopupSequenceDiagram(ref _WinSequenceDiagramScoutNormal, CommonSequenceIds.SeqScoutNormal, param); IsSequenceRunning_ScoutNormal = true; _SeqScoutNormal.Start(param, OnCompleteScoutNormal); } private void OnCompleteScoutNormal(SequenceActionResult res) { if (res != null) { if (res.Param is SeqScoutNormal_OutParam result && result.Success == true) { IsSequenceRunning_ScoutNormal = false; MessageUtil.ShowSuccessToast(string.Format("Success SeqScoutNormal")); CloseSequenceDiagram(_WinSequenceDiagramScoutNormal); return; } } if (_Laser.GetLaserReady()) { _Laser.LaserOff(); } IsSequenceRunning_ScoutNormal = false; MessageUtil.ShowWarningToast(string.Format("Fail SeqScoutNormal")); } private void PerformCmdStopScoutNormal(object obj) { if (_SeqScoutNormal.RunState == SequenceRunState.Idle) { return; } IsSequenceRunning_ScoutNormal = false; _SeqScoutNormal.Stop(); } private void PerformCmdRunScoutFlyingVision(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("Flying Vision", "Start Scanner Scout Flying Vision Sequence?"); if (result == false) { return; } if (VisionRecipeManager.GetFovInfos().Count == 0) { MessageUtil.ShowWarningToast(string.Format("Please check the Vision Recipe of the currently active Recipe.")); return; } if (_SeqScoutFlyingVision.RunState == SequenceRunState.Running) { MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqScoutFlyingVision"), Log); return; } var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B); var param = new SeqScoutFlyingVision_InitParam() { IsRealTimeScout = false, ScoutSeqParams = scoutSeqParams, SequenceAutoRunCount = 0, WeldingScannerListNo = eListNo.LIST2, }; PopupSequenceDiagram(ref _WinSequenceDiagramScoutFlyingVision, CommonSequenceIds.SeqScoutFlyingVision, param); IsSequenceRunning_ScoutFlyingVision = true; _SeqScoutFlyingVision.Start(param, OnCompleteScoutFlyingVision); } private void OnCompleteScoutFlyingVision(SequenceActionResult res) { if (res != null) { if (res.Param is SeqScoutFlyingVision_OutParam result && result.Success == true) { IsSequenceRunning_ScoutFlyingVision = false; MessageUtil.ShowSuccessToast(string.Format("Success SeqScoutFlyingVision")); CloseSequenceDiagram(_WinSequenceDiagramScoutFlyingVision); return; } } if (_Laser.GetLaserReady()) { _Laser.LaserOff(); } IsSequenceRunning_ScoutFlyingVision = false; MessageUtil.ShowWarningToast(string.Format("Fail SeqScoutFlyingVision")); } private void PerformCmdStopScoutFlyingVision(object obj) { if (_SeqScoutFlyingVision.RunState == SequenceRunState.Idle) { return; } IsSequenceRunning_ScoutFlyingVision = false; _SeqScoutFlyingVision.Stop(); } private void PerformCmdRunTeachingRun(object obj) { var result = MessageUtil.ShowYesNoMessageDialog("Teaching Run", "Start TeachingRun Sequence?"); if (result == false) { return; } if (IsLaserReady == false) { MessageUtil.ShowWarningToast(string.Format("Please check Laser Ready.")); return; } // TODO: PRIBAT_L1, PRIBAT_L2 에서 Suction 과 CLAMP 상태 등에 따라 Laser 가 나가지 않도록 해야 함. // TODO: 이 부분은, Delegate 를 사용해서, Interlock 을 각 장비별로 설정할 수 있도록 해주는게 좋겠음. if (_SeqTeachingRun.RunState == SequenceRunState.Running) { MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqTeachingRun"), Log); return; } // TODO: NeedSetLaserTiming 는 트럼프 레이저 를 사용할 때, UploadWeldingList Sequence 에서 LaserTiming Set 을 해야 할때 사용함. // TODO: SMW 와 LHS 는 트럼프 레이저를 사용하지 않으므로 false, PRIBAT_L1 과 PRIBAT_L2 할때 LaserType 을 읽어서 설정하는 것으로 추가하자 var currentModelInfo = EquipmentSpecificModelUtil.GetCurrentRecipeEquipmentSpecificModel(); if (currentModelInfo.equipmentSpecificModel == null) { MessageUtil.ShowWarningToast(string.Format("선택된 model 이 없습니다.", "SeqTeachingRun")); return; } var intervalTimeBlowOn = 0; var intervalTimeBlowOff = 0; if (currentModelInfo.equipmentSpecificModel.UseBlow) { intervalTimeBlowOn = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOn; intervalTimeBlowOff = currentModelInfo.equipmentSpecificModel.IntervalTimeBlowOff; } var param = new SeqTeachingRun_InitParam() { IsObjectSelectAll = IsObjectSelectAll, //UseStream = _EquipmentInfo.UseStream, UseStream = currentModelInfo.equipmentSpecificModel.UseStream, UseBlow = currentModelInfo.equipmentSpecificModel.UseBlow, IntervalTimeBlowOn = intervalTimeBlowOn, IntervalTimeBlowOff = intervalTimeBlowOff, NeedSetLaserTiming = false, }; PopupSequenceDiagram(ref _WinSequenceDiagramTeachingRun, CommonSequenceIds.SeqComponentTeachingRun, param); IsSequenceRunning_TeachingRun = true; _SeqTeachingRun.Start(param, OnCompleteTeachingRun); } private void OnCompleteTeachingRun(SequenceActionResult res) { if (res != null) { if (res.Param is SeqTeachingRun_OutParam result && result.Success == true) { IsSequenceRunning_TeachingRun = false; MessageUtil.ShowSuccessToast(string.Format("Success SeqTeachingRun")); CloseSequenceDiagram(_WinSequenceDiagramTeachingRun); return; } } if (_Laser.GetLaserReady()) { _Laser.LaserOff(); } IsSequenceRunning_TeachingRun = false; MessageUtil.ShowWarningToast(string.Format("Fail SeqTeachingRun")); } private void PerformCmdStopTeachingRun(object obj) { IsSequenceRunning_TeachingRun = false; if (_SeqTeachingRun.RunState == SequenceRunState.Idle) { return; } _SeqTeachingRun.Stop(); } private void PopupSequenceDiagram(ref WinSequenceDiagram winSequenceDiagram, string seqId, object param) { if (winSequenceDiagram == null) { winSequenceDiagram = new WinSequenceDiagram(seqId); winSequenceDiagram.Closing += ClosingEvent; winSequenceDiagram.SetParam(new SeqDrawerParam() { SequenceId = seqId, DiagramType = eDiagramType.Tree, LineType = eLineType.Straight, IsShowSubSequence = false, VisibleKeys = new List() }); winSequenceDiagram.Owner = Application.Current.MainWindow; winSequenceDiagram.Width = 600; winSequenceDiagram.SequenceParam = param; winSequenceDiagram.Show(); } else { winSequenceDiagram.SequenceParam = param; winSequenceDiagram.WindowState = WindowState.Normal; winSequenceDiagram.Show(); } } private void CloseSequenceDiagram(WinSequenceDiagram winSequenceDiagram) { Application.Current.Dispatcher.Invoke(() => { if (winSequenceDiagram != null) { winSequenceDiagram.Close(); } }); } private void ClosingEvent(object sender, CancelEventArgs e) { e.Cancel = true; (sender as Window).Hide(); } private void PerformCmdLaserGuideBeam(object obj) { if (!_Laser.GetPilotLaserSetBitStatus()) { _Laser.PilotLaserOn(); } else { _Laser.PilotLaserOff(); } } private void PerformCmdLaserReadyCheck(object obj) { if (!_Laser.GetLaserReady()) { _Laser.LaserOn(); //실질적으로 Laser Ready On을 의미함 } else { _Laser.LaserOff(); } } private void PerformCmdImportObjectFromDXF(object obj) { System.Windows.Forms.FileDialog dlg = new System.Windows.Forms.OpenFileDialog(); dlg.InitialDirectory = @"D:\share\jungwoo.jin\모바일글라스도면 외 (3) 파일_20241028"; dlg.DefaultExt = "dxf"; dlg.Filter = "DXF 도면 파일 (*.dxf)|*.dxf"; dlg.Title = "DXF 도면 열기"; if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.OK) { CommonHelper.GetMainPage().DxfParser(dlg.FileName); } } } }