diff --git a/src/Khd.Core.Domain/Models/PlcPoint.cs b/src/Khd.Core.Domain/Models/PlcPoint.cs new file mode 100644 index 0000000..e4b56b8 --- /dev/null +++ b/src/Khd.Core.Domain/Models/PlcPoint.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Domain.Models +{ + [Table("Plc_Point")] + public class PlcPoint + { + [Column("id")] + public int Id { get; set; } + + [Column("plcpoint_no")] + public string PlcPoint_No { get; set; } + + [Column("plcpoint_name")] + public string PlcPoint_Name { get; set; } + + [Column("plcpoint_address")] + public string PlcPoint_Address { get; set; } + + [Column("equipment_no")] + public string Equipment_No { get; set; } + + [Column("floor_no")] + public int Floor_No { get; set; } + + [Column("plc_code")] + public int Plc_Code { get; set; } + } +} diff --git a/src/Khd.Core.EntityFramework/DefaultDbContext.cs b/src/Khd.Core.EntityFramework/DefaultDbContext.cs index fbdb7de..4a2e0da 100644 --- a/src/Khd.Core.EntityFramework/DefaultDbContext.cs +++ b/src/Khd.Core.EntityFramework/DefaultDbContext.cs @@ -93,6 +93,6 @@ namespace Khd.Core.EntityFramework public DbSet WmsWarehouseMaterial { get; set; } public DbSet WcsOutstockLock { get; set; } public DbSet MesBaseBarcodeInfo { get; set; } - + public DbSet PlcPoint { get; set; } } } \ No newline at end of file diff --git a/src/Khd.Core.Wcs/Global/PlcConfig.cs b/src/Khd.Core.Wcs/Global/PlcConfig.cs index ec5013e..37a3ce7 100644 --- a/src/Khd.Core.Wcs/Global/PlcConfig.cs +++ b/src/Khd.Core.Wcs/Global/PlcConfig.cs @@ -11,7 +11,7 @@ } public static class ConnectionStrings { - public static string ConnectionString { get; set; } + public static string? ConnectionString { get; set; } } public class CommonLock { diff --git a/src/Khd.Core.Wcs/Global/StaticData.cs b/src/Khd.Core.Wcs/Global/StaticData.cs index 1937eba..0280b03 100644 --- a/src/Khd.Core.Wcs/Global/StaticData.cs +++ b/src/Khd.Core.Wcs/Global/StaticData.cs @@ -43,7 +43,8 @@ namespace Khd.Core.Wcs.Global public static List WcsInWareOrder = new List(); public static List WcsOutWareOrder = new List(); - public static List PlcConfigs { get; internal set; } + public static List PlcConfigs { get; set; } + public static Dictionary> PlcPoints = new Dictionary>(); public static Dictionary PlcDic = new Dictionary(); public static JcSnowId SnowId = new JcSnowId(); } diff --git a/src/Khd.Core.Wcs/MainCentralControl.cs b/src/Khd.Core.Wcs/MainCentralControl.cs index e312f81..3b60008 100644 --- a/src/Khd.Core.Wcs/MainCentralControl.cs +++ b/src/Khd.Core.Wcs/MainCentralControl.cs @@ -1,7 +1,7 @@ using Khd.Core.EntityFramework; using Khd.Core.Plc.S7; using Khd.Core.Wcs.Global; -using Khd.Core.Wcs.Wcs; +using Khd.Core.Wcs.MyWcs; using Masuit.Tools.Logging; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -15,60 +15,65 @@ namespace Khd.Core.Wcs public static object WcsMoRenQuXiang = 1; private readonly IHost _host; + + /// + /// 构造函数 + /// + /// public MainCentralControl(IHost host) { this._host = host; } + + /// + /// 启动程序 + /// public void Start() { try { - using (var scope = _host.Services.CreateScope()) + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + StaticData.PlcPoints = dbContext.PlcPoint.GroupBy(t => t.Floor_No).ToDictionary(t => t.Key, t => t.ToDictionary(t => t.PlcPoint_No, t => t)); + //设置程序启动时清空点位的数据=>0为 Int16位 + QingKongDianWei = GetValue("2", "0"); + //设置默认处理完成=>1为 Int16位 + WcsChuLiWanCheng = GetValue("2", "1"); + //设置默认去向=>1为 Int16位 + WcsMoRenQuXiang = GetValue("2", "1"); + + StaticData.BasePlcpointList = dbContext.BasePlcpoint.Where(t => t.isDelete == 0).ToList(); + var baseEquips = dbContext.BaseEquip.ToList(); + //加载配置项 + foreach (var plcConfig in StaticData.PlcConfigs) { - using (var dbContext = scope.ServiceProvider.GetRequiredService()) + if (!StaticData.PlcDic.Any(t => t.Key == plcConfig.Code)) { - //设置程序启动时清空点位的数据=>0为 Int16位 - QingKongDianWei = GetValue("2", "0"); - //设置默认处理完成=>1为 Int16位 - WcsChuLiWanCheng = GetValue("2", "1"); - //设置默认去向=>1为 Int16位 - WcsMoRenQuXiang = GetValue("2", "1"); - - StaticData.BasePlcpointList = dbContext.BasePlcpoint.Where(t => t.isDelete == 0).ToList(); - - //加载配置项 - foreach (var plcConfig in StaticData.PlcConfigs) + var plc = new Plc.S7.Plc((CpuType)plcConfig.CpuType, plcConfig.IP, plcConfig.Port, plcConfig.Rack, plcConfig.Slot); + plc.Open(); + StaticData.PlcDic.TryAdd(plcConfig.Code, plc); + } + } + //连接PLC判断 + foreach (var item in baseEquips) + { + if (item.floorNo != null) + { + if (item.equipType == 1) { - if (!StaticData.PlcDic.Any(t => t.Key == plcConfig.Code)) - { - var plc = new Plc.S7.Plc((CpuType)plcConfig.CpuType, plcConfig.IP, plcConfig.Port, plcConfig.Rack, plcConfig.Slot); - plc.Open(); - StaticData.PlcDic.TryAdd(plcConfig.Code, plc); - } + DockingPositionLogic dockingPositionLogic = new(item.floorNo.Value, item, _host, StaticData.PlcDic[0]); + dockingPositionLogic.Start(); } - //连接PLC判断 - try + else if (item.equipType == 2) { - //一楼调度线程 - var firstFloor = new FirstFloor(this._host, StaticData.PlcDic[0], "一楼输送线"); - firstFloor.StartPoint(); - Console.WriteLine(DateTime.Now+":一楼调度线程开启!"); - - //二楼楼调度线程 - - //三楼调度线程 - - //四楼调度线程 - - //五楼调度线程 + ElevatorLogic elevatorLogic = new(item.floorNo.Value, item, _host, StaticData.PlcDic[0]); + elevatorLogic.Start(); } - catch (Exception ex) + else if (item.equipType == 4 || item.equipType == 5) { - Console.WriteLine(ex.Message); - LogManager.Info($"程序启动失败 >>> {ex.Message}"); - return; + AgvTaskLogic agvTaskLogic = new(item.floorNo.Value, item, baseEquips.First(t => t.equipType == 1 && t.floorNo == item.floorNo), _host, StaticData.PlcDic[0]); + agvTaskLogic.Start(); } - } } } diff --git a/src/Khd.Core.Wcs/MyWcs/AgvTaskLogic.cs b/src/Khd.Core.Wcs/MyWcs/AgvTaskLogic.cs new file mode 100644 index 0000000..a5d39a9 --- /dev/null +++ b/src/Khd.Core.Wcs/MyWcs/AgvTaskLogic.cs @@ -0,0 +1,282 @@ +using Khd.Core.Domain.Dto.webapi; +using Khd.Core.Domain.Models; +using Khd.Core.EntityFramework; +using Khd.Core.Wcs.Global; +using Masuit.Tools.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Wcs.MyWcs +{ + /// + /// AGV任务逻辑 + /// + public class AgvTaskLogic + { + private readonly Dictionary _plcPoints; + private readonly Plc.S7.Plc _plc; + private readonly int _floorNo; + private readonly BaseEquip _baseEquip; + private readonly IHost _host; + private readonly BaseEquip _lineEquip; + + /// + /// 构造函数 + /// + /// 楼层号 + /// 基站设备 + /// 线路设备 + /// IHost + /// Plc + public AgvTaskLogic(int FloorNo, BaseEquip baseEquip, BaseEquip lineEquip, IHost host, Plc.S7.Plc plc) + { + _plc = plc; + _floorNo = FloorNo; + _baseEquip = baseEquip; + _lineEquip = lineEquip; + _host = host; + _plcPoints = StaticData.PlcPoints[FloorNo]; + } + + /// + /// 启动AGV任务逻辑 + /// + public void Start() + { + Thread ExecuteLogicThread = new(ExecuteTaskLogic) + { + IsBackground = true + }; + ExecuteLogicThread.Start(); + + Thread ContinueLogicThread = new(ContinueTaskLogic) + { + IsBackground = true + }; + ContinueLogicThread.Start(); + Console.WriteLine($"{DateTime.Now}:{this._floorNo}楼Agv任务逻辑启动成功"); + LogManager.Info($"{this._floorNo}楼Agv任务逻辑启动成功"); + } + + /// + /// 执行AGV任务逻辑 + /// + private void ExecuteTaskLogic() + { + while (true) + { + try + { + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + var wcsTask = dbContext.WcsTask + .Where(t => t.floorNo == _floorNo) + .Where(t => t.nextPointId == _baseEquip.objid) + .OrderBy(t => t.createTime) + .FirstOrDefault(); + if (wcsTask != null && wcsTask.taskStatus == 0)//未执行的任务 + { + if (wcsTask.taskType % 2 == 1)//入库 + { + var wmsBaseLocations = dbContext.WmsBaseLocation + .Where(t => t.activeFlag == "1") + .Where(t => t.delFlag == "0") + .Where(t => t.instockFlag == "0") + .Where(t => t.locationScrapType == "1") + .Where(t => t.locationStatus == "1") + .Where(t => t.outstockFlag == "0") + .Where(t => t.warehouseId == wcsTask.endPointId).ToList(); + if (wmsBaseLocations.Count > 0) + { + var wmsBaseLocation = wmsBaseLocations.First(); + wcsTask.endPointId = wmsBaseLocation.locationId; + wcsTask.endPointNo = wmsBaseLocation.locationCode; + var request = new RequestAGVTaskDto() + { + reqCode = wcsTask.objid.ToString(), + taskMode = "2", + positionCodePath = new List + { + new Position + { + podCode=_lineEquip.equipNo + }, + new Position + { + podCode=wmsBaseLocation.agvPositionCode + } + } + }; + var reponse = SendTask(request); + if (reponse != null) + { + if (reponse.message == "成功") + { + LogManager.Info("AGV任务执行成功,任务ID:" + wcsTask.objid); + wcsTask.taskStatus = 1; + wcsTask.updateTime = DateTime.Now; + wmsBaseLocation.instockFlag = "1"; + wmsBaseLocation.locationStatus = "2"; + dbContext.Update(wmsBaseLocation); + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + } + else + { + LogManager.Debug("AGV任务执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message); + } + } + } + } + else//出库 + { + var request = new RequestAGVTaskDto() + { + reqCode = wcsTask.objid.ToString(), + taskMode = "2", + positionCodePath = new List + { + new Position + { + podCode=wcsTask.startPointNo + }, + new Position + { + podCode=wcsTask.nextPointNo + } + } + }; + var reponse = SendTask(request); + if (reponse != null) + { + if (reponse.message == "成功") + { + LogManager.Info("AGV任务执行成功,任务ID:" + wcsTask.objid); + var wmsBaseLocations = dbContext.WmsBaseLocation.Where(t => t.agvPositionCode == wcsTask.startPointNo).ToList(); + foreach (var item in wmsBaseLocations) + { + var wmsBaseWarehouse = dbContext.WmsBaseWarehouse.FirstOrDefault(t => t.warehouseId == item.warehouseId); + if (wmsBaseWarehouse != null && wmsBaseWarehouse.warehouseFloor == _floorNo) + { + item.outstockFlag = "1"; + item.locationStatus = "6"; + dbContext.Update(item); + break; + } + } + wcsTask.taskStatus = 1; + wcsTask.updateTime = DateTime.Now; + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + } + else + { + LogManager.Debug("AGV任务执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message); + } + } + } + } + } + catch (Exception ex) + { + LogManager.Error(ex); + } + Thread.Sleep(1000); + } + } + + /// + /// 继续执行AGV任务逻辑 + /// + private void ContinueTaskLogic() + { + while (true) + { + try + { + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + var wcsTask = dbContext.WcsTask + .Where(t => t.floorNo == _floorNo) + .Where(t => t.nextPointId == _baseEquip.objid) + .Where(t=>t.taskStatus==2) + .OrderBy(t => t.createTime) + .FirstOrDefault(); + if (wcsTask != null) + { + var request = new RequestAGVTaskDto(); + request.reqCode = wcsTask.objid.ToString(); + var reponse = ContinueTask(request); + if (reponse != null) + { + if (reponse.message == "成功") + { + LogManager.Info("AGV任务继续执行成功,任务ID:" + wcsTask.objid); + wcsTask.taskStatus = 3; + wcsTask.updateTime = DateTime.Now; + var wmsBaseLocation = dbContext.WmsBaseLocation.FirstOrDefault(t => t.locationId == wcsTask.endPointId); + if (wmsBaseLocation != null) + { + wmsBaseLocation.instockFlag = "0"; + wmsBaseLocation.outstockFlag = "0"; + wmsBaseLocation.locationStatus = "1"; + dbContext.Update(wmsBaseLocation); + } + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + } + else + { + LogManager.Debug("AGV任务继续执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message); + } + } + } + } + catch(Exception ex) + { + LogManager.Error(ex); + } + } + } + + /// + /// 发送任务 + /// + private ReponseagvCallbackDto? SendTask(RequestAGVTaskDto request) + { + if (_baseEquip.serverPort == null) + { + throw new Exception("服务器端口不能为空"); + } + string ip = _baseEquip.serverIp; + int port = _baseEquip.serverPort.Value; + string url = ""; + string message = JsonConvert.SerializeObject(request); + string result = HttpHelper.SendPostMessage(ip, port, url, message); + return JsonConvert.DeserializeObject(result); + } + + /// + /// 继续执行任务 + /// + private ReponseagvcontinueTaskDto? ContinueTask(RequestAGVTaskDto request) + { + if (_baseEquip.serverPort == null) + { + throw new Exception("服务器端口不能为空"); + } + string ip = _baseEquip.serverIp; + int port = _baseEquip.serverPort.Value; + string url = ""; + string message = JsonConvert.SerializeObject(request); + string result = HttpHelper.SendPostMessage(ip, port, url, message); + return JsonConvert.DeserializeObject(result); + } + } +} diff --git a/src/Khd.Core.Wcs/MyWcs/DockingPositionLogic.cs b/src/Khd.Core.Wcs/MyWcs/DockingPositionLogic.cs new file mode 100644 index 0000000..b234495 --- /dev/null +++ b/src/Khd.Core.Wcs/MyWcs/DockingPositionLogic.cs @@ -0,0 +1,194 @@ +using Khd.Core.Domain.Models; +using Khd.Core.EntityFramework; +using Khd.Core.Wcs.Global; +using Masuit.Tools.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Wcs.MyWcs +{ + /// + /// 接驳位逻辑 + /// + public class DockingPositionLogic + { + private readonly int _floorNo; + private readonly Dictionary _dockingPosition; + private readonly Plc.S7.Plc _plc; + private readonly IHost _host; + private readonly BaseEquip _currentEquip; + + /// + /// 构造函数 + /// + /// 楼层号 + /// 当前设备 + /// IHost + /// Plc + public DockingPositionLogic(int floorNo, BaseEquip currentEquip, IHost host, Plc.S7.Plc plc) + { + _floorNo = floorNo; + _host = host; + _plc = plc; + _currentEquip = currentEquip; + _dockingPosition = StaticData.PlcPoints[floorNo]; + } + + /// + /// 启动线程 + /// + public void Start() + { + var ExecuteLogicThread = new Thread(ExecuteLogic); + ExecuteLogicThread.IsBackground = true; + ExecuteLogicThread.Start(); + Console.WriteLine($"{DateTime.Now}:{this._floorNo}楼接驳位线程启动成功"); + LogManager.Info($"{this._floorNo}楼接驳位线程启动成功"); + } + + /// + /// 执行任务 + /// + public void ExecuteLogic() + { + while (true) + { + try + { + var rfid = _plc.Read(_dockingPosition[$"RFID00{_floorNo}"].PlcPoint_Address); + var serialNo = _plc.Read(_dockingPosition[$"SerialNo00{_floorNo}"].PlcPoint_Address); + var isPallet = _plc.Read(_dockingPosition[$"IsPallet00{_floorNo}"].PlcPoint_Address); + var lineSignal = _plc.Read(_dockingPosition[$"LineSignal00{_floorNo}"].PlcPoint_Address); + var wcsRun = _plc.Read(_dockingPosition[$"WcsRun00{_floorNo}"].PlcPoint_Address); + if (rfid != null && serialNo != null && isPallet != null && lineSignal != null && wcsRun != null) + { + if (!string.IsNullOrEmpty(rfid.ToString()) && Convert.ToInt32(isPallet) == 1) + { + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + var wcsTask = dbContext.WcsTask + .Where(t => t.floorNo == _floorNo) + .Where(t => t.containerNo == rfid.ToString()) + .OrderBy(t => t.createTime) + .FirstOrDefault(); + + if (wcsTask == null) + { + var PalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == rfid.ToString()); + if (PalletInfo != null) + { + var WarehouseMaterial = dbContext.WmsWarehouseMaterial.FirstOrDefault(t => t.storageId == PalletInfo.materialId); + if (WarehouseMaterial != null) + { + var BaseWarehouse = dbContext.WmsBaseWarehouse.FirstOrDefault(t => t.warehouseId == WarehouseMaterial.warehouseId); + if (BaseWarehouse != null) + { + if (BaseWarehouse.warehouseFloor == _floorNo) + { + var agvEquip = dbContext.BaseEquip.FirstOrDefault(t => t.floorNo == _floorNo && (t.equipType == 4 || t.equipType == 5)); + if (agvEquip != null) + { + wcsTask = new WcsTask() + { + objid = StaticData.SnowId.NextId(), + floorNo = _floorNo, + containerNo = rfid.ToString(), + createBy = "WCS", + createTime = DateTime.Now, + startPointId = _currentEquip.objid, + startPointNo = _currentEquip.equipNo, + currPointId = _currentEquip.objid, + currPointNo = _currentEquip.equipNo, + taskStatus = 0, + endPointId = BaseWarehouse.warehouseId, + endPointNo = BaseWarehouse.warehouseCode, + equipmentNo = _currentEquip.equipNo, + masterId = null, + materialId = PalletInfo.materialId, + materialNo = PalletInfo.materialCode, + nextPointId = agvEquip.objid, + nextPointNo = agvEquip.equipNo, + taskType = 0, + useFlag = 1 + }; + } + } + else + { + var elevatorEquip = dbContext.BaseEquip.FirstOrDefault(t => t.floorNo == 1 && t.equipType == 2); + if (elevatorEquip != null) + { + wcsTask = new WcsTask() + { + objid = StaticData.SnowId.NextId(), + floorNo = _floorNo, + containerNo = rfid.ToString(), + createBy = "WCS", + createTime = DateTime.Now, + startPointId = _currentEquip.objid, + startPointNo = _currentEquip.equipNo, + currPointId = _currentEquip.objid, + currPointNo = _currentEquip.equipNo, + taskStatus = 0, + endPointId = BaseWarehouse.warehouseId, + endPointNo = BaseWarehouse.warehouseCode, + equipmentNo = _currentEquip.equipNo, + masterId = null, + materialId = PalletInfo.materialId, + materialNo = PalletInfo.materialCode, + nextPointId = elevatorEquip.objid, + nextPointNo = elevatorEquip.equipNo, + taskType = 0, + useFlag = 1 + }; + } + } + } + } + } + }//没有任务,默认入库 + + if (wcsTask != null && wcsTask.taskStatus == 0) + { + var ElevatorEquip = dbContext.BaseEquip.First(t => t.equipType == 2); + var AgvEquip = dbContext.BaseEquip.FirstOrDefault(t => t.floorNo == _floorNo && (t.equipType == 4 || t.equipType == 5)); + if (wcsTask.nextPointId == ElevatorEquip.objid)//下一个为提升机 + { + wcsTask.taskStatus = 1; + wcsTask.currPointId = _currentEquip.objid; + wcsTask.currPointNo = _currentEquip.equipNo; + wcsTask.nextPointId = ElevatorEquip.objid; + wcsTask.nextPointNo = ElevatorEquip.equipNo; + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + _plc.Write(_dockingPosition[$"WcsRun00{_floorNo}"].PlcPoint_Address, 1); + } + else if (AgvEquip != null && wcsTask.nextPointId == AgvEquip.objid)//下一个为AGV,即入库 + { + wcsTask.taskStatus = 0; + wcsTask.currPointId = _currentEquip.objid; + wcsTask.currPointNo = _currentEquip.equipNo; + wcsTask.nextPointId = AgvEquip.objid; + wcsTask.nextPointNo = AgvEquip.equipNo; + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + _plc.Write(_dockingPosition[$"WcsRun00{_floorNo}"].PlcPoint_Address, 2); + } + } + } + } + } + catch (Exception ex) + { + LogManager.Error(ex); + } + Thread.Sleep(1000); + } + } + } +} diff --git a/src/Khd.Core.Wcs/MyWcs/ElevatorLogic.cs b/src/Khd.Core.Wcs/MyWcs/ElevatorLogic.cs new file mode 100644 index 0000000..b4a752b --- /dev/null +++ b/src/Khd.Core.Wcs/MyWcs/ElevatorLogic.cs @@ -0,0 +1,122 @@ +using Khd.Core.Domain.Models; +using Khd.Core.EntityFramework; +using Khd.Core.Wcs.Global; +using Masuit.Tools.Logging; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Wcs.MyWcs +{ + /// + /// 提升机逻辑 + /// + public class ElevatorLogic + { + private readonly Plc.S7.Plc _plc; + private readonly int _floorNo; + private readonly Dictionary ElevatorPoints; + private readonly IHost _host; + private readonly BaseEquip _baseEquip; + + /// + /// 构造函数 + /// + /// 楼层号 + /// 基础设备 + /// IHost + /// Plc + public ElevatorLogic(int FloorNo, BaseEquip baseEquip, IHost host, Plc.S7.Plc plc) + { + _plc = plc; + _floorNo = FloorNo; + _host = host; + _baseEquip = baseEquip; + ElevatorPoints = StaticData.PlcPoints[_floorNo]; + } + + /// + /// 启动提升机逻辑 + /// + public void Start() + { + Thread executeThread = new(ExecuteLogic) + { + IsBackground = true + }; + executeThread.Start(); + Console.WriteLine($"{DateTime.Now}:提升机逻辑启动"); + LogManager.Info("提升机逻辑启动"); + } + + /// + /// 执行逻辑 + /// + public void ExecuteLogic() + { + while (true) + { + try + { + var targetFloor = _plc.Read(ElevatorPoints["ElevatorTargetFloor"].PlcPoint_Address);//目标楼层 + var signal = _plc.Read(ElevatorPoints["ElevatorSignal"].PlcPoint_Address);//到位信号 + var state = _plc.Read(ElevatorPoints["ElevatorState"].PlcPoint_Address);//提升机状态 + var currentFloor = _plc.Read(ElevatorPoints["ElevatorCurrentFloor"].PlcPoint_Address);//提升机当前楼层 + var serialNo = _plc.Read(ElevatorPoints["ElevatorSerialNo"].PlcPoint_Address);//提升机流水号 + var taskState = _plc.Read(ElevatorPoints["ElevatorTaskState"].PlcPoint_Address);//任务状态 + if (targetFloor != null && signal != null && state != null && currentFloor != null && serialNo != null && taskState != null) + { + if (Convert.ToInt32(state) == 0 && Convert.ToInt32(taskState) == 2) + { + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + for (int i = 1; i <= 5; i++) + { + try + { + var elevatorSerialNo = _plc.Read(StaticData.PlcPoints[i][$"ElevatorSerialNo00{i}"].PlcPoint_Address); + var elevatorTake = _plc.Read(StaticData.PlcPoints[i][$"ElevatorTake00{i}"].PlcPoint_Address); + if (elevatorSerialNo != null && elevatorTake != null && Convert.ToInt32(elevatorTake) == 1 && Convert.ToInt64(elevatorSerialNo) > 0) + { + var baseEquip = dbContext.BaseEquip.First(t => t.floorNo == i && t.equipType == 2); + var wcsTask = dbContext.WcsTask.OrderBy(t => t.createTime).FirstOrDefault(t => t.nextPointId == baseEquip.objid && t.taskStatus == 1); + if (wcsTask != null) + { + var endEquip = dbContext.BaseEquip.First(t => t.objid == wcsTask.endPointId); + if (endEquip.floorNo != null) + { + wcsTask.taskStatus = 2; + wcsTask.nextPointId = _baseEquip.objid; + wcsTask.nextPointNo = _baseEquip.equipNo; + _plc.Write(ElevatorPoints["ElevatorCurrentFloor"].PlcPoint_Address, i); + _plc.Write(ElevatorPoints["ElevatorTargetFloor"].PlcPoint_Address, endEquip.floorNo);//写入目的地楼层 + dbContext.Update(wcsTask); + dbContext.SaveChanges(); + LogManager.Info($"提升机下发任务{i}=>{wcsTask.nextPointId}"); + Console.WriteLine($"{DateTime.Now}:提升机下发任务{i}=>{wcsTask.nextPointId}"); + break; + } + } + } + } + catch (Exception e) + { + LogManager.Error($"{i}楼提升机异常", e); + } + } + } + } + } + catch (Exception ex) + { + LogManager.Error(ex); + } + Thread.Sleep(1000); + } + } + } +} diff --git a/src/Khd.Core.Wcs/Program.cs b/src/Khd.Core.Wcs/Program.cs index 5d9ea57..c35db02 100644 --- a/src/Khd.Core.Wcs/Program.cs +++ b/src/Khd.Core.Wcs/Program.cs @@ -9,34 +9,37 @@ using Microsoft.Extensions.Hosting; internal class Program { - public static IHost _host; + private static void Main(string[] args) { - - init(); //初始化加载配置文件 + Init(); //初始化加载配置文件 AppDomain.CurrentDomain.UnhandledException += GlobalExceptionHandler; //全局异常捕获 try { - bool ret; - System.Threading.Mutex mutex = new System.Threading.Mutex(true, "服务端", out ret); + var mutex = new Mutex(true, "服务端", out bool ret); if (ret) { IHost host = CreateHostBuilder(args).Build(); - _host = host; - Console.WriteLine("系统启动开始 :" + DateTime.Now); - LogManager.Info("系统启动开始 "); - MainCentralControl main = new MainCentralControl(host); + + LogManager.Info("系统启动开始"); + Console.WriteLine($"{DateTime.Now}:系统启动开始"); + + MainCentralControl main = new(host); main.Start(); - //while (true) - //{ - // Console.ReadLine(); - //} mutex.ReleaseMutex(); // 释放 Mutex + LogManager.Info("系统启动成功"); + Console.WriteLine($"{DateTime.Now}:系统启动成功"); + + while (true) + { + Console.ReadLine(); + } } else { Console.Write("系统重复开启,请先关闭之前窗口"); + Console.ReadLine(); } } catch (Exception ex) @@ -47,8 +50,7 @@ internal class Program } private static void GlobalExceptionHandler(object sender, UnhandledExceptionEventArgs e) { - Exception exception = e.ExceptionObject as Exception; - if (exception != null) + if (e.ExceptionObject is Exception exception) { Console.WriteLine("全局异常捕获:"); Console.WriteLine(exception.Message); @@ -66,7 +68,7 @@ internal class Program /// /// 初始化加载配置文件 /// - private static void init() + private static void Init() { IConfigurationRoot configuration = new ConfigurationBuilder() .SetBasePath(AppDomain.CurrentDomain.BaseDirectory) @@ -74,14 +76,12 @@ internal class Program .Build(); StaticData.PlcConfigs = configuration.GetSection("PlcConfigs").Get>(); - ConnectionStrings.ConnectionString = configuration["ConnectionStrings:DefaultConnection"].ToString(); + ConnectionStrings.ConnectionString = configuration["ConnectionStrings:DefaultConnection"]; } static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((_, services) => { - //services.AddDbContext(options => - // options.UseSqlServer(ConnectionStrings.ConnectionString)); services.AddDbContext(options => options.UseMySql(ConnectionStrings.ConnectionString, new MySqlServerVersion(new Version(8, 0, 31)))); }); diff --git a/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs index 7a151fe..5201566 100644 --- a/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs +++ b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs @@ -59,7 +59,7 @@ namespace Khd.Core.Wcs.Wcs public void StartPoint() { - Thread FlowPointThread = new Thread(MonitorInLocatorPoint); + var FlowPointThread = new Thread(MonitorInLocatorPoint); FlowPointThread.Start(); } public void MonitorInLocatorPoint() @@ -188,34 +188,37 @@ namespace Khd.Core.Wcs.Wcs dbContext.Add(order); } var dic = StaticData.BaseDictionary.Where(t => t.dicKey == "TaskType" && t.ud1 == "O").FirstOrDefault(); - WcsTask rawTask = new() + if(dic!= null) { - objid = StaticData.SnowId.NextId(), - orderId = item.rawOutstockId, - masterId = orderID, - taskType = Convert.ToInt32(dic.dicValue), - containerNo = "", - taskStatus = 0, - materialId = item.warehouseId, - qty = 1, - startPointId = item.warehouseId, - startPointNo = "", - currPointId = item.warehouseId, - currPointNo = "", - endPointId = item.warehouseId, - endPointNo = "", - }; - dbContext.Add(rawTask); + WcsTask rawTask = new() + { + objid = StaticData.SnowId.NextId(), + orderId = item.rawOutstockId, + masterId = orderID, + taskType = Convert.ToInt32(dic.dicValue), + containerNo = "", + taskStatus = 0, + materialId = item.warehouseId, + qty = 1, + startPointId = item.warehouseId, + startPointNo = "", + currPointId = item.warehouseId, + currPointNo = "", + endPointId = item.warehouseId, + endPointNo = "" + }; + dbContext.Add(rawTask); - //获取最早入库时间 - var firstDate = rawStock.Where(t => t.materialId == item.productId && t.warehouseId == item.warehouseId).OrderBy(t => t.createDate).FirstOrDefault(); + //获取最早入库时间 + var firstDate = rawStock.Where(t => t.materialId == item.productId && t.warehouseId == item.warehouseId).OrderBy(t => t.createDate).FirstOrDefault(); - //回写wms出库记录表 - dbContext.WmsRawOutstock.Where(t => t.rawOutstockId == item.rawOutstockId).Update(t => new WmsProductOutstock() - { - executeStatus = "1", - updateDate = DateTime.Now - }); + //回写wms出库记录表 + dbContext.WmsRawOutstock.Where(t => t.rawOutstockId == item.rawOutstockId).Update(t => new WmsProductOutstock() + { + executeStatus = "1", + updateDate = DateTime.Now + }); + } } } diff --git a/src/Khd.Core.Wcs/Wcs/FirstFloor.cs b/src/Khd.Core.Wcs/Wcs/FirstFloor.cs index 4efbb2e..0e596bc 100644 --- a/src/Khd.Core.Wcs/Wcs/FirstFloor.cs +++ b/src/Khd.Core.Wcs/Wcs/FirstFloor.cs @@ -245,7 +245,7 @@ namespace Khd.Core.Wcs.Wcs task.currPointNo = "F01"; task.nextPointId = T01; task.nextPointNo = "T01"; - task.taskStatus = 1; + task.taskStatus = 0; task.updateBy = "一楼接驳位线程"; task.updateTime = DateTime.Now; task.remark = "一楼创建入库任务";