2026-01-26 18:56:53 +09:00

146 lines
5.3 KiB
C#

using Aurora.Api.Manager;
using Aurora.Api;
using Aurora.Framework.Alarm;
using Aurora;
using AuroraPLC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reactive.Linq;
using WeldingCommon.Devices;
using WeldingCommon.Sequences;
using AuroraOCT;
namespace WeldingCommon.Alarm
{
public class AlarmManager
{
private static readonly Logger AlarmLog = new Logger("ALARM");
protected static AlarmManager _Instance;
public readonly IAuroraEnvironment _AuroraEnv;
public readonly IAlarmService _AlarmService;
private readonly IDeviceManager _DeviceManager;
private static PLCController _Plc;
private static OCT _OCT;
public AlarmManager(IAuroraEnvironment aurora)
{
_AuroraEnv = aurora;
_AlarmService = aurora.AlarmService;
_DeviceManager = aurora.DeviceManager;
_Plc = _DeviceManager.GetDevice(CommonDeviceIds.PLCDevice) as PLCController;
_OCT = _DeviceManager.GetDevice(CommonDeviceIds.OCT) as OCT;
// Reset Alarm Event Subscribe > Clear All Device Alarms
// TODO:: Check when event below generated. If event does not generated, remove.
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_ALARM_RESET_ALL_ALARM)
.Select(msg => msg.Param)
.Subscribe(ClearAllAlarm);
aurora.EventObservable.AsObservable(AuroraSysEvent.SYS_ALARM_RESET_ALARM)
.Select(msg => msg.Param)
.Subscribe(ClearAlarm);
}
public static void Init(IAuroraEnvironment aurora)
{
if (_Instance == null) {
_Instance = new AlarmManager(aurora);
}
}
private void ClearAlarm(object obj)
{
//각 Alarm별 clear 처리를 따로 해줘야 할까 ?
}
private void ClearAllAlarm(object mAlarmList)
{
if (!(mAlarmList is List<IAlarmDescription> alarmList)) {
return;
}
//_Plc?.SetDOStatus("PC_LIGHT_ALARM_STATUS", false);
//_Plc?.SetDOStatus("PC_HEAVY_ALARM_STATUS", false);
_Plc.WriteBit(_Plc.PC_LIGHT_ALARM_STATUSAddr, false);
_Plc.WriteBit(_Plc.PC_HEAVY_ALARM_STATUSAddr, false);
//_OCT.OCT_QA_Error = false;
_Instance._AlarmService.ClearAllAlarm();
}
public static bool Alarm(int code, bool isLog = true, bool useReport = true)
{
AlarmDescription alarm = (AlarmDescription)_Instance._AlarmService.GetAlarmDescription(code);
// 모든 Alarm 은 띄워 줌
if (!_Instance._AlarmService.GetCurrentAlarmCodes().Contains(code)) {
_Instance._AlarmService.SetAlarm(code, useReport);
if (isLog) {
if (alarm.Level == AlarmLevel.H) {
AlarmLog.E($"Code : {code} , Description : {alarm.Name}");
} else {
AlarmLog.W($"Code : {code} , Description : {alarm.Name}");
}
}
//PLC의 중알람의 경우 PC에서 Dialog만 발생하고 Alarm 중알람 Word를 써주지 않는다
if (alarm.Level == AlarmLevel.H && alarm.Unit == "PLC") {
return true;
}
if (alarm.Level == AlarmLevel.H) {
_Plc.WriteBit(_Plc.PC_HEAVY_ALARM_STATUSAddr, true);
} else {
_Plc.WriteBit(_Plc.PC_LIGHT_ALARM_STATUSAddr, true);
}
return true;
} else {
}
return false;
}
public static void StopCommonSequenceByAlarm(int code)
{
AlarmDescription alarm = (AlarmDescription)_Instance._AlarmService.GetAlarmDescription(code);
// 바로 Sequence 를 정지해야 하는 경우 발생할 수 있음.
// 불필요 할까?? Device 의 상태에 따라서 멈춰야 하는 Sequence 가 다를 수도 있다.
// 만약에 Sequence 가 종료되었을 때, pass, fail 여부에 따라 다를 지도.
if (alarm.Level == AlarmLevel.H) {
StopSequence(CommonSequenceIds.SeqMarkGrid);
StopSequence(CommonSequenceIds.SeqScannerCalibration);
StopSequence(CommonSequenceIds.SeqReceiveCellInfo);
StopSequence(CommonSequenceIds.SeqReportCellResult);
StopSequence(CommonSequenceIds.SeqScoutFlyingVision);
StopSequence(CommonSequenceIds.SeqScoutNormal);
StopSequence(CommonSequenceIds.SeqUploadWeldingList);
StopSequence(CommonSequenceIds.SeqTeachingRun);
}
}
protected static void StopSequence(string sequenceId)
{
if (_Instance._AuroraEnv.SequenceEntry[sequenceId].RunState == SequenceRunState.Running) {
_Instance._AuroraEnv.SequenceEntry[sequenceId].EmergencyStop();
AlarmLog.I($"{_Instance._AuroraEnv.SequenceEntry[sequenceId]} EmergencyStop");
}
}
public static void SetPlc(IAuroraEnvironment aurora)
{
_Plc = aurora.DeviceManager.GetDevice(CommonDeviceIds.PLCDevice) as PLCController;
}
}
}