报警相关代码操作共享集合时有线程安全风险
This commit is contained in:
@@ -1527,56 +1527,63 @@ namespace JinYuan.ControlCenters
|
|||||||
/// <param name="resByte"></param>
|
/// <param name="resByte"></param>
|
||||||
List<AlarmData> listOld = new List<AlarmData>();
|
List<AlarmData> listOld = new List<AlarmData>();
|
||||||
List<AlarmData> listNew = new List<AlarmData>();
|
List<AlarmData> listNew = new List<AlarmData>();
|
||||||
List<AlarmStatus> listAlarmStatus = null;
|
//List<AlarmStatus> listAlarmStatus = null;
|
||||||
string alarmStartDate = "";
|
string alarmStartDate = "";
|
||||||
int AlarmCount = 0;
|
int AlarmCount = 0;
|
||||||
string strAllAlarm = "";
|
string strAllAlarm = "";
|
||||||
bool isRead = false;
|
bool isRead = false;
|
||||||
|
private readonly object _alarmLock = new object();
|
||||||
private void ShowAlarmEven_Run(string strGuidAlarm)
|
private void ShowAlarmEven_Run(string strGuidAlarm)
|
||||||
{
|
{
|
||||||
if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
|
if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
|
||||||
{
|
{
|
||||||
//StringBuilder sb = new StringBuilder();
|
|
||||||
listNew.Clear();
|
|
||||||
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
|
||||||
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500);
|
JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500);
|
||||||
if (resByte.IsSuccess && resByte != null)
|
|
||||||
{
|
|
||||||
if (resByte == null) { return; }
|
|
||||||
//如果未配置报警地址信息返回 TODO
|
|
||||||
if (listAlarmForm == null) { return; }
|
|
||||||
int startPlcAddr = 10010;//TODO 读取起始地址
|
|
||||||
//3.公用方法解析byte[]数据 => List<AlarmStatus>
|
|
||||||
if (resByte == null) { return; } //如果未配置报警地址信息返回
|
|
||||||
//TODO 切换三菱和欧姆龙
|
|
||||||
listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
|
|
||||||
//4.判定有不良后,关联AlarmStatus 和AlarmForm
|
|
||||||
if (listAlarmStatus == null) { return; } //状态信息为空返回
|
|
||||||
//如果有报警,获取报警信息
|
|
||||||
if (listAlarmStatus.Any(p => p.Status))
|
|
||||||
{
|
|
||||||
//关联表单数据和报警记录,获取报警信息
|
|
||||||
listNew = listAlarmStatus
|
|
||||||
.Where(s => s.Status)
|
|
||||||
.Join(listAlarmForm
|
|
||||||
, s => s.PLCAdress
|
|
||||||
, f => f.PLCAdress
|
|
||||||
, (s, f) => new AlarmData()
|
|
||||||
{
|
|
||||||
AlarmGuid = strGuidAlarm,
|
|
||||||
PLCAdress = s.PLCAdress,
|
|
||||||
AlarmCode = f.AlarmCode,
|
|
||||||
AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
|
|
||||||
AlarmType = "停机报警",
|
|
||||||
AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
|
|
||||||
AlarmState = "1",
|
|
||||||
StartTime = Date,
|
|
||||||
EndTime = Date,
|
|
||||||
Flag = 0
|
|
||||||
}).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
string strAlarm = "";
|
if (!resByte.IsSuccess || resByte == null || listAlarmForm == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int startPlcAddr = 10010;
|
||||||
|
var listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
|
||||||
|
|
||||||
|
if (listAlarmStatus == null || !listAlarmStatus.Any(p => p.Status))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前新的报警信息
|
||||||
|
var newAlarmData = new List<AlarmData>();
|
||||||
|
// 当前已经消除的报警信息
|
||||||
|
var saveAlarmData = new List<AlarmData>();
|
||||||
|
var listOldAlarm = new List<AlarmData>();
|
||||||
|
|
||||||
|
#region 操作共享列表listNew、listOld时加锁
|
||||||
|
lock (_alarmLock)
|
||||||
|
{
|
||||||
|
listNew.Clear();
|
||||||
|
|
||||||
|
//关联表单数据和报警记录,获取报警信息
|
||||||
|
listNew = listAlarmStatus
|
||||||
|
.Where(s => s.Status)
|
||||||
|
.Join(listAlarmForm
|
||||||
|
, s => s.PLCAdress
|
||||||
|
, f => f.PLCAdress
|
||||||
|
, (s, f) => new AlarmData()
|
||||||
|
{
|
||||||
|
AlarmGuid = strGuidAlarm,
|
||||||
|
PLCAdress = s.PLCAdress,
|
||||||
|
AlarmCode = f.AlarmCode,
|
||||||
|
AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
|
||||||
|
AlarmType = "停机报警",
|
||||||
|
AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
|
||||||
|
AlarmState = "1",
|
||||||
|
StartTime = Date,
|
||||||
|
EndTime = Date,
|
||||||
|
Flag = 0
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
//添加新的报警信息
|
//添加新的报警信息
|
||||||
if (listNew.Count > 0)
|
if (listNew.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -1595,6 +1602,8 @@ namespace JinYuan.ControlCenters
|
|||||||
if (alarmLog == null)
|
if (alarmLog == null)
|
||||||
{
|
{
|
||||||
listOld.Add(r);
|
listOld.Add(r);
|
||||||
|
newAlarmData.Add(r.Clone() as AlarmData);
|
||||||
|
|
||||||
//上传报警
|
//上传报警
|
||||||
if (CommonMethods.sysConfig.MesModeSwitching)
|
if (CommonMethods.sysConfig.MesModeSwitching)
|
||||||
{
|
{
|
||||||
@@ -1614,9 +1623,6 @@ namespace JinYuan.ControlCenters
|
|||||||
CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
|
CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//移除已经消除的报警信息
|
|
||||||
var saveAlarmData = new List<AlarmData>();
|
|
||||||
var listOldAlarm = new List<AlarmData>();
|
|
||||||
listOldAlarm.AddRange(listOld);
|
listOldAlarm.AddRange(listOld);
|
||||||
if (listOldAlarm.Count > 0)
|
if (listOldAlarm.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -1626,55 +1632,57 @@ namespace JinYuan.ControlCenters
|
|||||||
if (alarmLog == null)
|
if (alarmLog == null)
|
||||||
{
|
{
|
||||||
item.EndTime = Date;
|
item.EndTime = Date;
|
||||||
saveAlarmData.Add(item);
|
saveAlarmData.Add(item.Clone() as AlarmData);
|
||||||
listOld.Remove(item);
|
listOld.Remove(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
if (saveAlarmData.Count > 0)
|
if (saveAlarmData.Count > 0)
|
||||||
|
{
|
||||||
|
string strALLAlarm = "";
|
||||||
|
//写csv文件
|
||||||
|
var nowDate = DateTime.Now;
|
||||||
|
string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}";
|
||||||
|
string fileName = $@"{nowDate.Day}.csv";
|
||||||
|
string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
|
||||||
|
string alarmContent = string.Empty;
|
||||||
|
|
||||||
|
List<FaultCodeList> faultCodeLists = new List<FaultCodeList>();
|
||||||
|
foreach (var m in saveAlarmData)
|
||||||
{
|
{
|
||||||
string strALLAlarm = "";
|
FaultCodeList item = new FaultCodeList();
|
||||||
//写csv文件
|
item.faultCode = m.AlarmCode;
|
||||||
var nowDate = DateTime.Now;
|
faultCodeLists.Add(item);
|
||||||
string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}";
|
alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
|
||||||
string fileName = $@"{nowDate.Day}.csv";
|
strALLAlarm += $"{m.AlarmContent},";
|
||||||
string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
|
|
||||||
string alarmContent = string.Empty;
|
|
||||||
|
|
||||||
List<FaultCodeList> faultCodeLists = new List<FaultCodeList>();
|
//上传报警
|
||||||
foreach (var m in saveAlarmData)
|
|
||||||
{
|
|
||||||
FaultCodeList item = new FaultCodeList();
|
|
||||||
item.faultCode = m.AlarmCode;
|
|
||||||
faultCodeLists.Add(item);
|
|
||||||
alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
|
|
||||||
strALLAlarm += $"{m.AlarmContent},";
|
|
||||||
|
|
||||||
//上传报警
|
|
||||||
if (CommonMethods.sysConfig.MesModeSwitching)
|
|
||||||
{
|
|
||||||
//上传报警
|
|
||||||
MESDataCombin.EquAlarm(m, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
|
|
||||||
CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);
|
|
||||||
|
|
||||||
// 上传消除的报警信息
|
|
||||||
if (CommonMethods.sysConfig.MesModeSwitching)
|
if (CommonMethods.sysConfig.MesModeSwitching)
|
||||||
{
|
{
|
||||||
//上传设备报警状态
|
//上传报警
|
||||||
MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists);
|
MESDataCombin.EquAlarm(m, 0);
|
||||||
}
|
}
|
||||||
//报警保存
|
|
||||||
SaveAlarmCount(saveAlarmData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
|
||||||
|
CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);
|
||||||
|
|
||||||
|
// 上传消除的报警信息
|
||||||
|
if (CommonMethods.sysConfig.MesModeSwitching)
|
||||||
|
{
|
||||||
|
//上传设备报警状态
|
||||||
|
MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists);
|
||||||
|
}
|
||||||
|
//报警保存
|
||||||
|
SaveAlarmCount(saveAlarmData, newAlarmData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
List<AlarmData> safeEqptStatus = new List<AlarmData>();
|
List<AlarmData> safeEqptStatus = new List<AlarmData>();
|
||||||
List<AlarmStatus> listSafeEqptStatus = null;
|
List<AlarmStatus> listSafeEqptStatus = null;
|
||||||
private void ShowSafeEqptEven_Run()
|
private void ShowSafeEqptEven_Run()
|
||||||
@@ -1742,7 +1750,7 @@ namespace JinYuan.ControlCenters
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 报警保存
|
/// 报警保存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SaveAlarmCount(List<AlarmData> alarmDatas)
|
private void SaveAlarmCount(List<AlarmData> alarmDatas, List<AlarmData> newAlarmDataList)
|
||||||
{
|
{
|
||||||
bool ISAdd = false;
|
bool ISAdd = false;
|
||||||
var recordToUpdate = new AlarmCountEntry();
|
var recordToUpdate = new AlarmCountEntry();
|
||||||
@@ -1783,7 +1791,7 @@ namespace JinYuan.ControlCenters
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foreach (var m in listNew)
|
foreach (var m in newAlarmDataList)
|
||||||
{
|
{
|
||||||
AlarmCountEntry alarm = new AlarmCountEntry();
|
AlarmCountEntry alarm = new AlarmCountEntry();
|
||||||
alarm.PLCAdress = m.PLCAdress;
|
alarm.PLCAdress = m.PLCAdress;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
using CsvHelper.Configuration.Attributes;
|
using CsvHelper.Configuration.Attributes;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace JinYuan.Models
|
namespace JinYuan.Models
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 工位报警数据
|
/// 工位报警数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AlarmData
|
public class AlarmData : ICloneable
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 报警唯一标识符
|
/// 报警唯一标识符
|
||||||
@@ -56,6 +57,21 @@ namespace JinYuan.Models
|
|||||||
/// 更新状态
|
/// 更新状态
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Flag { get; set; }
|
public int Flag { get; set; }
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new AlarmData() {
|
||||||
|
AlarmGuid = this.AlarmGuid,
|
||||||
|
PLCAdress = this.PLCAdress,
|
||||||
|
AlarmContent = this.AlarmContent,
|
||||||
|
AlarmCode = this.AlarmCode,
|
||||||
|
AlarmType = this.AlarmType,
|
||||||
|
StartTime = this.StartTime,
|
||||||
|
EndTime = this.EndTime,
|
||||||
|
AlarmDesc = this.AlarmDesc,
|
||||||
|
AlarmState = this.AlarmState,
|
||||||
|
Flag = this.Flag
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AlarmCSVData
|
public class AlarmCSVData
|
||||||
|
|||||||
Reference in New Issue
Block a user