- CheckPageNoComp: PC_PAGE_NO 에코값과 현재 PLC_PAGE_NO 비교해 일치 시 PC_PAGE_CHANGE_COMPLETE=true, 불일치 시 false (기존 무조건 false) → 동일 Recipe/Page 반복 시 완료 ACK 전달 - SeqStatusMonitor: PLC/PC Auto State OFF 에지 감시 → PC_RECIPE_NO/PC_PAGE_NO 0 초기화. 단 PC Auto OFF는 M70515(Weld_01 Ready) 살아있으면 보존(Resume 시나리오) - ExecuteWelding: 완료비트 송신 간 딜레이 5→50ms 여유 확보 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
139 lines
5.5 KiB
C#
139 lines
5.5 KiB
C#
using Aurora.Api;
|
|
using AuroraIO;
|
|
using AuroraLaser;
|
|
using ILSOS_PrismaticRD_PTOP.Device;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using WeldingCommon.Alarm;
|
|
using WeldingCommon.Settings;
|
|
using WeldingCommon.Utils;
|
|
|
|
namespace WeldingCommon.Sequences
|
|
{
|
|
public class SeqStatusMonitor
|
|
{
|
|
static readonly Logger Log = new Logger("SeqStatusMonitor");
|
|
|
|
const string SEQ_START = "SEQ START"; // 딱 한번 Sequence 진입 시에만 실행될 Node
|
|
|
|
const string SEQ_LoopFirst = "SEQ Loop First";
|
|
|
|
public const string UPDATE_STATUS = "Update Status";
|
|
public const string UPDATE_UI = "Update UI";
|
|
public const string UPDATE_IO = "Update IO";
|
|
|
|
private static SequenceSetting _SequenceSetting;
|
|
|
|
private static Laser _laser;
|
|
private static PLCControllerPTOP _plc;
|
|
private static IODevice _io;
|
|
|
|
public const int TIMEOUT_PLC_LIVE_CHECK = 2000; // msec
|
|
public const int NODE_SLEEP = 20;
|
|
public static SequenceBuilder Builder()
|
|
{
|
|
SequenceBuilder sb = new SequenceBuilder(1000, true);
|
|
|
|
sb.AddAction(SEQ_START, StartNode);
|
|
sb.AddDecision(SEQ_LoopFirst, LoopFirstNode);
|
|
sb.AddAction(UPDATE_STATUS, UpdateStatus);
|
|
sb.AddAction(UPDATE_UI, UpdateUI);
|
|
sb.AddAction(UPDATE_IO, UpdateIO);
|
|
|
|
sb.Flows(sb.Init > sb[SEQ_START] > sb[SEQ_LoopFirst]
|
|
> sb[UPDATE_STATUS] > sb[UPDATE_UI]
|
|
> sb[UPDATE_IO] > sb[SEQ_LoopFirst]);
|
|
|
|
sb.Flows(sb[SEQ_LoopFirst] > sb.Final);
|
|
|
|
sb.OnStopped(OnStopped);
|
|
sb.OnForceError(OnForceError);
|
|
|
|
//sb.Draw("SeqAlarmMonitor.pdf");
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
private static SequenceActionResult StartNode(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
_SequenceSetting = context.Settings[CommonSettingIds.Sequence] as SequenceSetting;
|
|
|
|
if (_plc is null)
|
|
_plc = context.Devices[CommonDeviceIds.PLCDevice] as PLCControllerPTOP;
|
|
|
|
if (_laser is null)
|
|
_laser = context.Devices[CommonDeviceIds.Laser] as Laser;
|
|
|
|
if (_io is null)
|
|
_io = context.Devices[CommonDeviceIds.IODevice] as IODevice;
|
|
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static string LoopFirstNode(SequenceContext context, string id, ICollection<string> branches, SequenceActionResult param)
|
|
{
|
|
while (!context.Stopped) {
|
|
Thread.Sleep(NODE_SLEEP);
|
|
return UPDATE_STATUS;
|
|
}
|
|
|
|
return SeqNodeIds.FINAL;
|
|
}
|
|
|
|
private static SequenceActionResult UpdateStatus(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
_plc.WriteBit(PLCControllerPTOP.eBitOutput.PC_HEAVY_ALARM_STATUS, AlarmManager.HasAlarmLevelHigh());
|
|
_plc.WriteBit(PLCControllerPTOP.eBitOutput.PC_LIGHT_ALARM_STATUS, AlarmManager.HasAlarmLevelLow());
|
|
|
|
var boolian = _plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_ALARM_RESET).data;
|
|
if (ChangeChecker.IsChangedBoolMonitoring("AlarmReset", boolian, true)){
|
|
context.EventPublisher.Publish(new EventMessage("SeqStatusMonitor", CommonEventIds.EVENT_RESET_ALL_ALARMS_REQUEST));
|
|
}
|
|
|
|
// ── Auto State OFF 시 에코 워드(PC_RECIPE_NO/PC_PAGE_NO) 0 초기화 ──────────────
|
|
// PLC Auto OFF : 무조건 초기화
|
|
// PC Auto OFF : M70515(PLC_WELD_READY_REQ, Weld_01 Ready) 살아있으면 보존(초기화 생략)
|
|
bool plcAutoOff = ChangeChecker.IsChangedBoolMonitoring("PlcAutoStateOff",
|
|
_plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_AUTO_STATUS).data, false);
|
|
bool pcAutoOff = ChangeChecker.IsChangedBoolMonitoring("PcAutoStateOff",
|
|
_plc.ReadOutBit(PLCControllerPTOP.eBitOutput.PC_AUTO_STATUS).data, false);
|
|
|
|
bool weldReadyAlive = _plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_WELD_READY_REQ).data; // M70515
|
|
|
|
if (plcAutoOff || (pcAutoOff && !weldReadyAlive))
|
|
{
|
|
_plc.WriteWord(PLCControllerPTOP.eWordOutput.PC_RECIPE_NO, 0);
|
|
_plc.WriteWord(PLCControllerPTOP.eWordOutput.PC_PAGE_NO, 0);
|
|
Log.W($"[StatusMonitor] Auto OFF(PLC:{plcAutoOff}/PC:{pcAutoOff}, M70515:{weldReadyAlive}) → PC_RECIPE_NO/PC_PAGE_NO 0 초기화");
|
|
}
|
|
|
|
Thread.Sleep(NODE_SLEEP);
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult UpdateUI(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
Thread.Sleep(NODE_SLEEP);
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static SequenceActionResult UpdateIO(SequenceContext context, string id, SequenceActionResult param)
|
|
{
|
|
// 260618: M70509(구 PLC_RMS_USED)를 Recipe 변경 요청(PLC_RECIPE_CHANGE_REQ)으로 재정의.
|
|
// RMS 핸들러는 비활성(EquipmentSetup) 상태이고 Status.RMSUse 소비처가 없어 읽기 제거.
|
|
//Status.RMSUse = _plc.ReadBit(PLCControllerPTOP.eBitInput.PLC_RMS_USED).data;
|
|
Thread.Sleep(NODE_SLEEP);
|
|
return SequenceAction.Ok();
|
|
}
|
|
|
|
private static void OnStopped(SequenceContext context)
|
|
{
|
|
}
|
|
|
|
private static void OnForceError(SequenceContext context, string arg2)
|
|
{
|
|
}
|
|
}
|
|
}
|