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

191 lines
6.9 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()
{
}
}
}