NohDoyeon241104 aa5928ce3e refactor: PTOP 네임스페이스/클래스 정리(Scanner→PTOP) 및 머신 PTOP 단독화
- namespace/using ILSOS_PrismaticScanner → ILSOS_PrismaticRD_PTOP (전 .cs/.xaml)
- 파일/클래스 리네임 7개: AlarmCode/AlarmManager/PAIX/EquipmentSpecificModel→_PTOP,
  RMSHandlerForScanner→ForPTOP, SettingUploadDataListForScanner→ForPTOP,
  SeqAutoRunPrismaticScanner→SeqAutoRunPrismatic, PLCControllerPrismaticScanner→PLCControllerPTOP
- PAIX_PrismaticScanner: 머신 참조만 PAIX_PTOP로 변경, WeldingCommon 공유 참조(SeqTestRun)는 보존
- XAML 3종(x:Class/clr-namespace/code-behind) 일치, csproj Compile Include 갱신
- csproj 빌드 경로 TDC→PTOP(_out_prismatic_rd_ptop)
- sln에서 Scanner/Gun/CleanLaser 제거 및 해당 머신 소스 삭제 → Machines에 PTOP만
- 분석/작업일지 문서 추가 (참고본: 정리후(빌드완) 기준)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 11:28:19 +09:00

504 lines
20 KiB
C#

using Aurora.Api;
using AuroraChiller;
using AuroraIO;
using AuroraLaser;
using AuroraLaser.Trumpf;
using AuroraLaserScanner;
using AuroraLBAD;
using AuroraOCT;
using ILSOS_PrismaticRD_PTOP.Alarm;
using ILSOS_PrismaticRD_PTOP.Device;
using ILSOS_PrismaticRD_PTOP.Device.IO;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using WeldingCommon.Alarm;
using WeldingCommon.Settings;
using static AuroraIO.AJINEXTEK.AjinIO.IOModuleInfo;
using static ILSOS_PrismaticRD_PTOP.Device.IO.PAIX_PTOP;
using static ILSOS_PrismaticRD_PTOP.Device.PLCControllerPTOP;
namespace WeldingCommon.Sequences
{
class SeqAlarmMonitor
{
const string SEQ_START = "SEQ START"; // 딱 한번 Sequence 진입 시에만 실행될 Node
const string SEQ_LoopFirst = "SEQ Loop First";
const string SEQ_WAIT_TIME = "SEQ Wait Time";
//const string SEQ_LoopLast = "SEQ Loop Last";
public const string CHECK_ALARM_PLC = "Check Alarm PLC";
public const string CHECK_ALARM_SCANNER = "Check Alarm Scanner";
public const string CHECK_ALARM_LASER = "Check Alarm Laser";
public const string CHECK_ALARM_LBAD = "Check Alarm LBAD";
public const string CHECK_ALARM_OCT = "Check Alarm OCT";
public const string CHECK_ALARM_CHILLER = "Check Alarm Chiller";
public const string CHECK_ALARM_LEAK_SENSOR = "Check Alarm LeakSensor";
public const string CHECK_ALARM_IO_BOARD = "Check Alarm IOBoard";
private static SequenceSetting _SequenceSetting;
private static PLCControllerPTOP _Plc;
private static Scanner _Scanner;
private static Laser _Laser;
private static LaserTruFiber _LaserTruFiber;
private static PAIX_PTOP _IO;
private static SmcChiller _Chiller;
private static OCT _OCT;
private static LBAD _LBAD;
public const int TIMEOUT_PLC_LIVE_CHECK = 2000; // msec
public SequenceBuilder Builder()
{
SequenceBuilder sb = new SequenceBuilder(1000, true);
sb.AddAction(SEQ_START, StartNode);
sb.AddDecision(SEQ_LoopFirst, LoopFirstNode);
sb.AddAction(SEQ_WAIT_TIME, WaitTime);
sb.AddAction(CHECK_ALARM_PLC, CheckAlarmPLC);
sb.AddAction(CHECK_ALARM_SCANNER, CheckAlarmScanner);
sb.AddAction(CHECK_ALARM_LASER, CheckAlarmLaser);
sb.AddAction(CHECK_ALARM_LBAD, CheckAlarmLBAD);
sb.AddAction(CHECK_ALARM_OCT, CheckAlarmOCT);
sb.AddAction(CHECK_ALARM_CHILLER, CheckAlarmChiller);
sb.AddAction(CHECK_ALARM_LEAK_SENSOR, CheckAlarmLeakSensor);
sb.AddAction(CHECK_ALARM_IO_BOARD, CheckAlarmIOBoard);
//sb.AddAction(SEQ_LoopLast, LoopLastNode);
sb.Flows(sb.Init > sb[SEQ_START] > sb[SEQ_LoopFirst] > sb[SEQ_WAIT_TIME]
> sb[CHECK_ALARM_PLC] > sb[CHECK_ALARM_SCANNER]
> sb[CHECK_ALARM_LASER] > sb[CHECK_ALARM_LBAD]
> sb[CHECK_ALARM_OCT] > sb[CHECK_ALARM_CHILLER] > sb[CHECK_ALARM_LEAK_SENSOR] > sb[CHECK_ALARM_IO_BOARD]
//> sb[SEQ_LoopLast] > sb[SEQ_LoopFirst]);
> sb[SEQ_LoopFirst]);
sb.Flows(sb[SEQ_LoopFirst] > sb.Final);
sb.OnStopped(OnStopped);
sb.OnForceError(OnForceError);
//sb.Draw("AlarmMonitor.pdf");
return sb;
}
private static SequenceActionResult StartNode(SequenceContext context, string id, SequenceActionResult param)
{
_SequenceSetting = context.GetSetting<SequenceSetting>(CommonSettingIds.Sequence);
InitDev(context);
return SequenceAction.Ok();
}
private static void InitDev(SequenceContext context)
{
if (_SequenceSetting.PlcActivated)
_Plc = context.Devices[CommonDeviceIds.PLCDevice] as PLCControllerPTOP;
if (_SequenceSetting.ScannerActivated)
_Scanner = context.GetLaserScanner();
if (_SequenceSetting.LaserActivated) {
_Laser = context.GetLaser();
_LaserTruFiber = _Laser.getCore() as LaserTruFiber;
}
if (_SequenceSetting.LbadActivated)
_LBAD = context.GetLBAD();
if (_SequenceSetting.OctActivated)
_OCT = context.GetOCT();
if (_SequenceSetting.ChillerActivated)
_Chiller = context.GetChiller();
// Scanner, Laser, LBAD, OCT, Chiller, LeakSensor 는 IO 로도 상태 check 할 수 있음.
if (_SequenceSetting.ScannerActivatedWithIO
|| _SequenceSetting.LaserActivatedWithIO
|| _SequenceSetting.LbadActivatedWithIO
|| _SequenceSetting.OctActivatedWithIO
|| _SequenceSetting.ChillerActivatedWithIO
|| _SequenceSetting.LeakSensorActivatedWithIO)
{
_IO = context.GetIOUnit() as PAIX_PTOP;
}
}
private static string LoopFirstNode(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
{
while (!context.Stopped)
{
//_SequenceSetting = context.GetSetting<SequenceSetting>(CommonSettingIds.Sequence);
return SEQ_WAIT_TIME;
}
return SeqNodeIds.FINAL;
}
private static SequenceActionResult WaitTime(SequenceContext context, string id, SequenceActionResult param)
{
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmPLC(SequenceContext context, string id, SequenceActionResult param)
{
if (_Plc == null || _SequenceSetting.PlcActivated == false)
{
return SequenceAction.Ok();
}
if (_Plc.IsSimul)
{
return SequenceAction.Ok();
}
if (!_Plc.IsActivated)
{
// 260512 임시 주석
//AlarmManager.Alarm(AlaramCode_PrismaticScanner.ALARM_DEVICE_PLC_DEACTIVATED);
}
else
{
if (_SequenceSetting.PlcActivatedLive)
{
//PLC Live Check 시간은 확인 필요
Stopwatch sw = Stopwatch.StartNew();
while (!context.Stopped)
{
if (_Plc.ReadBit(eBitInput.PLC_LIVE_STATUS).data)
{
break;
}
if (sw.ElapsedMilliseconds > TIMEOUT_PLC_LIVE_CHECK)
{
//260512 -타임아웃 주석 풀기
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_PLC_DISCONNECT);
break;
}
Thread.Sleep(10);
}
}
// EMO check 는 항상 해야 함.
if (_Plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_EMO_STATUS).data) {
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_PLC_EMO);
_Laser.LaserOff();
}
if (_Plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_LIGHT_ALARM_STATUS).data) {
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_PLC_Light);
}
if (_Plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_HEAVY_ALARM_STATUS).data) {
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_PLC_Heavy);
}
bool boolian = _Plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_DOOR_INTERLOCK).data;
if (boolian) {
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_PLC_DOOR_INTERLOCK);
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmScanner(SequenceContext context, string id, SequenceActionResult param)
{
if (_Scanner == null || _SequenceSetting.ScannerActivated == false)
{
return SequenceAction.Ok();
}
if (_Scanner.IsSimul)
{
return SequenceAction.Ok();
}
if (!_Scanner.IsActivated)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_SCANNER_DEACTIVATED);
}
else
{
var lastErrorcode = _Scanner.GetLastError();
//Scanner의 activate 상태를 체크하면.. 수동상태에서 디바이스를 deactivaed시키면 알람 발생하므로 조건문 변경 필요
if (lastErrorcode != 0)
{
//260512 타임아웃으로 주석 처리 - 해제할 것
//AlarmManager.ChangeAlarmDescription(AlarmCode_PTOP.ALARM_DEVICE_SCANNER_ERROR, $"Scanner Error Code : {lastErrorcode} Check Scanner Error Status");
}
// TODO: Scanner 는 Alarm 과 연결되어 있지 않음. 알람 추가되었을 시에 어떤 IO 를 check 하지??
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmLaser(SequenceContext context, string id, SequenceActionResult param)
{
if (_Laser == null || _SequenceSetting.LaserActivated == false)
{
return SequenceAction.Ok();
}
if (_Laser.IsSimul)
{
return SequenceAction.Ok();
}
if (!_Laser.IsActivated)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_LASER_DEACTIVATED);
}
else
{
if (!_Laser.GetConnected())
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_DISCONNECT);
}
if (_SequenceSetting.LaserActivatedWithIO && CheckDeviceIO())
{
//Laser Disconnect Check 조건문 변경 필요
if (!_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserAssigned)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_DISCONNECT);
}
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserError)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_ERROR);
}
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.Warning)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_WARNING);
}
//Laser EMO IO Map 확인 필요
if (!_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserEMO_1)) || !_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LaserEMO_2)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_EMO);
}
} else {
_LaserTruFiber = _Laser.getCore() as LaserTruFiber;
// Laser OPCUA로 연결한 경우
if (_LaserTruFiber.GetEStopOpen()) {
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LASER_EMO);
}
if (_LaserTruFiber.GetFaultLaser()) {
string alarmCode = $"{Convert.ToString(_LaserTruFiber.GetLastMessageCompID(),16).ToUpper().PadLeft(2,'0')}{Convert.ToString(_LaserTruFiber.GetLastMessageCompNum(),16).ToUpper().PadLeft(2,'0')} {Convert.ToString(_LaserTruFiber.GetLastMessageMsgCode(),16).ToUpper().PadLeft(2,'0')}";
string alarmDescription = $" {_LaserTruFiber.GetLastMessageShortText()}";
AlarmManager.ChangeAlarmDescription(AlarmCode_PTOP.ALARM_DEVICE_LASER_ERROR_MSG, alarmCode + alarmDescription);
} else if (_LaserTruFiber.GetMonitoring()) {
string alarmCode = $"{Convert.ToString(_LaserTruFiber.GetLastMessageCompID(), 16).ToUpper().PadLeft(2, '0')}{Convert.ToString(_LaserTruFiber.GetLastMessageCompNum(), 16).ToUpper().PadLeft(2, '0')} {Convert.ToString(_LaserTruFiber.GetLastMessageMsgCode(), 16).ToUpper().PadLeft(2, '0')}";
string alarmDescription = $" {_LaserTruFiber.GetLastMessageShortText()}";
AlarmManager.ChangeAlarmDescription(AlarmCode_PTOP.ALARM_DEVICE_LASER_WARNING_MSG, alarmCode + alarmDescription);
}
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmLBAD(SequenceContext context, string id, SequenceActionResult param)
{
if (_LBAD == null || _SequenceSetting.LbadActivated == false)
{
return SequenceAction.Ok();
}
if (_LBAD.IsSimul)
{
return SequenceAction.Ok();
}
if (!_LBAD.IsActivated)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_LBAD_DEACTIVATED);
}
else
{
// TODO: ReadyByAuto 는 Auto 돌렸을 때, Sequence 안뜨도록 하는 로직 이라고 함. 이 부분 수정이 필요 할 듯.
// 이게 Sequence 안에서 Try 하면서 계속 붙이는 부분과 관련이 있는 듯함.
if (_LBAD.GetReadybyAuto())
{
if (!_LBAD.GetConnected())
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_LBAD_DISCONNECT);
}
// TODO: 이건 바로 밖의 else 부분으로 빼야 할 지도, Device check 와 IO 로 check 는 다르므로
if (_SequenceSetting.LbadActivatedWithIO && CheckDeviceIO())
{
if (!_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LBADReadyStatus)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LBAD_ERROR);
}
}
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmOCT(SequenceContext context, string id, SequenceActionResult param)
{
if (_OCT == null || _SequenceSetting.OctActivated == false)
{
return SequenceAction.Ok();
}
if (_OCT.IsSimul)
{
return SequenceAction.Ok();
}
if (!_OCT.IsActivated)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_OCT_DEACTIVATED);
}
else
{
if (!_OCT.GetConnected())
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_OCT_DISCONNECT);
}
if (_SequenceSetting.OctActivatedWithIO && CheckDeviceIO())
{
if (!_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LDDError)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_OCT_ERROR);
}
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmChiller(SequenceContext context, string id, SequenceActionResult param)
{
if (_Chiller == null || _SequenceSetting.ChillerActivated == false)
{
return SequenceAction.Ok();
}
if (_Chiller.IsSimul)
{
return SequenceAction.Ok();
}
if (!_Chiller.IsActivated)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_CHILLER_DEACTIVATED);
}
else
{
if (!_Chiller.GetConnected())
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_CHILLER_DISCONNECT);
}
if (_Chiller.GetChillerRunningFlag())
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_CHILLER_ERROR);
}
if (_SequenceSetting.ChillerActivatedWithIO && CheckDeviceIO())
{
// TODO: IO 로 Chiller check 하는 것이 있으면 추가
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmLeakSensor(SequenceContext context, string id, SequenceActionResult param)
{
if (_SequenceSetting.LeakSensorActivatedWithIO && CheckDeviceIO())
{
//Leak Sensor IO Map 추가 필요
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LeakSensorHead)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LEAK_SENSOR_DETECT_SCANNER);
}
if (_IO._iOUnit.ReadDiBit(Convert.ToInt32(eADIAddress.LeakSensorChiller)))
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_LEAK_SENSOR_DETECT_CHILLER);
}
}
return SequenceAction.Ok();
}
private static SequenceActionResult CheckAlarmIOBoard(SequenceContext context, string id, SequenceActionResult param)
{
if (!CheckDeviceIO())
return SequenceAction.Ok();
//if (!_IO.ReadDiBit(ePrismaticDIAddress.CCCAPASSYLaserMC1ON))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_CCCAPASSYLaserMC1ON);
//if (!_IO.ReadDiBit(ePrismaticDIAddress.CCCAPASSYLaserMC2ON))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_CCCAPASSYLaserMC2ON);
//if (_IO.ReadDiBit(ePrismaticDIAddress.BOXTempAlarm))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_BOXTempAlarm);
//if (!_IO.ReadDiBit(ePrismaticDIAddress.CCCAPChillerLeakSensor))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_CCCAPChillerLeakSensor);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm1))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm1);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm2))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm2);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm3))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm3);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm4))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm4);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm5))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm5);
//if (_IO.ReadDiBit(ePrismaticDIAddress.FanAlarm6))
// AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_FanAlarm6);
return SequenceAction.Ok();
}
private static bool CheckDeviceIO()
{
return false;
if (_IO == null)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_IS_NULL);
return false;
}
// IO 가 Simul 이면, Read Bit 를 해주지 않기 위해
if (_IO.IsSimul)
{
return false;
}
if (_IO.IsActivated == false)
{
AlarmManager.Alarm(AlarmCode_PTOP.ALARM_DEVICE_IO_DEACTIVATED);
return false;
}
// 우선 주석 처리 함. 잦은 호출이 발생할 수 있어서
//if (_IO.IsConnected() == false) {
// AlarmManager.Alarm(AlaramCode_PrismaticScanner.ALARM_DEVICE_IO_DISCONNECT);
//}
return true;
}
//private static SequenceActionResult LoopLastNode(SequenceContext context, string id, SequenceActionResult param)
//{
// //Thread.Sleep(100);
// return SequenceAction.Ok();
//}
private static void OnForceError(SequenceContext arg1, string arg2)
{
}
private static void OnStopped(SequenceContext obj)
{
}
}
}