using Khd.Core.Domain.Dto.webapi; using Khd.Core.Domain.Models; using Khd.Core.EntityFramework; using Khd.Core.Library; using Khd.Core.Plc.S7; using Khd.Core.Wcs.Global; using Masuit.Tools; using Masuit.Tools.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; namespace Khd.Core.Wcs.Wcs { public class SystemTimer { private readonly LoggerUtils _logger = new LoggerUtils(); private readonly IHost host; private Plc.S7.Plc Plc30 = StaticData.PlcDic[0]; private Plc.S7.Plc Plc31 = StaticData.PlcDic[1]; private Plc.S7.Plc Plc220 = StaticData.PlcDic[2]; public SystemTimer(IHost host) { this.host = host; } public void Start() { var messageSynchronousThread = new Thread(MessageSynchronousLogic) { Name = "MessageSynchronousThread", IsBackground = true }; messageSynchronousThread.Start();//陈工设备信息推送 var PlcHeartBeat30Thread = new Thread(PlcHeartBeat30Logic) { Name = "PlcHeartBeat30Thread", IsBackground = true }; PlcHeartBeat30Thread.Start();//脉冲 var PlcHeartBeat31Thread = new Thread(PlcHeartBeat31Logic) { Name = "PlcHeartBeat31Thread", IsBackground = true }; PlcHeartBeat31Thread.Start();//脉冲 var PlcHearBeat220Thread = new Thread(PlcHearBeat220Logic) { Name = "PlcHeartBeat220Thread", IsBackground = true }; PlcHearBeat220Thread.Start(); var deleteTaskThread = new Thread(DeleteTaskLogic) { Name = "DeleteTaskThread", IsBackground = true }; deleteTaskThread.Start(); Console.WriteLine($"{DateTime.Now}: SystemTimer started"); } private void DeleteTaskLogic(object? obj) { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); while (true) { try { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); List wcsTasks = dbContext.WcsTask.Where(t => t.IsDelete == 1).ToList(); foreach (var item in wcsTasks) { BaseEquip agvEquip = StaticData.BaseEquip.First(t => t.objid == item.nextPointId); if (!string.IsNullOrEmpty(item.taskCode) && !string.IsNullOrEmpty(agvEquip.serverIp)) { dbContext.WcsTask.Remove(item); var cancelTask = new { reqCode = StaticData.SnowId.NextId().ToString(), taskCode = item.taskCode }; string reponse = HttpHelper.SendPostMessage(agvEquip.serverIp, agvEquip.serverPort.Value, "rcms/services/rest/hikRpcService/cancelTask", cancelTask.ToJsonString()); var result = JsonConvert.DeserializeObject(reponse); if (result != null && result.code == "0") { dbContext.SaveChanges(); _logger.Info($"任务{item.taskCode}已删除"); } else { _logger.Error($"任务{item.taskCode}删除失败,原因:{result?.message}"); } } else { dbContext.WcsTask.Remove(item); dbContext.SaveChanges(); _logger.Info($"任务{item.objid}已删除"); } } } catch { } Thread.Sleep(1000); } } private void PlcHearBeat220Logic(object? obj) { BasePlcpoint HeartBeat30 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "putTray"); while (true) { try { StaticData.PlcDic[0].Read(HeartBeat30.plcpointAddress); } catch { try { StaticData.PlcDic[2] = new Plc.S7.Plc(StaticData.PlcDic[2].CPU, StaticData.PlcDic[2].IP, StaticData.PlcDic[2].Port, StaticData.PlcDic[2].Rack, StaticData.PlcDic[2].Slot); StaticData.PlcDic[2].Open(); } catch (Exception ex2) { _logger.Error("Plc短线重连失败" + ex2.Message); } } Thread.Sleep(1000); } } /// /// 定时发送心跳包 /// /// private void PlcHeartBeat30Logic(object? obj) { BasePlcpoint HeartBeat30 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "HeartBeat30"); bool heartBeatCount = false; while (true) { try { heartBeatCount = !heartBeatCount; StaticData.PlcDic[0].WriteToPoint(HeartBeat30.plcpointAddress, heartBeatCount, HeartBeat30.plcpointLength?.ToString()); } catch { try { StaticData.PlcDic[0] = new Plc.S7.Plc(StaticData.PlcDic[0].CPU, StaticData.PlcDic[0].IP, StaticData.PlcDic[0].Port, StaticData.PlcDic[0].Rack, StaticData.PlcDic[0].Slot); StaticData.PlcDic[0].Open(); } catch (Exception ex2) { _logger.Error("Plc短线重连失败" + ex2.Message); } } Thread.Sleep(1000); } } /// /// 定时发送心跳包 /// /// private void PlcHeartBeat31Logic(object? obj) { BasePlcpoint HeartBeat31 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "CTUHeart"); bool heartBeatCount = false; while (true) { try { heartBeatCount = !heartBeatCount; StaticData.PlcDic[1].WriteToPoint(HeartBeat31.plcpointAddress, heartBeatCount, HeartBeat31.plcpointLength?.ToString()); } catch (Exception ex) { if (ex is PlcException) { try { StaticData.PlcDic[1] = new Plc.S7.Plc(StaticData.PlcDic[1].CPU, StaticData.PlcDic[1].IP, StaticData.PlcDic[1].Port, StaticData.PlcDic[1].Rack, StaticData.PlcDic[1].Slot); StaticData.PlcDic[1].Open(); } catch (Exception ex2) { _logger.Error("Plc短线重连失败" + ex2.Message); } } else { _logger.Error(ex.Message + "\n" + ex.StackTrace); } } Thread.Sleep(1000); } } /// /// 定时更新基础设备信息 /// /// private void BaseEquipLogic(object? obj) { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); while (true) { try { dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); List updateEquips = dbContext.BaseEquip.Where(t => t.remark == "99").ToList(); if (updateEquips.Count > 0) { foreach (var equip in updateEquips) { equip.remark = "0"; dbContext.BaseEquip.Update(equip); dbContext.SaveChanges(); } StaticData.BaseEquip = dbContext.BaseEquip.ToList(); } } catch { } Thread.Sleep(5000); } } /// /// 定时同步消息 /// /// private void MessageSynchronousLogic(object? obj) { while (true) { try { HositerLogic(); CtuLineLogic(); ThirdAgvLogic(); FiveAgvLogic(); FiveBearAgvLogic(); CtuCmdLogic(); SecondAgvLogic(); SendTrayMessage(); UpdatePlcPointValue(); } catch (Exception ex) { if (ex is PlcException) { } else { _logger.Error(ex.Message + "\n" + ex.StackTrace); } } Thread.Sleep(1000); } } private void SendTrayMessage() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); BaseEquip baseEquip = dbContext.BaseEquip.First(t => t.objid == 40); BasePlcpoint oneInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneIn"); BasePlcpoint oneOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut"); BasePlcpoint someOutPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut"); BasePlcpoint someInPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someIn"); BasePlc basePlc = StaticData.basePlcs.First(t => t.Name == "托盘库去向"); BasePlc basePlc2 = StaticData.basePlcs.First(t => t.Name == "托盘库数量"); string? value = "0"; if (StaticData.PlcDic[0].Read(oneInPoint.plcpointAddress)?.ToString() == "1") { value = "1"; } else if (StaticData.PlcDic[0].Read(oneOutPoint.plcpointAddress)?.ToString() == "1") { value = "2"; } else if (StaticData.PlcDic[0].Read(someOutPoint.plcpointAddress)?.ToString() == "1") { value = "3"; } else if (StaticData.PlcDic[0].Read(someInPoint.plcpointAddress)?.ToString() == "1") { value = "4"; } StaticData.PlcDic[2].WriteToPoint(basePlc.Address, value, basePlc.type); StaticData.PlcDic[2].WriteToPoint(basePlc2.Address, baseEquip.emptyCount.ToString(), basePlc2.type); } private void UpdatePlcPointValue() { try { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); foreach (var item in StaticData.basePlcs) { item.Value = StaticData.PlcDic[2].Read(item.Address)?.ToString(); } dbContext.UpdateRange(StaticData.basePlcs); dbContext.SaveChanges(); } catch { } } /// /// 定时更新三楼AGV信息 /// /// private void ThirdAgvLogic() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var baseEquip = StaticData.BaseEquip.First(t => t.objid == 9); dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var basePlcs = StaticData.basePlcs.Where(t => t.Station == "3楼AGV").ToList(); var data = new { reqCode = StaticData.SnowId.NextId(), mapCode = "BB" }; string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString()); var reponse = JsonConvert.DeserializeObject(result); if (reponse != null && reponse.code == "0") { var cardStatus = reponse.data.First(t => t.RobotCode == "2032"); cardStatus.DateNow = DateTime.Now; dbContext.Update(cardStatus); dbContext.SaveChanges(); var quantityPlc = basePlcs.First(t => t.Name.Contains("电量")); this.Plc220.WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type); var XPlc = basePlcs.First(t => t.Name.Contains('X')); var Ylc = basePlcs.First(t => t.Name.Contains('Y')); this.Plc220.WriteToPoint(XPlc.Address, cardStatus.PosY.ToString(), XPlc.type); this.Plc220.WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type); } } /// /// 定时更新二楼AGV信息 /// /// private void SecondAgvLogic() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var baseEquip = StaticData.BaseEquip.First(t => t.objid == 8); dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var basePlcs = StaticData.basePlcs.Where(t => t.Station == "2楼AGV").ToList(); var data = new { reqCode = StaticData.SnowId.NextId(), mapCode = "CC" }; string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString()); var reponse = JsonConvert.DeserializeObject(result); if (reponse != null && reponse.code == "0") { var cardStatus = reponse.data.First(t => t.RobotCode == "2033"); cardStatus.DateNow = DateTime.Now; dbContext.Update(cardStatus); dbContext.SaveChanges(); var quantityPlc = basePlcs.First(t => t.Name.Contains("电量")); this.Plc220.WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type); var XPlc = basePlcs.First(t => t.Name.Contains('X')); var Ylc = basePlcs.First(t => t.Name.Contains('Y')); this.Plc220.WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type); this.Plc220.WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type); } } /// /// 定时更新五楼AGV信息 /// /// private void FiveAgvLogic() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var baseEquip = StaticData.BaseEquip.First(t => t.objid == 10); dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼AGV").ToList(); List type = new List() { 27, 28, 34, 35, 37, 38, 46, 47 }; var wcsCmds = dbContext.WcsCmd.Where(t => type.Contains(t.cmdType)).ToList(); if (wcsCmds.Count > 0) { WcsCmd wcsCmd = wcsCmds.First(); var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First(); Plc220.WriteToPoint(endPlc.Address, wcsCmd.nextPointId.ToString(), endPlc.type); var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.cmdType).ToPlc; Plc220.WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type); } else { var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First(); this.Plc220.WriteToPoint(endPlc.Address, "0", endPlc.type); var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, "0", startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); Plc220.WriteToPoint(cmdPlc.Address, "0", cmdPlc.type); } var data = new { reqCode = StaticData.SnowId.NextId(), mapCode = "EE" }; string result = HttpHelper.SendPostMessage(baseEquip.serverIp, baseEquip.serverPort.Value, "rcms-dps/rest/queryAgvStatus", data.ToJsonString()); var reponse = JsonConvert.DeserializeObject(result); if (reponse != null && reponse.code == "0") { var cardStatus = reponse.data.First(t => t.RobotCode == "2034"); cardStatus.DateNow = DateTime.Now; dbContext.Update(cardStatus); var quantityPlc = basePlcs.First(t => t.Name.Contains("电量")); this.Plc220.WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type); var XPlc = basePlcs.First(t => t.Name.Contains('X')); var Ylc = basePlcs.First(t => t.Name.Contains('Y')); this.Plc220.WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type); this.Plc220.WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type); basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼背负式").ToList(); cardStatus = reponse.data.First(t => t.RobotCode == "6011"); cardStatus.DateNow = DateTime.Now; quantityPlc = basePlcs.First(t => t.Name.Contains("电量")); this.Plc220.WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type); XPlc = basePlcs.First(t => t.Name.Contains('X')); Ylc = basePlcs.First(t => t.Name.Contains('Y')); this.Plc220.WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type); this.Plc220.WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type); dbContext.Update(cardStatus); basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼CTU").ToList(); cardStatus = reponse.data.First(t => t.RobotCode == "8161"); cardStatus.DateNow = DateTime.Now; quantityPlc = basePlcs.First(t => t.Name.Contains("电量")); this.Plc220.WriteToPoint(quantityPlc.Address, cardStatus.Battery, quantityPlc.type); XPlc = basePlcs.First(t => t.Name.Contains("X")); Ylc = basePlcs.First(t => t.Name.Contains("Y")); this.Plc220.WriteToPoint(XPlc.Address, cardStatus.PosX.ToString(), XPlc.type); this.Plc220.WriteToPoint(Ylc.Address, cardStatus.PosY.ToString(), Ylc.type); dbContext.Update(cardStatus); dbContext.SaveChanges(); } } /// /// 定时更新五楼背负式AGV信息 /// /// private void FiveBearAgvLogic() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var baseEquip = StaticData.BaseEquip.First(t => t.objid == 10); dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼背负式").ToList(); var wcsCmds = dbContext.WcsCmd.Where(t => t.cmdType == 32 || t.cmdType == 48).ToList(); if (wcsCmds.Count > 0) { WcsCmd wcsCmd = wcsCmds.First(); var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First(); Plc220.WriteToPoint(endPlc.Address, wcsCmd.nextPointId.ToString(), endPlc.type); var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.cmdType).ToPlc; Plc220.WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type); } else { var endPlc = basePlcs.Where(t => t.Name.Contains("目的地")).First(); this.Plc220.WriteToPoint(endPlc.Address, "0", endPlc.type); var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, "0", startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); Plc220.WriteToPoint(cmdPlc.Address, "0", cmdPlc.type); } } /// /// 定时更新五楼CTU信息 /// /// private void CtuCmdLogic() { using var scope = host.Services.CreateScope(); using var dbContext = scope.ServiceProvider.GetRequiredService(); var baseEquip = StaticData.BaseEquip.First(t => t.objid == 11); dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload()); var basePlcs = StaticData.basePlcs.Where(t => t.Station == "5楼CTU").ToList(); var wcsCmds = dbContext.WcsCmd.Where(t => t.cmdType == 29 || t.cmdType == 30 || t.cmdType == 31).ToList(); if (wcsCmds.Count > 0) { var wcsCmd = wcsCmds.First(); List startList = new List(); List endList = new List(); if (wcsCmd.cmdType != 30) { startList.Add(wcsCmd.currPointId); endList.AddRange(wcsCmds.Select(t => t.nextPointId).ToList()); } else { startList.Add(wcsCmd.nextPointId); endList.AddRange(wcsCmds.Select(t => t.currPointId).ToList()); } while (endList.Count < 6) { endList.Add(0); } var endPlcs = basePlcs.Where(t => t.Name.Contains("目的地")).OrderBy(t => t.Name).ToList(); for (int i = 0; i < endPlcs.Count; i++) { this.Plc220.WriteToPoint(endPlcs[i].Address, endList[i].ToString(), endPlcs[i].type); } var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, wcsCmd.currPointId.ToString(), startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); string cmdType = StaticData.BaseDictionary.First(t => t.objid == wcsCmd.cmdType).ToPlc; Plc220.WriteToPoint(cmdPlc.Address, cmdType, cmdPlc.type); } else { var endPlcs = basePlcs.Where(t => t.Name.Contains("目的地")).OrderBy(t => t.Name).ToList(); for (int i = 0; i < endPlcs.Count; i++) { this.Plc220.WriteToPoint(endPlcs[i].Address, "0", endPlcs[i].type); } var startPlc = basePlcs.First(t => t.Name.Contains("起始点")); Plc220.WriteToPoint(startPlc.Address, "0", startPlc.type); var cmdPlc = basePlcs.First(t => t.Name.Contains("任务代号")); Plc220.WriteToPoint(cmdPlc.Address, "0", cmdPlc.type); } } /// /// 定时更新五楼U型线信息 /// private void CtuLineLogic() { var basePlcpoints = StaticData.BasePlcpointList.ToList(); var basePlcs = StaticData.basePlcs.ToList(); var bill = from a in basePlcpoints from b in basePlcs where a.plcpointNo == b.Name && b.Station == "U型线" select new { a, b }; foreach (var item in bill) { if (item.a.plcpointNo.Contains("RFID")) { string? rfid = Plc31.ReadRFID(item.a.plcpointAddress); if (!string.IsNullOrEmpty(rfid)) { rfid = rfid[(rfid.IndexOf("C") + 1)..]; Plc220.WriteToPoint(item.b.Address, rfid, item.b.type); } else { Plc220.WriteToPoint(item.b.Address, "0", item.b.type); } } else { var value = Plc31.Read(item.a.plcpointAddress); if (value != null && !string.IsNullOrEmpty(value.ToString())) { Plc220.WriteToPoint(item.b.Address, value.ToString(), item.b.type); } else { Plc220.WriteToPoint(item.b.Address, "0", item.b.type); } } } } /// /// 提升机和接驳位信息同步 /// private void HositerLogic() { var basePlcpoints = StaticData.BasePlcpointList.ToList(); var basePlcs = StaticData.basePlcs.ToList(); var bill = from a in basePlcpoints from b in basePlcs where a.plcpointNo == b.Name && b.Station != "U型线" select new { a, b }; foreach (var item in bill) { if (item.a.plcpointNo.Contains("RFID")) { string? rfid = Plc30.ReadRFID(item.a.plcpointAddress); if (!string.IsNullOrEmpty(rfid)) { rfid = rfid[(rfid.IndexOf("JYHB") + 4)..]; Plc220.WriteToPoint(item.b.Address, rfid, item.b.type); } else { Plc220.WriteToPoint(item.b.Address, "0", item.b.type); } } else { var value = Plc30.Read(item.a.plcpointAddress); if (value != null && !string.IsNullOrEmpty(value.ToString())) { Plc220.WriteToPoint(item.b.Address, value.ToString(), item.b.type); } else { Plc220.WriteToPoint(item.b.Address, "0", item.b.type); } } } } } }