332 lines
12 KiB
C#
332 lines
12 KiB
C#
using Aurora;
|
|
using Aurora.Api;
|
|
using Aurora.Util.HislogPlus;
|
|
using Aurora.View;
|
|
using AuroraLaser;
|
|
using DB;
|
|
using Hermes.Functional;
|
|
using ILSOS_PrismaticGun.Alarm;
|
|
using ILSOS_PrismaticGun.Device;
|
|
using ILSOS_PrismaticGun.Device.ACS;
|
|
using ILSOS_PrismaticGun.Process;
|
|
using ILSOS_PrismaticGun.Process.Services.History;
|
|
using ILSOS_PrismaticGun.Sequences.SubSequence.PLCInterface;
|
|
using ILSOS_PrismaticGun.Tools;
|
|
using ILSOS_PrismaticGun.WeldingCanvas;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
using System.Dynamic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reactive.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Documents;
|
|
using WeldingCommon;
|
|
using WeldingCommon.Devices;
|
|
using WeldingCommon.Popup;
|
|
using WeldingCommon.Sequences.Main;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
using static ILSOS_PrismaticGun.Device.PLCControllerPrismaticGun;
|
|
|
|
namespace ILSOS_PrismaticGun
|
|
{
|
|
public class ProcessManager
|
|
{
|
|
private static ProcessManager _Instance;
|
|
public static ProcessManager Instance {
|
|
get {
|
|
if (_Instance is null) {
|
|
_Instance = new ProcessManager();
|
|
}
|
|
return _Instance;
|
|
}
|
|
}
|
|
|
|
private static DualLogger _Log = new DualLogger();
|
|
|
|
private IAuroraEnvironment _env;
|
|
private PLCControllerPrismaticGun _plc;
|
|
private Laser _laser;
|
|
public PalletInfo PalletInStageA { get; set; }
|
|
public PalletInfo PalletInStageB { get; set; }
|
|
|
|
public IHistoryReader<WeldingDataForPrismaticGun> HistoryReader { get; private set; }
|
|
private IHistoryWriter<WeldingDataForPrismaticGun> _historyWriter;
|
|
|
|
private static CsvLogger CsvLogStageA;
|
|
private static CsvLogger CsvLogStageB;
|
|
|
|
private object _lock = new object();
|
|
public bool StopRequest {
|
|
get {
|
|
lock(_lock)
|
|
return _StopRequest;
|
|
}
|
|
private set {
|
|
lock(_lock)
|
|
_StopRequest = value;
|
|
}
|
|
}
|
|
private bool _StopRequest;
|
|
public ProcessManager()
|
|
{
|
|
_Log.AddLogger("ProcessManager", "StageA");
|
|
_Log.AddLogger("ProcessManager", "StageB");
|
|
}
|
|
|
|
public void Init(IAuroraEnvironment env)
|
|
{
|
|
_env = env;
|
|
_plc = env.DeviceManager[CommonDeviceIds.PLCDevice] as PLCControllerPrismaticGun;
|
|
_laser = env.DeviceManager[CommonDeviceIds.Laser] as Laser;
|
|
|
|
env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_START_REQUEST)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(x => {
|
|
AutoRunStart();
|
|
_Log.W("PLC Request Auto Run");
|
|
|
|
});
|
|
|
|
// PLC Stop - 상태감시 필요 (Cycle Stop)
|
|
env.EventObservable.AsObservable(CommonEventIds.EVENT_AUTO_RUN_STOP_REQUEST)
|
|
.ObserveOnDispatcher()
|
|
.Subscribe(x => {
|
|
_Log.E("PLC Request Auto Run Cycle Stop!!!!");
|
|
CycleStop();
|
|
});
|
|
|
|
// Cell History
|
|
var historyServ = new CellHistoryService<WeldingDataForPrismaticGun>(maxCount: 50, pumpMs: 100);
|
|
_historyWriter = historyServ as IHistoryWriter<WeldingDataForPrismaticGun>;
|
|
HistoryReader = historyServ as IHistoryReader<WeldingDataForPrismaticGun>;
|
|
|
|
var setting = _env.SettingEntry[CommonSettingIds.SystemParameter] as SystemParameter;
|
|
CsvLogStageA = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageA"), "StageA_CellInfo");
|
|
CsvLogStageB = new CsvLogger(Path.Combine(setting.CellHistoryFolderPath, "StageB"), "StageB_CellInfo");
|
|
|
|
// Pallet Register
|
|
RegistrySerializer.Init();
|
|
LoadRegistryData();
|
|
}
|
|
|
|
private void SaveRegistryData(eStage stage, PalletInfo cell)
|
|
{
|
|
if (cell.WeldingStage is eStage.A)
|
|
RegistrySerializer.SaveToRegistry("PalletInStageA", cell);
|
|
else
|
|
RegistrySerializer.SaveToRegistry("PalletInStageB", cell);
|
|
|
|
Thread.Sleep(50);
|
|
}
|
|
private void LoadRegistryData()
|
|
{
|
|
PalletInStageA = RegistrySerializer.LoadFromRegistry<PalletInfo>("PalletInStageA");
|
|
PalletInStageA.WeldingStage = eStage.A;
|
|
PalletInStageB = RegistrySerializer.LoadFromRegistry<PalletInfo>("PalletInStageB");
|
|
PalletInStageB.WeldingStage = eStage.B;
|
|
}
|
|
|
|
public bool LoadingComplete(PalletInfo cell)
|
|
{
|
|
cell.SetState(ePalletState.LoadingComp);
|
|
|
|
if (Status.EquipmentStatus == eEqpStatus.Auto)
|
|
SaveRegistryData(cell.WeldingStage, cell);
|
|
|
|
_Log.W($"{cell.ToString()} Load Complete", cell.WeldingStage);
|
|
return true;
|
|
}
|
|
public void WeldingStart(PalletInfo cell)
|
|
{
|
|
// 저장은 하지 않는다. 웰딩중에 끊기면 배출함
|
|
cell.SetState(ePalletState.Welding);
|
|
cell.weldingData.WeldingStartTime = DateTime.Now;
|
|
|
|
if (Status.EquipmentStatus == eEqpStatus.Auto)
|
|
SaveRegistryData(cell.WeldingStage, cell);
|
|
|
|
_Log.W($"{cell.ToString()} Welding Start", cell.WeldingStage);
|
|
}
|
|
public bool WeldingComplete(PalletInfo cell)
|
|
{
|
|
// 메뉴얼은 카운팅이 안됨
|
|
if (cell.weldingData.TotalProduct < uint.MaxValue && cell.weldingData.IsLaserOn)
|
|
cell.weldingData.TotalProduct++;
|
|
|
|
if (cell.weldingData.TodayProduct < uint.MaxValue && cell.weldingData.IsLaserOn)
|
|
cell.weldingData.TodayProduct++;
|
|
|
|
cell.SetState(ePalletState.WeldingComp);
|
|
cell.weldingData.WeldingEndTime = DateTime.Now;
|
|
|
|
if (Status.EquipmentStatus == eEqpStatus.Auto)
|
|
SaveRegistryData(cell.WeldingStage, cell);
|
|
|
|
// 히스토리 파일 저장
|
|
if (cell.WeldingStage is eStage.A)
|
|
CsvLogStageA.WriteLineCellData(cell);
|
|
else
|
|
CsvLogStageB.WriteLineCellData(cell);
|
|
|
|
_Log.W($"{cell.ToString()} Welding Complete", cell.WeldingStage);
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool UnloadingComplete(PalletInfo cell)
|
|
{
|
|
cell.SetState(ePalletState.UnloadingComp);
|
|
|
|
if (Status.EquipmentStatus == eEqpStatus.Auto)
|
|
SaveRegistryData(cell.WeldingStage, cell);
|
|
|
|
// 일단 메뉴얼도 히스토리로 남기도록 함
|
|
_historyWriter.Append(cell.WeldingStage, cell.weldingData.Clone() as WeldingDataForPrismaticGun);
|
|
|
|
_Log.W($"{cell.ToString()} Unload Complete", cell.WeldingStage);
|
|
|
|
return true;
|
|
}
|
|
public bool PalletClear(eStage stage)
|
|
{
|
|
if(stage is eStage.A) {
|
|
PalletInStageA.Clear();
|
|
SaveRegistryData(stage, PalletInStageA);
|
|
} else {
|
|
PalletInStageB.Clear();
|
|
SaveRegistryData(stage, PalletInStageB);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#region Welding Enable >> Stage 두개 다 사용못하는 경우 알람 발생을 하기위한 플래그.. 이렇게 하면 복잡한데 일단 필요
|
|
private bool _enableLaserUse = true;
|
|
public bool IsEnableLaserUse()
|
|
{
|
|
lock (_lock) {
|
|
return _enableLaserUse;
|
|
}
|
|
}
|
|
public void EnableLaserUse(bool enable)
|
|
{
|
|
lock (_lock) {
|
|
_enableLaserUse = enable;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Cycle Stop을 하기 위한 동작
|
|
private bool autoStartStageA = false;
|
|
private bool autoStartStageB = false;
|
|
internal void SetAutoPrepare(eStage stage, bool on)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (stage is eStage.A)
|
|
autoStartStageA = on;
|
|
else
|
|
autoStartStageB = on;
|
|
|
|
_Log.I($"Stage {Enum.GetName(typeof(eStage), stage)} [Prepare > {on}]", stage);
|
|
|
|
if (!autoStartStageA && !autoStartStageB)
|
|
{
|
|
_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, false);
|
|
_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, false);
|
|
_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, true);
|
|
Status.SetStatus(eEqpStatus.Manual);
|
|
_laser.LaserOff();
|
|
_Log.W($"Run Stop >> Laser Off && Manual Change");
|
|
}
|
|
}
|
|
}
|
|
|
|
internal bool IsAutoPrepare()
|
|
{
|
|
lock (_lock) {
|
|
if (autoStartStageA && autoStartStageB) {
|
|
_plc.WriteBit(eBitOutput.PC_AUTO_STATUS, true);
|
|
_plc.WriteBit(eBitOutput.PC_AUTO_COMPLETE, true);
|
|
_plc.WriteBit(eBitOutput.PC_MANUAL_COMPLETE, false);
|
|
Status.SetStatus(eEqpStatus.Auto);
|
|
_Log.W($"Run Prepare OK");
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endregion
|
|
|
|
internal void AutoStart(bool on)
|
|
{
|
|
if (on) {
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running)
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop();
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running)
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop();
|
|
|
|
StopRequest = false;
|
|
EnableLaserUse(true);
|
|
_laser.LaserOn();
|
|
_Log.W($"Laser On Start!!!");
|
|
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Start();
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Start();
|
|
_Log.W($"Auto Sequence Start");
|
|
} else {
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running)
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop();
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running)
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop();
|
|
|
|
_laser.LaserOff();
|
|
_Log.W($"Auto Sequence Stop");
|
|
}
|
|
}
|
|
public async void AutoRunStart()
|
|
{
|
|
bool shouldStop = await TimerMessageBox.ShowAsync(Application.Current.MainWindow, "자동 시작", "자동 운전을 시작하시겠습니까?", true, 5000);
|
|
if (!shouldStop)
|
|
return;
|
|
|
|
AutoStart(true);
|
|
}
|
|
internal void CycleStop()
|
|
{
|
|
// 용접중이면, 정지 신호만 주고 정상 시퀀스 종료를 준다
|
|
if (PalletInStageA.palletState == ePalletState.Welding) {
|
|
_Log.E($"{PalletInStageA.ToString()} CycleStop OK!! State is welding", eStage.A);
|
|
StopRequest = true;
|
|
}
|
|
// 용접중이 아니면, 그냥 시퀀스 종료 시킨다.
|
|
else {
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].RunState == SequenceRunState.Running){
|
|
_Log.E($"{PalletInStageA.ToString()} Stop !! not Welding State", eStage.A);
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageA].Stop();
|
|
}
|
|
}
|
|
|
|
// 용접중이면, 정지 신호만 주고 정상 시퀀스 종료를 준다
|
|
if (PalletInStageB.palletState == ePalletState.Welding) {
|
|
_Log.E($"{PalletInStageB.ToString()} CycleStop OK!! State is welding", eStage.B);
|
|
StopRequest = true;
|
|
}
|
|
// 용접중이 아니면, 그냥 시퀀스 종료 시킨다.
|
|
else {
|
|
if (_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].RunState == SequenceRunState.Running){
|
|
_Log.E($"{PalletInStageB.ToString()} Stop !! not Welding State", eStage.B);
|
|
_env.SequenceEntry[SequenceIds.SeqAutoRunPrismaticGunStageB].Stop();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|