257 lines
9.4 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|