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); } }