401 lines
15 KiB
C#
401 lines
15 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Api.Manager;
|
|
using Aurora.View;
|
|
using AuroraLaserScanner;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using ILSOS_PrismaticRD_PTOP.Device;
|
|
using ILSOS_PrismaticRD_PTOP.Recipes;
|
|
using ILSOS_PrismaticRD_PTOP.Sequences;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Input;
|
|
using System.Windows.Threading;
|
|
using VisionCommon;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Alarm;
|
|
using WeldingCommon.Data;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.Popup;
|
|
using WeldingCommon.Sequences;
|
|
using WeldingCommon.Sequences.Main;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using WeldingCommon.Views;
|
|
using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP;
|
|
using static WeldingCommon.Sequences.Main.SeqExecutePlcBitInterface_InitParam;
|
|
using static WeldingCommon.Views.UCCommonAutoRunViewModel;
|
|
|
|
namespace ILSOS_PrismaticRD_PTOP.Views
|
|
{
|
|
public class UCMainAutoRunViewModel : UCCommonAutoRunViewModel
|
|
{
|
|
private readonly Logger Log = new Logger("UCMainAutoRunViewModel");
|
|
|
|
public ICommand CMD_VisibleChanged { get; }
|
|
public ICommand CMD_RunSequenceAutoRun { get; }
|
|
public ICommand CMD_StopSequenceAutoRun { get; }
|
|
public ICommand CMD_Reset { get; } // Totoal Product, Today Product
|
|
|
|
private readonly IRecipeManager _RecipeManager;
|
|
private readonly ISettingEntry _SettingEntry;
|
|
private readonly IAlarmService _AlarmService;
|
|
|
|
private SystemParameter _SystemParameter;
|
|
private readonly Scanner _Scanner;
|
|
private readonly PLCControllerPTOP _Plc;
|
|
|
|
private ISequence _SeqAutoRun; // TestRun으로 우선 확인 후
|
|
|
|
private ISequence _SeqPlcInterface;
|
|
|
|
private ISequence _SeqQTest;
|
|
|
|
// 260605 현장 SeqAutoRunPTOP
|
|
private ISequence _SeqAutoRunPTOP;
|
|
|
|
public bool IsSequenceRunning_AutoRun { get => _IsSequenceRunning_AutoRun; set => SetProperty(ref _IsSequenceRunning_AutoRun, value); }
|
|
private bool _IsSequenceRunning_AutoRun;
|
|
|
|
public bool IsAlarm { get => _IsAlarm; set => SetProperty(ref _IsAlarm, value); }
|
|
private bool _IsAlarm;
|
|
|
|
private DateTime _NowDateTime;
|
|
public DateTime NowDateTime { get => _NowDateTime; set => SetProperty(ref _NowDateTime, value); }
|
|
|
|
public int CurrentPageNum { get => _CurrentPageNum; set => SetProperty(ref _CurrentPageNum, value); }
|
|
private int _CurrentPageNum;
|
|
|
|
public WeldingData CurrentWeldingData { get => Status.GetProcessingWeldingData(); }
|
|
|
|
private readonly DispatcherTimer _MonitorTimer;
|
|
|
|
public UCMainAutoRunViewModel(IAuroraEnvironment aurora, string sequenceId) : base(aurora, sequenceId)
|
|
{
|
|
_RecipeManager = _Aurora.RecipeManager;
|
|
_SettingEntry = _Aurora.SettingEntry;
|
|
_AlarmService = _Aurora.AlarmService;
|
|
|
|
_SystemParameter = _Aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
_Scanner = _Aurora.DeviceManager[CommonDeviceIds.Scanner] as Scanner;
|
|
_Plc = _Aurora.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPTOP;
|
|
|
|
// MainViewModel에서 RunStateChanged를 설정해준다면, ManualView 상태에서도 해당 이벤트가 호출될지.. 호출될 듯 하긴 함.
|
|
_SeqAutoRun = _Aurora.SequenceEntry[SequenceIds.SeqAutoRun];
|
|
_SeqAutoRunPTOP = _Aurora.SequenceEntry[SequenceIds.SeqAutoRunPTOP]; // 260605
|
|
|
|
// Autorun과 Status 변경(Manual, Auto 변경) 시 사용하는 시퀸스ID가 다르도록 설정. 같을 경우, 문제 발생.
|
|
_SeqPlcInterface = _Aurora.SequenceEntry[SequenceIds.SeqExecutePlcBitInterfaceForStatusChange];
|
|
|
|
// Q Test
|
|
_SeqQTest = _Aurora.SequenceEntry[SequenceIds.SeqEventQTest];
|
|
InitVariable();
|
|
|
|
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
|
|
|
|
CMD_RunSequenceAutoRun = new DelegateCommand(OnAutoRunStartRequest); // 260511 이곳 시퀸스
|
|
CMD_StopSequenceAutoRun = new DelegateCommand(OnStopSequenceAutoRun);
|
|
CMD_Reset = new DelegateCommand(PerformCmdReset);
|
|
|
|
_MonitorTimer = new DispatcherTimer();
|
|
_MonitorTimer.Tick += OnMonitoring;
|
|
_MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
|
|
|
|
//이벤트로 AUTORUN 스타트 요청에 대한 메소드 실행 오면 그때 동작함. 시퀸스 돔
|
|
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_START_REQUEST)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(x => OnAutoRunStartRequest());
|
|
|
|
// Stop 요청 시 정지 로직 실행
|
|
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_STOP_REQUEST)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(x => OnStopSequenceAutoRun());
|
|
|
|
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_EQUIPMENT_STATUS_CHANGE)
|
|
.Subscribe(x => IsSequenceRunning_AutoRun = Status.EquipmentStatus == eEqpStatus.Auto);
|
|
|
|
Observable.Merge(
|
|
_Aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_ALARM_SET_ALARM),
|
|
_Aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_ALARM_RESET_ALARM),
|
|
_Aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_ALARM_RESET_ALL_ALARM))
|
|
.Subscribe(x => IsAlarm = AlarmManager.HasAlarmLevelHigh());
|
|
|
|
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_CHANGE_RECIPE_INFO)
|
|
.ObserveOnDispatcher()
|
|
.Select(param => (RecipeInfo)param.Param)
|
|
.Subscribe(OnUpdateCurrentActivatedRecipe);
|
|
|
|
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_UPDATE_PAGENUM)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(x => OnAutoRunUpdatePageNum(x));
|
|
|
|
Status.SetWorkingPosition(eWorkingPosition.NONE);
|
|
}
|
|
|
|
|
|
private void InitVariable()
|
|
{
|
|
NowDateTime = DateTime.Now;
|
|
|
|
if (NowDateTime.Day != _SystemParameter.LastProductTime.Day)
|
|
InitializeTodayCount();
|
|
|
|
CurrentWeldingData.TodayProduct = _SystemParameter.TodayProductCount;
|
|
CurrentWeldingData.TotalProduct = _SystemParameter.TotalProductCount;
|
|
CurrentWeldingData.AutoRunStartTime = default(DateTime);
|
|
CurrentWeldingData.WeldingEndTime = _SystemParameter.LastProductTime;
|
|
CurrentWeldingData.WeldingSpanTimeMilliseconds = "0";
|
|
CurrentWeldingData.LotId = "Default_Lot_Id";
|
|
CurrentWeldingData.CellId = "Default_Cell_Id";
|
|
}
|
|
|
|
private void OnUpdateCurrentActivatedRecipe(RecipeInfo info)
|
|
{
|
|
// Activate Layer 불러오기
|
|
RecipeHelper.OnActiveReloaded();
|
|
|
|
// Page UI 업데이트
|
|
RecipeHelper.UpdateAutorunRecipe();
|
|
}
|
|
|
|
private void OnAutoRunUpdatePageNum(EventMessage x)
|
|
{
|
|
if (x.Param is int pageIdx)
|
|
{
|
|
CurrentPageNum = pageIdx + 1;
|
|
}
|
|
}
|
|
private void VisibleChanged(object obj)
|
|
{
|
|
bool visible = (bool)obj;
|
|
if (visible)
|
|
{
|
|
_MonitorTimer.Start();
|
|
}
|
|
else
|
|
{
|
|
_MonitorTimer.Stop();
|
|
}
|
|
}
|
|
|
|
private void OnMonitoring(object sender, EventArgs e)
|
|
{
|
|
// 켜져있는 상태에서는 24시 넘어갈 때만 초기화
|
|
if (NowDateTime.Day != DateTime.Now.Day)
|
|
InitializeTodayCount();
|
|
|
|
NowDateTime = DateTime.Now;
|
|
}
|
|
|
|
// PLC 비트에 의한 AutoRun 실행의 경우, PLC 인터페이스 이후 AutoRun 필요
|
|
public override async void OnAutoRunStartRequest(object obj = null)
|
|
{
|
|
if (!ApproveAutorunByUserOrAuto()) { return; }
|
|
|
|
base.OnAutoRunStartRequest();
|
|
|
|
#region 팝업 띄우는 창과 함께 Bit false
|
|
bool IsStart = await TimerMessageBox.ShowAsync(Application.Current.MainWindow, "운전 시작", "자동 운전을 시작하시겠습니까?", true, 5000);
|
|
if (!IsStart)
|
|
{
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS, false);
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS_P, false); //양극
|
|
return;
|
|
}
|
|
#endregion
|
|
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS, true); // 음극
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS_P, true); //양극
|
|
|
|
// PLC에선 Auto Req 받으면 바로 살려주도록
|
|
|
|
Status.GetProcessingWeldingData().AutoRunStartTime = DateTime.Now;
|
|
RunSequenceAutoRun();
|
|
}
|
|
|
|
private void RunSequenceAutoRun()
|
|
{
|
|
// 자동으로 Activated Recipe로 변경
|
|
OnUpdateCurrentActivatedRecipe(null);
|
|
|
|
//var param = new SeqAutoRunPrismatic_InitParam()
|
|
//{
|
|
// VisionRecipeNo = 0
|
|
//};
|
|
|
|
var param = new SeqTeachingRun_InitParam()
|
|
{
|
|
IsObjectSelectAll = true,
|
|
|
|
};
|
|
|
|
Status.SetStatus(eEqpStatus.Auto);
|
|
//_SeqAutoRun.Start(param, OnCompleteAutoRun);
|
|
|
|
|
|
// 260605
|
|
_SeqAutoRunPTOP.Start(param, OnCompleteAutoRunPTOP);
|
|
|
|
}
|
|
|
|
private void OnCompleteAutoRun(SequenceActionResult res)
|
|
{
|
|
if (res != null)
|
|
{
|
|
if (res.Param is SeqAutoRunPrismatic_OutParam result && result.Success == true)
|
|
{
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqAutoRunPrismatic"));
|
|
return;
|
|
}
|
|
}
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqAutoRunPrismatic"));
|
|
}
|
|
#region 260605
|
|
private void OnCompleteAutoRunPTOP(SequenceActionResult res)
|
|
{
|
|
if (res != null)
|
|
{
|
|
// OutParam 타입을 SeqAutoRunPTOP_OutParam으로 수정
|
|
if (res.Param is SeqAutoRunPTOP.SeqAutoRunPTOP_OutParam result && result.Success == true)
|
|
{
|
|
MessageUtil.ShowSuccessToast(string.Format("Success SeqAutoRunPTOP"));
|
|
return;
|
|
}
|
|
}
|
|
MessageUtil.ShowWarningToast(string.Format("Fail SeqAutoRunPTOP"));
|
|
}
|
|
#endregion
|
|
|
|
private bool ApproveAutorunByUserOrAuto()
|
|
{
|
|
// [테스트용] 알람/인터락 체크 일시 주석 처리
|
|
/*
|
|
bool boolian = AlarmManager.HasAlarmLevelHigh();
|
|
|
|
if (boolian)
|
|
{
|
|
Log.E($"Clear Heavy Alarms For Welding!");
|
|
MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!"));
|
|
return false;
|
|
}
|
|
|
|
boolian = AlarmManager.IsPlcDoorOpen();
|
|
if (boolian)
|
|
{
|
|
Log.E($"PLC Door Opened!! Can't Weld Now.");
|
|
MessageUtil.ShowWarningToast(string.Format("Close Door ! Clear PLC DoorInterlock!"));
|
|
return false;
|
|
}
|
|
|
|
boolian = AlarmManager.IsPlcEmoAlarm();
|
|
if (boolian)
|
|
{
|
|
Log.E($"PLC EMO Pushed!! Can't Weld Now.");
|
|
MessageUtil.ShowWarningToast(string.Format("Clear PLC EMO Status!"));
|
|
return false;
|
|
}
|
|
|
|
if (VisionRecipeManager.GetFovInfos().Count == 0)
|
|
{
|
|
MessageUtil.ShowWarningToast(string.Format("Please check the Vision Recipe of the currently active Recipe."));
|
|
return false;
|
|
}
|
|
*/
|
|
|
|
|
|
if (_SeqAutoRunPTOP.RunState == SequenceRunState.Running)
|
|
{
|
|
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqAutoRunPTOP"), Log);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public override void OnAutoRunStopRequest()
|
|
{
|
|
base.OnAutoRunStopRequest();
|
|
//// Prewelding은 자동 운전 정지 와도 무시
|
|
//StopSequenceAutoRun();
|
|
}
|
|
|
|
private void OnStopSequenceAutoRun(object obj = null)
|
|
{
|
|
//if (_SeqAutoRun.RunState == SequenceRunState.Running)
|
|
// _SeqAutoRun.Stop();
|
|
|
|
|
|
|
|
|
|
if (_SeqAutoRunPTOP.RunState == SequenceRunState.Running)
|
|
_SeqAutoRunPTOP.Stop();
|
|
|
|
Status.SetStatus(eEqpStatus.Manual);
|
|
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS, false);
|
|
_Plc.WriteBit(eBitOutput.PC_AUTO_STATUS_P, false);
|
|
|
|
//Recipe를 기존에 선택된 Recipe로 Rollback 해 줌
|
|
RecipeHelper.RollbackRecipe();
|
|
//AutoRun 정지 시 CorrectionFile을 Vision으로 변경
|
|
_Scanner.SelectCorrectionTable(1);
|
|
|
|
Log.I("Stop AutoRun Requested and Cleaned up.");
|
|
}
|
|
|
|
private void PerformCmdReset(object commandParameter)
|
|
{
|
|
// SystemParameter를 저장하기 전에는 반드시 업데이트를 해주어야 한다.
|
|
_SystemParameter = _Aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
|
|
switch ((string)commandParameter)
|
|
{
|
|
case "TotalProduct":
|
|
{
|
|
CurrentWeldingData.TotalProduct = 0;
|
|
_SystemParameter.TotalProductCount = CurrentWeldingData.TotalProduct;
|
|
Status.GetProcessingWeldingData().TotalProduct = 0;
|
|
|
|
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParameter, "UCMainAutoRunViewModel");
|
|
}
|
|
break;
|
|
|
|
case "TodayProduct":
|
|
{
|
|
CurrentWeldingData.TodayProduct = 0;
|
|
_SystemParameter.TodayProductCount = CurrentWeldingData.TodayProduct;
|
|
Status.GetProcessingWeldingData().TodayProduct = 0;
|
|
|
|
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParameter, "UCMainAutoRunViewModel");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void InitializeTodayCount()
|
|
{
|
|
// SystemParameter를 저장하기 전에는 반드시 업데이트를 해주어야 한다.
|
|
// SystemParameter에 저장된 값 불러오기
|
|
_SystemParameter = _Aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
|
|
CurrentWeldingData.TodayProduct = 0;
|
|
_SystemParameter.TodayProductCount = CurrentWeldingData.TodayProduct;
|
|
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParameter, "UCMainAutoRunViewModel");
|
|
}
|
|
}
|
|
|
|
enum InputType
|
|
{
|
|
keyboardInput,
|
|
ClickInput
|
|
}
|
|
}
|