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 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; } } }