2026-06-05 13:44:39 +09:00

257 lines
9.4 KiB
C#

using Aurora;
using Aurora.Api;
using Aurora.Api.Manager;
using Aurora.Framework.Alarm;
using AuroraPLC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using WeldingCommon.Devices;
using WeldingCommon.Sequences;
using static WeldingCommon.Devices.PLCController;
namespace WeldingCommon.Alarm
{
public class AlarmManager
{
private static readonly Logger AlarmLog = new Logger("ALARM");
protected static AlarmManager _Instance;
protected static IAuroraEnvironment _AuroraEnv;
public readonly IAlarmService _AlarmService;
private readonly IDeviceManager _DeviceManager;
private static PLCController _Plc;
public AlarmManager(IAuroraEnvironment aurora)
{
_AuroraEnv = aurora;
_AlarmService = aurora.AlarmService;
_DeviceManager = aurora.DeviceManager;
_Plc = _DeviceManager.GetDevice(CommonDeviceIds.PLCDevice) as PLCController;
// 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);
aurora.EventObservable.AsObservable(CommonEventIds.EVENT_RESET_ALL_ALARMS_REQUEST)
.Select(msg => msg.Param)
.Subscribe(ClearAllAlarmRequest);
}
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<AlarmDescription> alarmList)) {
return;
}
//_Plc?.WriteBit(_Plc.LightAlarmStatusAddr, false);
//_Plc?.WriteBit(_Plc.HeavyAlarmStatusAddr, false);
}
private void ClearAllAlarmRequest(object obj)
{
Application.Current.Dispatcher.InvokeAsync(() => _Instance._AlarmService.ClearAllAlarm());
//_Plc?.WriteBit(_Plc.LightAlarmStatusAddr, false);
//_Plc?.WriteBit(_Plc.HeavyAlarmStatusAddr, false);
}
public static bool Alarm(int code, bool isLog = true, bool useReport = true)
{
// 모든 Alarm 은 띄워 줌
if (!_Instance._AlarmService.GetCurrentAlarmCodes().Contains(code)) {
_Instance._AlarmService.SetAlarm(code, useReport);
AlarmDescription alarm = _Instance._AlarmService.GetAlarmDescription(code);
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.HeavyAlarmStatusAddr, true);
//} else {
// _Plc?.WriteBit(_Plc.LightAlarmStatusAddr, true);
//}
return true;
}
return false;
}
public static bool ChangeAlarmDescription(int code, string description, bool isLog = true, bool useReport = true)
{
// 중복 알람은 로그로 남기지 않도록 하는 코드
if (IsOccuredAlarm(code))
return true;
AlarmDescription alarm = _Instance._AlarmService.GetAlarmDescription(code);
alarm.Description = description;
// 모든 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.HeavyAlarmStatusAddr, true);
//} else {
// _Plc?.WriteBit(_Plc.LightAlarmStatusAddr, true);
//}
return true;
}
return false;
}
public static void StopCommonSequenceByAlarm(int code)
{
AlarmDescription alarm = _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 (_AuroraEnv.SequenceEntry[sequenceId].RunState == SequenceRunState.Running) {
_AuroraEnv.SequenceEntry[sequenceId].EmergencyStop();
AlarmLog.I($"{_AuroraEnv.SequenceEntry[sequenceId]} EmergencyStop");
}
}
// 공통부. 현재 발생한 중알람 여부 조회
public static bool HasAlarmLevelHigh()
{
try {
if (ApplicationExt.IsSimulation)
return false;
var alarmList = _Instance._AlarmService.GetCurrentAlarmCodes();
if (alarmList.Count > 0) {
foreach (var item in alarmList) {
if (IsAlarmLevelHigh(item)) {
return true;
}
}
}
return false;
} catch (Exception ex) {
AlarmLog.E($"{ex.Message} Exception Accured");
return false;
}
}
public static bool IsAlarmLevelHigh(int item)
{
var desc = _Instance._AlarmService.GetAlarmDescription(item);
if (desc != null) {
if (desc.Level == AlarmLevel.H) {
return true;
}
} else {
// Alarm Description을 알 수 없는 경우 : 위험할 수 있으니 일단 H로 취급
return true;
}
return false;
}
public static bool HasAlarmLevelLow()
{
var alarmList = _Instance._AlarmService.GetCurrentAlarmCodes();
if (alarmList.Count > 0) {
foreach (var item in alarmList) {
if (IsAlarmLevelLow(item)) {
return true;
}
}
}
return false;
}
public static bool IsAlarmLevelLow(int item)
{
var desc = _Instance._AlarmService.GetAlarmDescription(item);
if (desc != null) {
if (desc.Level == AlarmLevel.L) {
return true;
}
} else {
// Alarm Description을 알 수 없는 경우 : 위험할 수 있으니 일단 H로 취급
return true;
}
return false;
}
public static bool IsOccuredAlarm(int AlarmCode)
{
var CurAlarmList = _Instance._AlarmService.GetCurrentAlarmCodes();
if (CurAlarmList.FirstOrDefault(x => x == AlarmCode) != 0)
return true;
return false;
}
public static bool IsPlcEmoAlarm()
{
if (_Plc == null) return false;
else return _Plc.ReadBit(eCommonBitInput.PLC_EMO_STATUS).data;
}
public static bool IsPlcDoorOpen()
{
if (_Plc == null) return false;
else return _Plc.ReadBit(eCommonBitInput.PLC_DOOR_INTERLOCK).data;
}
}
}