Files
6098/Cowain.Bake.Main/Station/AlarmStation.cs

191 lines
6.9 KiB
C#
Raw Normal View History

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.上传MOM3.界面显示报警
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()
{
}
}
}