191 lines
6.9 KiB
C#
191 lines
6.9 KiB
C#
|
|
using Cowain.Bake.BLL;
|
|||
|
|
using Cowain.Bake.Common.Core;
|
|||
|
|
using Cowain.Bake.Common.Enums;
|
|||
|
|
using Cowain.Bake.Common.Interface;
|
|||
|
|
using Cowain.Bake.Communication.MOM;
|
|||
|
|
using Cowain.Bake.Model;
|
|||
|
|
using Cowain.Bake.Model.Models;
|
|||
|
|
using Opc.Ua;
|
|||
|
|
using Prism.Ioc;
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Concurrent;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Linq;
|
|||
|
|
using Unity;
|
|||
|
|
using JSON = Newtonsoft.Json.JsonConvert;
|
|||
|
|
using static Cowain.Bake.Common.Models.MESModel;
|
|||
|
|
|
|||
|
|
namespace Cowain.Bake.Main.Station
|
|||
|
|
{
|
|||
|
|
public class AlarmStation : IServerManager
|
|||
|
|
{
|
|||
|
|
readonly ConcurrentDictionary<string, bool[]> _alarmValues;
|
|||
|
|
public string Name { get; set; } = "";
|
|||
|
|
List<TAlarm> _allAlarms { get; set; } //ConcurrentBag //验证,如果还报线程问题,就用ConcurrentBag
|
|||
|
|
List<TAlarmContent> _allAlarmContent { get; set; }
|
|||
|
|
public IUnityContainer _unityContainer { get; set; }
|
|||
|
|
List<AlertInfoModel> _arrayAlert = new List<AlertInfoModel>();
|
|||
|
|
private readonly Prism.Events.IEventAggregator _eventAggregator;
|
|||
|
|
readonly static object _objLock = new object();
|
|||
|
|
|
|||
|
|
public AlarmStation(IUnityContainer unityContainer, Prism.Events.IEventAggregator eventAggregator)
|
|||
|
|
{
|
|||
|
|
_unityContainer = unityContainer;
|
|||
|
|
_alarmValues = new ConcurrentDictionary<string, bool[]>();
|
|||
|
|
_eventAggregator = eventAggregator;
|
|||
|
|
Start();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Start()
|
|||
|
|
{
|
|||
|
|
_allAlarms = _unityContainer.Resolve<AlarmService>().GetAllInAlarms();
|
|||
|
|
_allAlarmContent = _unityContainer.Resolve<AlarmContentService>().GetAll();
|
|||
|
|
|
|||
|
|
foreach(var item in _allAlarms)
|
|||
|
|
{
|
|||
|
|
_eventAggregator.GetEvent<AlarmAddEvent>().Publish(item);//2.界面刷新,发布事件(发送消息)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//报警可能是一个数组(TAlarmContent),也可能是一个点(TTagList)。
|
|||
|
|
public void AlarmInfo(DataValue data, Variable node)
|
|||
|
|
{
|
|||
|
|
if (1 == data.WrappedValue.TypeInfo.ValueRank) //数组
|
|||
|
|
{
|
|||
|
|
lock (_objLock)
|
|||
|
|
{
|
|||
|
|
AlarmArray(data, node); //会导致恢复后,一条报警信息会显示二次
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn("没有单个数据报警!");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public TAlarmContent GetAlarmContent(int nodeId, int offset)
|
|||
|
|
{
|
|||
|
|
return _allAlarmContent.Where(m => m.Offset == offset
|
|||
|
|
&& m.TagIds.Split(',').Any(x => x == nodeId.ToString())
|
|||
|
|
&& !string.IsNullOrEmpty(m.Desc)).FirstOrDefault();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
AlertInfoModel AssembleAlertModel(int code, string reset, string message)
|
|||
|
|
{
|
|||
|
|
return new AlertInfoModel()
|
|||
|
|
{
|
|||
|
|
AlertCode = code.ToString(),
|
|||
|
|
AlertReset = reset,
|
|||
|
|
AlertMessage = message,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//一个数组报警(订阅的是一个数组) --TAlarmContent
|
|||
|
|
private void AlarmArray(DataValue data, Variable node)
|
|||
|
|
{
|
|||
|
|
string key = "";
|
|||
|
|
_arrayAlert.Clear();
|
|||
|
|
bool[] value = data.WrappedValue.Value as bool[];
|
|||
|
|
if (data.WrappedValue.Value is bool[] v)
|
|||
|
|
{
|
|||
|
|
value = v;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Warn($"数组报警类型异常:{data.WrappedValue.Value.GetType().Name}");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//LogHelper.Instance.Warn($"数组报警:{JSON.SerializeObject(value)}");
|
|||
|
|
key = $"StationId:{node.StationId},Id:{node.Id}";
|
|||
|
|
|
|||
|
|
if (_alarmValues.TryGetValue(key, out bool[] oldValue)) //有
|
|||
|
|
{
|
|||
|
|
if (oldValue.Count() != value.Count())
|
|||
|
|
{
|
|||
|
|
LogHelper.Instance.Error($"报警老值与新值长度不匹配,key:{key},desc:{node.VarDesc}");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
var diffs = value.Zip(oldValue, (a, b) => a != b).Select((b, i) => new { Value = b, Index = i }).Where(x => x.Value);
|
|||
|
|
foreach (var item in diffs)
|
|||
|
|
{
|
|||
|
|
DealAlarmNode(node, item.Index, value[item.Index]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else //第一次进入
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
for (int i = 0; i < value.Count(); ++i)
|
|||
|
|
{
|
|||
|
|
DealAlarmNode(node, i, value[i]);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_alarmValues[key] = value;
|
|||
|
|
if (int.Parse(_unityContainer.Resolve<SysSetupService>().GetValueByParaID(ESysSetup.MOMEnable.ToString())) == (int)EMOMEnable.Enable)
|
|||
|
|
{
|
|||
|
|
_unityContainer.Resolve<MESProcess>().MESEqptAlert(_arrayAlert);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void DealAlarmNode(Variable node, int offset, bool value)
|
|||
|
|
{
|
|||
|
|
TAlarmContent alarmContent = GetAlarmContent(node.Id, offset); //找到报警信息
|
|||
|
|
|
|||
|
|
if (alarmContent == null)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
//报警三种处理,1,入库,2.上传MOM,3.界面显示报警
|
|||
|
|
if (value)
|
|||
|
|
{
|
|||
|
|
AddAlarm(offset, node.StationId, alarmContent.Desc);
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
DeleteAlarm(offset, node.StationId, alarmContent.Desc);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void AddAlarm(int errCode, int stationId, string desc)
|
|||
|
|
{
|
|||
|
|
var alarm = _allAlarms.Find(x => x.StationId == stationId && x.Desc == desc);
|
|||
|
|
if (null == alarm)
|
|||
|
|
{
|
|||
|
|
TAlarm currentAlarm = new TAlarm()
|
|||
|
|
{
|
|||
|
|
StationId = stationId,
|
|||
|
|
Desc = desc,
|
|||
|
|
StartTime = DateTime.Now,
|
|||
|
|
Status = EAlarmStatus.Alert.GetDescription(),
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
_allAlarms.Add(currentAlarm); //增加到内存
|
|||
|
|
_arrayAlert.Add(AssembleAlertModel(errCode, ((int)EAlarmStatus.Alert).ToString(), desc)); //上传到MES
|
|||
|
|
_unityContainer.Resolve<AlarmService>().Insert<TAlarm>(currentAlarm); //增加到DB
|
|||
|
|
_eventAggregator.GetEvent<AlarmAddEvent>().Publish(currentAlarm);//.界面刷新,发布事件(发送消息)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void DeleteAlarm(int errCode, int stationId, string desc)
|
|||
|
|
{
|
|||
|
|
TAlarm alarm = _allAlarms.Find(x => x.StationId == stationId
|
|||
|
|
&& x.Desc == desc);
|
|||
|
|
|
|||
|
|
if (null != alarm)
|
|||
|
|
{
|
|||
|
|
_allAlarms.Remove(alarm);
|
|||
|
|
_arrayAlert.Add(AssembleAlertModel(errCode, ((int)EAlarmStatus.Renew).ToString(), desc));
|
|||
|
|
_unityContainer.Resolve<AlarmService>().CancelAlarm(alarm);
|
|||
|
|
_eventAggregator.GetEvent<AlarmCancelEvent>().Publish(alarm);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Stop()
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|