Kyungshin-Welder/Machines/ILSOS_KS/Views/Main/UCMainAutoRunViewModel.cs
2026-01-26 14:51:28 +09:00

395 lines
14 KiB
C#

using Aurora;
using Aurora.Api;
using Aurora.Api.Manager;
using Aurora.View;
using AuroraLaserScanner;
using AuroraPLC;
using ILSOS_KS.Device;
using ILSOS_KS.Sequences;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading;
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.Data;
using WeldingCommon.Devices;
using WeldingCommon.Recipes;
using WeldingCommon.Sequences;
using WeldingCommon.Settings;
using WeldingCommon.Views;
using static ILSOS_KS.Device.PLCControllerKS;
using static WeldingCommon.Views.UCCommonAutoRunViewModel;
namespace ILSOS_KS.Views
{
public class UCMainAutoRunViewModel : NotifyPropertyChangedBase
{
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 IAuroraEnvironment _Aurora;
private readonly IRecipeManager _RecipeManager;
private readonly ISettingEntry _SettingEntry;
private readonly IAlarmService _AlarmService;
private readonly SystemParameter _SystemParameter;
private readonly Scanner _Scanner;
private readonly PLCControllerKS _Plc;
private ISequence _SeqAutoRun;
private bool _IsSequenceRunning_AutoRun;
public bool IsSequenceRunning_AutoRun { get => _IsSequenceRunning_AutoRun; set => SetProperty(ref _IsSequenceRunning_AutoRun, value); }
public ICommand CMD_RunSequenceDryRun { get; }
public ICommand CMD_StopSequenceDryRun { get; }
private ISequence _SeqDryRun;
private bool _IsSequenceRunning_DryRun;
public bool IsSequenceRunning_DryRun { get => _IsSequenceRunning_DryRun; set => SetProperty(ref _IsSequenceRunning_DryRun, value); }
private bool _IsAlarm;
public bool IsAlarm { get => _IsAlarm; set => SetProperty(ref _IsAlarm, value); }
private DateTime _NowDateTime;
public DateTime NowDateTime { get => _NowDateTime; set => SetProperty(ref _NowDateTime, value); }
public WeldingData CurrentWeldingData { get => Status.GetProcessingWeldingData(); }
public UCCommonAutoRunViewModel CommonAutoRunViewModel { get; }
private readonly UserControl _UCRecipe;
private readonly DispatcherTimer _MonitorTimer;
public UCMainAutoRunViewModel(IAuroraEnvironment aurora, UserControl recipe, string sequenceId, ExternalRecipeUpdate externalRecipeUpdate)
{
_Aurora = aurora;
_RecipeManager = _Aurora.RecipeManager;
_SettingEntry = _Aurora.SettingEntry;
_AlarmService = _Aurora.AlarmService;
CommonAutoRunViewModel = new UCCommonAutoRunViewModel(_Aurora, sequenceId, externalRecipeUpdate);
_UCRecipe = recipe;
_SystemParameter = aurora.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
_Scanner = _Aurora.DeviceManager[CommonDeviceIds.Scanner] as Scanner;
_Plc = _Aurora.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerKS;
_SeqAutoRun = _Aurora.SequenceEntry[SequenceIds.SeqAutoRunKS_New];
_SeqAutoRun.RunStateChanged += AutoRunSeq_RunStateChanged;
_SeqDryRun = _Aurora.SequenceEntry[SequenceIds.SeqDryRun];
InitVariable();
CMD_VisibleChanged = new DelegateCommand(VisibleChanged);
CMD_RunSequenceAutoRun = new DelegateCommand(PerformCmdRunSequenceAutoRun);
CMD_StopSequenceAutoRun = new DelegateCommand(PerformCmdStopSequenceAutoRun);
CMD_Reset = new DelegateCommand(PerformCmdReset);
CMD_RunSequenceDryRun = new DelegateCommand(PerformCmdRunSequenceDryRun);
CMD_StopSequenceDryRun = new DelegateCommand(PerformCmdStopSequenceDryRun);
_MonitorTimer = new DispatcherTimer();
_MonitorTimer.Tick += OnMonitoring;
_MonitorTimer.Interval = TimeSpan.FromMilliseconds(100);
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_SEQ_AUTO_RUN_START)
.ObserveOnDispatcher()
.Subscribe(x => OnAutoRunStartRequest());
_Aurora.EventObservable.AsObservable(CommonEventIds.EVENT_SEQ_AUTO_RUN_STOP)
.ObserveOnDispatcher()
.Subscribe(x => OnAutoRunStopRequest());
_Aurora.EventObservable.AsObservable("Autorun_Recipe_Change")
.Select(x => ((int, string))x.Param) // (int, string)
.ObserveOnDispatcher()
.Subscribe(x => OnAutorunRecipeChange(x.Item1, x.Item2));
}
#region 경신 추가
private void PerformCmdStopSequenceDryRun(object obj)
{
if (_SeqDryRun.RunState == SequenceRunState.Idle)
{
return;
}
IsSequenceRunning_DryRun = false;
_SeqDryRun.Stop();
}
private void OnCompleteDryRun(SequenceActionResult res)
{
if (res != null)
{
if (res.Param is SeqRCCTeachingRun_OutParam result && result.Success == true)
{
IsSequenceRunning_DryRun = false;
MessageUtil.ShowSuccessToast(string.Format("Success SeqDryRun"));
return;
}
}
IsSequenceRunning_DryRun = false;
MessageUtil.ShowWarningToast(string.Format("Fail SeqDryRun"));
}
private void PerformCmdRunSequenceDryRun(object obj)
{
var result = MessageUtil.ShowYesNoMessageDialog("DryRun Sequence", "Start AutoRun Sequence?");
if (result == false)
{
return;
}
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
var param = new SeqManualRunRCC_InitParam()
{
ScoutSeqParams = scoutSeqParams,
};
//_SequenceDialog.Show();
IsSequenceRunning_DryRun = true;
_SeqDryRun.Start(param, OnCompleteDryRun);
}
private void OnAutorunRecipeChange(int recipeRequestId, string recipeName)
{
if (recipeName != null)
{
_RecipeManager.SaveLock(CommonRecipeIds.ScannerObjectTeaching, false);
_UCRecipe.IsEnabled = false;
WeldingRecipeManager.OnActiveRecipe(recipeRequestId, recipeName);
WeldingRecipeManager.OnActiveReloaded();
CommonAutoRunViewModel.OnAutorunRecipeChange();
}
}
#endregion
private void InitVariable()
{
IsSequenceRunning_AutoRun = false;
IsAlarm = false;
NowDateTime = DateTime.Now;
CurrentWeldingData.TotalProduct = _SystemParameter.TotalProductCount;
CurrentWeldingData.TodayProduct = _SystemParameter.TodayProductCount;
CurrentWeldingData.AutoRunStartTime = default(DateTime);
CurrentWeldingData.WeldingEndTime = default(DateTime);
CurrentWeldingData.WeldingSpanTimeMilliseconds = "0";
CurrentWeldingData.LotId = "Default_Lot_Id";
CurrentWeldingData.CellId = "Default_Cell_Id";
}
private void VisibleChanged(object obj)
{
bool visible = (bool)obj;
if (visible)
{
_MonitorTimer.Start();
}
else
{
_MonitorTimer.Stop();
}
}
private void OnMonitoring(object sender, EventArgs e)
{
NowDateTime = DateTime.Now;
// Sequence Status check
if (_SeqAutoRun.RunState != SequenceRunState.Idle)
{
IsSequenceRunning_AutoRun = true;
}
else
{
IsSequenceRunning_AutoRun = false;
}
// Alarm Status check
List<int> currentAlarmCode = _AlarmService.GetCurrentAlarmCodes();
if (currentAlarmCode.Count != 0)
{
IsAlarm = true;
}
else
{
IsAlarm = false;
}
}
private void PerformCmdRunSequenceAutoRun(object obj)
{
var result = MessageUtil.ShowYesNoMessageDialog("AutoRun Sequence", "Start AutoRun 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 (_SeqAutoRun.RunState == SequenceRunState.Running)
{
MessageUtil.ShowWarningToast(string.Format("이미 시퀀스가 Start 상태입니다.", "SeqAutoRunKS"));
return;
}
RunSequenceAutoRun();
}
private void OnAutoRunStartRequest()
{
RunSequenceAutoRun();
}
private void RunSequenceAutoRun()
{
var scoutSeqParams = new ScoutSeqParams(VisionRecipeManager.GetFovInfos()[0], eDisplayType.Machine_B);
var param = new SeqAutoRunKS_New_InitParam()
{
ScoutSeqParams = scoutSeqParams,
};
//_SequenceDialog.Show();
IsSequenceRunning_AutoRun = true;
_SeqAutoRun.Start(param, OnCompleteAutoRun);
_Plc.WriteBit(_Plc.AutoCompleteAddr, true);
}
private void OnCompleteAutoRun(SequenceActionResult res)
{
if (res != null)
{
if (res.Param is SeqAutoRunKS_New_OutParam result && result.Success == true)
{
IsSequenceRunning_AutoRun = false;
MessageUtil.ShowSuccessToast(string.Format("Success SeqAutoRunKS"));
return;
}
}
IsSequenceRunning_AutoRun = false;
MessageUtil.ShowWarningToast(string.Format("Fail SeqAutoRunKS"));
}
private void PerformCmdStopSequenceAutoRun(object obj)
{
StopSequenceAutoRun();
}
private void OnAutoRunStopRequest()
{
StopSequenceAutoRun();
}
private void StopSequenceAutoRun()
{
if (_SeqAutoRun.RunState == SequenceRunState.Idle)
{
return;
}
IsSequenceRunning_AutoRun = false;
_SeqAutoRun.Stop();
_Plc.WriteBit(_Plc.ManualCompleteAddr, true);
//Recipe를 기존에 선택된 Recipe로 Rollback 해 줌
WeldingRecipeManager.RollbackRecipe();
//AutoRun 정지 시 CorrectionFile을 Vision으로 변경
_Scanner.SelectCorrectionTable(1);
}
private string GetPLC_WordDataToString(short[] rawData)
{
byte[] bytes = new byte[rawData.Length * 2];
for (int i = 0; i < rawData.Length; i++)
{
bytes[i * 2] = (byte)(rawData[i] & 0xFF); // 하위 바이트
bytes[i * 2 + 1] = (byte)((rawData[i] >> 8) & 0xFF); // 상위 바이트
}
string result = Encoding.ASCII.GetString(bytes);
return result;
}
private void PerformCmdReset(object commandParameter)
{
switch ((string)commandParameter)
{
case "TotalProduct":
{
CurrentWeldingData.TotalProduct = 0;
_SystemParameter.TotalProductCount = CurrentWeldingData.TotalProduct;
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParameter, "UCMainAutoRunViewModel");
}
break;
case "TodayProduct":
{
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
CurrentWeldingData.TodayProduct = 0;
_SystemParameter.TodayProductCount = CurrentWeldingData.TodayProduct;
_SystemParameter.CurrentDate = currentDate;
_SettingEntry.Save(CommonSettingIds.SystemParameter, _SystemParameter, "UCMainAutoRunViewModel");
}
break;
default:
return;
}
}
private void AutoRunSeq_RunStateChanged(object sender, (string sequenceId, SequenceRunState state) e)
{
//AutoRun 상황에서 Recipe Save Lock
_RecipeManager.SaveLock(
CommonRecipeIds.ScannerObjectTeaching,
e.state != SequenceRunState.Idle);
//AutoRun 상황에서 Reicpe 화면 수정할 수 없도록 함
if (e.state == SequenceRunState.Running)
{
Application.Current.Dispatcher.InvokeAsync(() => {
_UCRecipe.IsEnabled = false;
});
}
else
{
Application.Current.Dispatcher.InvokeAsync(() => {
_UCRecipe.IsEnabled = true;
});
}
}
}
}