using Common.Const;
using Entity.DbModel.Station;
using HybirdFrameworkCore.Autofac.Attribute;
using HybirdFrameworkCore.Const;
using HybirdFrameworkDriver.ModbusTcpMaster;
using log4net;
using Repository.Station;
using Service.Plc.Msg;
namespace Service.Plc.Client;
///
///
///
[Scope]
public class PlcClient : ModbusTcpMaster
{
private static readonly ILog Log = LogManager.GetLogger(typeof(PlcClient));
private long TaskNo = 0;
public BinInfoRepository BinInfoRepository { get; set; }
public EquipAlarmDefineRepository EquipAlarmDefineRepository { get; set; }
public EquipAlarmRecordRepository EquipAlarmRecordRepository { get; set; }
public EquipAlarmProcessRecordRepository EquipAlarmProcessRecordRepository { get; set; }
//修改当前任务
public void ExChangeTaskNo(long taskNo)
{
Interlocked.Exchange(ref TaskNo, taskNo);
}
//重置当前任务
public void ResetTaskNo()
{
Interlocked.Exchange(ref TaskNo, 0);
}
//读取当前任务
public long ReadTaskNo()
{
return Interlocked.Read(ref TaskNo);
}
public PlcClient()
{
ReadAction = BatchRead;
Ip = "172.0.20.40";
Port = 502;
Duration = 1000;
AutoReConnect = true;
ByteSeq = EndingConst.ByteSeq.BA;
WordSeq = EndingConst.WordSeq.CD;
}
private bool BatchRead(ModbusTcpMaster master)
{
try
{
Log.Info("Plc read satrt");
if (master != null)
{
var bytes01 = master.BatchReadHolderRegister(1, 118);
if (bytes01 != null)
{
PlcMgr.DataValidityTime = DateTime.Now;
ModbusDecoder.Decode(bytes01, PlcMgr.HostToPlcData, EndingConst.ByteSeq.AB,
EndingConst.WordSeq.DC);
}
var bytes02 = master.BatchReadHolderRegister(201, 232);
if (bytes02 != null)
{
PlcMgr.DataValidityTime = DateTime.Now;
ModbusDecoder.Decode(bytes02, PlcMgr.PlcToHostData, EndingConst.ByteSeq.AB,
EndingConst.WordSeq.DC);
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec01.Value, "1");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec02.Value, "2");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec03.Value, "3");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec04.Value, "4");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec05.Value, "5");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec06.Value, "6");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec07.Value, "7");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec08.Value, "8");
UpdateBinInfoCache(PlcMgr.PlcToHostData.MaterialDetec09.Value, "9");
UpdateBinInfoCache(PlcMgr.PlcToHostData.MaterialDetec10.Value, "10");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec21.Value, "11");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec22.Value, "12");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec23.Value, "13");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec24.Value, "14");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec25.Value, "15");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec26.Value, "16");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec27.Value, "17");
UpdateBinInfo(PlcMgr.PlcToHostData.MaterialDetec28.Value, "18");
UpdateBinInfoCache(PlcMgr.PlcToHostData.MaterialDetec29.Value, "19");
UpdateBinInfoCache(PlcMgr.PlcToHostData.MaterialDetec30.Value, "20");
}
var bytes03 = master.BatchReadHolderRegister(701, 32);
if (bytes03 != null)
{
PlcMgr.LastPlcFaultData = PlcMgr.PlcFaultData;
PlcMgr.DataValidityTime = DateTime.Now;
ModbusDecoder.Decode(bytes03, PlcMgr.PlcFaultData, EndingConst.ByteSeq.AB,
EndingConst.WordSeq.CD);
List alarm = new List()
{
PlcMgr.PlcFaultData.ErrorCode01.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode02.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode03.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode04.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode05.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode06.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode07.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode08.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode09.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode10.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode11.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode12.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode13.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode14.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode15.Value.ToString(),
PlcMgr.PlcFaultData.ErrorCode16.Value.ToString(),
};
SaveAlarmInfo(alarm);
}
Log.Info("Plc read finish");
}
}
catch (Exception e)
{
Log.Info($"Plc read error:{e}");
throw;
}
return true;
}
private void SaveAlarmInfo(List lstAlarm)
{
string plc = "plc";
if (lstAlarm.Count > 0)
{
#region 有报警比较两边差异,新出现的报警就添加,消失的报警就处理并记录
var lstEquipAlarmRecord = EquipAlarmRecordRepository.QueryListByClause(i => i.EquipTypeCode == 3);
var sqllstAlarm = lstEquipAlarmRecord.Select(obj => obj.ErrorCode).ToList();
// 找出实时报警中存在但数据库中不存在的元素
List uniqueToList1 = lstAlarm.Except(sqllstAlarm).ToList();
// 找出数据库中存在但实时报警中不存在的元素
List uniqueToList2 = sqllstAlarm.Except(lstAlarm).ToList();
if (uniqueToList1.Count > 0)
{
//这里要添加新的报警数据
foreach (var errorCode in uniqueToList1)
{
EquipAlarmDefine? alarmDefine =
EquipAlarmDefineRepository.SelectByEquipCodeAndErrorCode((int)EquipmentType.Plc, plc,
errorCode);
if (alarmDefine != null)
{
EquipAlarmRecord record = new EquipAlarmRecord()
{
EquipTypeCode = alarmDefine.EquipTypeCode,
EquipCode = alarmDefine.EquipCode,
ErrorCode = alarmDefine.ErrorCode,
ErrorLevel = alarmDefine.ErrorLevel,
ErrorMsg = alarmDefine.ErrorMsg,
ProcessMethod = alarmDefine.ProcessMethod,
StartTime = DateTime.Now
};
EquipAlarmRecordRepository.Insert(record);
}
}
}
if (uniqueToList2.Count > 0)
{
//这些是要清除实时报警,并且处理记录的。
// 使用LINQ找出ErrorCode在uniqueToList2中的EquipAlarmRecord对象
List filteredObjectList = lstEquipAlarmRecord
.Where(obj => uniqueToList2.Contains(obj.ErrorCode))
.ToList();
foreach (var VARIABLE in filteredObjectList)
{
EquipAlarmProcessRecord EquipAlarmProcessRecord = new EquipAlarmProcessRecord();
EquipAlarmProcessRecord.EquipTypeCode = VARIABLE.EquipTypeCode;
EquipAlarmProcessRecord.EquipCode = VARIABLE.EquipCode;
EquipAlarmProcessRecord.ErrorCode = VARIABLE.ErrorCode;
EquipAlarmProcessRecord.ErrorLevel = VARIABLE.ErrorLevel;
EquipAlarmProcessRecord.ErrorMsg = VARIABLE.ErrorMsg;
EquipAlarmProcessRecord.ProcessMethod = VARIABLE.ProcessMethod;
EquipAlarmProcessRecord.StartTime = VARIABLE.StartTime;
EquipAlarmProcessRecord.ProcessTime = DateTime.Now;
EquipAlarmProcessRecordRepository.Insert(EquipAlarmProcessRecord);
}
EquipAlarmRecordRepository.Delete(filteredObjectList);
}
#endregion
}
else
{
#region 没报警把已处理记录更新并删除实时报警
var lstEquipAlarmRecord = EquipAlarmRecordRepository.QueryListByClause(i => i.EquipTypeCode == 3);
if (lstEquipAlarmRecord.Count > 0)
{
foreach (var VARIABLE in lstEquipAlarmRecord)
{
EquipAlarmProcessRecord EquipAlarmProcessRecord = new EquipAlarmProcessRecord();
EquipAlarmProcessRecord.EquipTypeCode = VARIABLE.EquipTypeCode;
EquipAlarmProcessRecord.EquipCode = VARIABLE.EquipCode;
EquipAlarmProcessRecord.ErrorCode = VARIABLE.ErrorCode;
EquipAlarmProcessRecord.ErrorLevel = VARIABLE.ErrorLevel;
EquipAlarmProcessRecord.ErrorMsg = VARIABLE.ErrorMsg;
EquipAlarmProcessRecord.ProcessMethod = VARIABLE.ProcessMethod;
EquipAlarmProcessRecord.StartTime = VARIABLE.StartTime;
EquipAlarmProcessRecord.ProcessTime = DateTime.Now;
EquipAlarmProcessRecordRepository.Insert(EquipAlarmProcessRecord);
}
}
EquipAlarmRecordRepository.Delete(lstEquipAlarmRecord);
#endregion
}
}
private void UpdateBinInfo(int exists, string binNo)
{
if (exists == 0)
BinInfoRepository.Update(
it =>
new BinInfo()
{
Exists = 0,
BatteryNo = "-1",
Soc = (decimal)-1,
Soe = (decimal)-1,
Soh = (decimal)-1,
},
it => it.No == binNo);
else
BinInfoRepository.Update(it => it.Exists == 1,
it => it.No == binNo);
}
private void UpdateBinInfoCache(int exists, string binNo)
{
if (exists == 0)
BinInfoRepository.Update(
it =>
new BinInfo()
{
Exists = 0,
},
it => it.No == binNo);
else
BinInfoRepository.Update(it => it.Exists == 1,
it => it.No == binNo);
}
}