diff --git a/src/Khd.Core.Api/Controllers/ReceiveProdPlanController.cs b/src/Khd.Core.Api/Controllers/ReceiveProdPlanController.cs index 22b895c..905bf5b 100644 --- a/src/Khd.Core.Api/Controllers/ReceiveProdPlanController.cs +++ b/src/Khd.Core.Api/Controllers/ReceiveProdPlanController.cs @@ -18,19 +18,20 @@ namespace Khd.Core.Api.Controllers [ApiController] public class ReceiveProdPlanController : ControllerBase { - private readonly IMesProdPlanApplication _application; + //private readonly IMesProdPlanApplication _application; - public ReceiveProdPlanController(IMesProdPlanApplication application) - { - _application = application; - } + //public ReceiveProdPlanController(IMesProdPlanApplication application) + //{ + // _application = application; + //} [HttpPost] public ReponseBase SaveProdPlan(RequestInfo model) { LogManager.Info($"收到MES接口信息:{model.ToJsonString()}"); - return _application.SaveProdPlan(model); + //return _application.SaveProdPlan(model); + return null; } } diff --git a/src/Khd.Core.Api/Startup.cs b/src/Khd.Core.Api/Startup.cs index a49089c..afb34be 100644 --- a/src/Khd.Core.Api/Startup.cs +++ b/src/Khd.Core.Api/Startup.cs @@ -66,7 +66,7 @@ namespace Khd.Core.Api .WithMethods("GET", "POST", "PUT", "DELETE", "OPTIONS"); })); - services.AddApplication(); + //services.AddApplication(); services.AddLibrary(); } diff --git a/src/Khd.Core.Application/ApplicationExtensions.cs b/src/Khd.Core.Application/ApplicationExtensions.cs index b3ae082..84271ec 100644 --- a/src/Khd.Core.Application/ApplicationExtensions.cs +++ b/src/Khd.Core.Application/ApplicationExtensions.cs @@ -8,7 +8,7 @@ namespace Khd.Core.Application { public static void AddApplication(this IServiceCollection services) { - services.AddTransient(); + //services.AddTransient(); } } } \ No newline at end of file diff --git a/src/Khd.Core.Wcs/Global/StaticData.cs b/src/Khd.Core.Wcs/Global/StaticData.cs index 14845cf..94377ea 100644 --- a/src/Khd.Core.Wcs/Global/StaticData.cs +++ b/src/Khd.Core.Wcs/Global/StaticData.cs @@ -1,4 +1,4 @@ -using CMS.Model; +//using CMS.Model; using Khd.Core.Domain.Dto.wcs; using Khd.Core.Domain.Models; using System; diff --git a/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj b/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj index 80f3855..386a593 100644 --- a/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj +++ b/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj @@ -9,6 +9,9 @@ + + + diff --git a/src/Khd.Core.Wcs/MainCentralControl.cs b/src/Khd.Core.Wcs/MainCentralControl.cs index 4cace03..e443e72 100644 --- a/src/Khd.Core.Wcs/MainCentralControl.cs +++ b/src/Khd.Core.Wcs/MainCentralControl.cs @@ -33,6 +33,14 @@ namespace Khd.Core.Wcs { try { + for (int i = 0; i < 20; i++) + { + + var d = new SnowflakeIdGenerator(1,2); + long ww = d.GenerateId(); + Console.WriteLine(ww); + Thread.Sleep(10); + } using (var scope = _host.Services.CreateScope()) { using (var dbContext = scope.ServiceProvider.GetRequiredService()) diff --git a/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs new file mode 100644 index 0000000..a2ca3ad --- /dev/null +++ b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs @@ -0,0 +1,127 @@ +using AngleSharp.Dom; +using Khd.Core.Domain.Dto.wcs; +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 Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Khd.Core.Domain.Dto.webapi; + +using Khd.Core.Plc.S7; + +using Khd.Core.Wcs.Wcs; +using System.Data; +using Microsoft.EntityFrameworkCore; +using Z.EntityFramework.Plus; +using Masuit.Tools; +using Microsoft.IdentityModel.Tokens; + +namespace Khd.Core.Wcs.Wcs +{ + /// + /// 根据出入库记录创建出入库任务 + /// + public class CreateTaskByRecord + { + private readonly IHost _host; + private readonly Plc.S7.Plc _plc; + List ScanPoint { get; set; }//点位信息 + BaseSitenode? sitenode { get; set; }//站台信息 + + NodeSetting? NodeSettingCarNo { get; set; } + NodeSetting? NodeSettingCarState { get; set; } + NodeSetting? NodeSettingCarRun { get; set; } + NodeSetting? NodeSettingWcsState { get; set; } + NodeSetting? NodeSettingWcsSend { get; set; } + NodeSetting? NodeSettingWcsSendMaterial { get; set; } + NodeSetting? NodeSettingPLCSendSendMaterialstate { get; set; } + Thread FlowPointThread; + public CreateTaskByRecord(IHost host, Plc.S7.Plc plc, string siteNo) + { + this._host = host; + this._plc = plc; + this.ScanPoint = StaticData.BasePlcpointList.ToList();//加载当前站点所对应的点位 + this.sitenode = StaticData.SiteNodeList.FirstOrDefault(t => t.siteNo == siteNo);//获取当前站台信息 + //this.NodeSettingCarNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carno")); + //this.NodeSettingCarState = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carstate")); + //this.NodeSettingCarRun = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carrun")); + //this.NodeSettingWcsState = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("plcsendK")); + //this.NodeSettingWcsSend = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("wcsend")); + //this.NodeSettingWcsSendMaterial = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("wcssendmessage")); + //this.NodeSettingPLCSendSendMaterialstate = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("plcsendmessage")); + try + { + //默认启动,清理plc的上位机写入点位值 + //this._plc.Write(NodeSettingCarRun.plcpointAddress, MainCentralControl.QingKongDianWei); + //this._plc.Write(NodeSettingWcsSend.plcpointAddress, MainCentralControl.QingKongDianWei); + //this._plc.Write(NodeSettingWcsSendMaterial.plcpointAddress, MainCentralControl.QingKongDianWei); + } + catch (Exception ex) + { + Console.WriteLine("站点" + siteNo + " 初始化数据异常" + ex.Message); + LogManager.Error(ex); + } + } + /// + /// 启动上件扫描监听 + /// + public void StartPoint() + { + + FlowPointThread = new Thread(MonitorInLocatorPoint); + FlowPointThread.Start(); + } + public void MonitorInLocatorPoint() + { + while (true) + { + try + { + CreateTask(); + } + catch (Exception ex) + { + LogManager.Error(ex); + } + finally + { + Thread.Sleep(2000); + } + } + } + + private void CreateTask() + { + try + { + using var scope = _host.Services.CreateScope(); + using var dbContext = scope.ServiceProvider.GetRequiredService(); + var rawInstock = dbContext.WcsTask.Where(t => t.customerNo == "1" ).ToList(); + if (rawInstock.Count>0) + { + foreach (var item in rawInstock) + { + WcsTask wcsTask = new WcsTask(); + //wcsTask.customerNo = item.palletInfoCode; + dbContext.Add(wcsTask); + dbContext.SaveChanges(); + } + + } + } + catch (Exception ex) + { + //LogManager.Info($"错误日志输出 >>> OutWarePoint类 WriteMaterialMessage 方法报错 {ex}"); + LogManager.Error(ex); + } + + } + } +} diff --git a/src/Khd.Core.Wcs/Wcs/FlowPoint.cs b/src/Khd.Core.Wcs/Wcs/FlowPoint.cs index 7200cb2..934342e 100644 --- a/src/Khd.Core.Wcs/Wcs/FlowPoint.cs +++ b/src/Khd.Core.Wcs/Wcs/FlowPoint.cs @@ -43,7 +43,7 @@ namespace Khd.Core.Wcs.Wcs { this._host = host; this._plc = plc; - this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 + //this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 this.sitenode = StaticData.SiteNodeList.FirstOrDefault(t => t.siteNo == siteNo);//获取当前站台信息 this.NodeSettingCarNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carno")); this.NodeSettingCarState = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carstate")); @@ -200,7 +200,7 @@ namespace Khd.Core.Wcs.Wcs } else if (siteNo == "K18") { - dbContext.BaseWaitdownline.Where(t => t.carNo == carno).Update(a => new BaseWaitdownline() { downline = 0 }); //修改车辆状态为未上线 (修改downline字段等于0) + //dbContext.BaseWaitdownline.Where(t => t.carNo == carno).Update(a => new BaseWaitdownline() { downline = 0 }); //修改车辆状态为未上线 (修改downline字段等于0) //flag == 2 上件点闸口正常时写弯通2,挂具返回上件点, //flag == 1上件点闸口人工维护损坏时写直通1,挂具返回K22流转点; var flag = GetFlag(1, "UpState"); diff --git a/src/Khd.Core.Wcs/Wcs/OutWarePoint.cs b/src/Khd.Core.Wcs/Wcs/OutWarePoint.cs index fb2827f..353019c 100644 --- a/src/Khd.Core.Wcs/Wcs/OutWarePoint.cs +++ b/src/Khd.Core.Wcs/Wcs/OutWarePoint.cs @@ -47,7 +47,7 @@ namespace Khd.Core.Wcs.Wcs { this._host = host; this._plc = plc; - this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 + //this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 this.sitenode = StaticData.SiteNodeList.FirstOrDefault(t => t.siteNo == siteNo);//获取当前站台信息 this.NodeSettingCarNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carno")); this.NodeSettingCarState = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carstate")); diff --git a/src/Khd.Core.Wcs/Wcs/SecondFloor.cs b/src/Khd.Core.Wcs/Wcs/SecondFloor.cs new file mode 100644 index 0000000..2fb629e --- /dev/null +++ b/src/Khd.Core.Wcs/Wcs/SecondFloor.cs @@ -0,0 +1,135 @@ +using Khd.Core.Domain.Models; +using Khd.Core.Wcs.Global; +using Masuit.Tools.Logging; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Wcs.Wcs +{ + /// + /// 二楼调度 + /// + public class SecondFloor + { + List ScanPoint { get; set; }//点位信息 + private readonly IHost _host; + private readonly Plc.S7.Plc _plc; + BasePlcpoint? LineRFID { get; set; } + BasePlcpoint? LineWcsrun { get; set; } + BasePlcpoint? LineSignal { get; set; } + BasePlcpoint? LineIsPallet { get; set; } + BasePlcpoint? LineSerialNO { get; set; } + BasePlcpoint? LineFeedSeriaNo { get; set; } + Thread FlowPointThread; + int FloorNo { get; set; } + public SecondFloor(IHost host, Plc.S7.Plc plc, int floor) + { + this._host = host; + this._plc = plc; + FloorNo = floor; + this.ScanPoint = StaticData.BasePlcpointList.Where(t=>t.floorNo== floor).ToList();//加载当前站点所对应的点位 + this.LineRFID = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("RFID")); + this.LineWcsrun = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("wcsrun")); + this.LineSignal = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("linesignal")); + this.LineIsPallet = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("ispallet")); + this.LineSerialNO = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("serialno")); + this.LineFeedSeriaNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("feedserialno")); + + //var lineRFID = this._plc.Read(NodeSettingCarNo.plcpointAddress); + try + { + //默认启动,清理plc的上位机写入点位值 + this._plc.Write(LineRFID.plcpointAddress, MainCentralControl.QingKongDianWei); + } + catch (Exception ex) + { + Console.WriteLine("楼层" + floor + " 初始化数据异常" + ex.Message); + LogManager.Error(ex); + } + } + /// + /// 启动上件扫描监听 + /// + public void StartPoint() + { + + FlowPointThread = new Thread(MonitorInLocatorPoint); + FlowPointThread.Start(); + } + + public void MonitorInLocatorPoint() + { + while (true) + { + try + { + var rfid = this._plc.Read(LineRFID.plcpointAddress); + var isSignal = this._plc.Read(LineSignal.plcpointAddress); + var isPallet = this._plc.Read(LineIsPallet.plcpointAddress); + if (rfid != null && isSignal != null && isPallet != null ) + { + //正常读到输送线信息 有到位信号,并且有托盘,获取条码信息 + if (Convert.ToInt32(isSignal) > 0 && Convert.ToInt32(isPallet) == 1) + { + //获取条码信息 + var palletNo = Convert.ToString(rfid); + //var carRun = GetTask(palletNo, FloorNo); + //if (string.IsNullOrEmpty(carRun)) + //{ + // Console.WriteLine($" FlowPoint类GetTargetTo方法去向返回{carRun},查看错误日志内容!"); + // Thread.Sleep(1000); + // continue; + //} + //var ToInt16carRun = MainCentralControl.getValue("2", carRun); + } + } + } + catch (Exception ex) + { + LogManager.Error(ex); + } + finally + { + Thread.Sleep(1000); + } + } + } + + public string GetTask(string customerNo,int floorNo,string equipNo) + { + //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv + var task = StaticData.WcsTask.Where(t => t.customerNo == customerNo).FirstOrDefault(); + if (task == null) + { + var palletInfo = StaticData.MesBasePalletInfo.Where(t => t.palletInfoCode == customerNo).FirstOrDefault(); + //查询该条码绑定的物料信息 + var material = StaticData.WmsWarehouseMaterial.Where(t=>t.storageId== palletInfo.materialId).FirstOrDefault(); + var wareHouse = StaticData.WmsBaseWarehouse.Where(t => t.warehouseId == material.warehouseId).FirstOrDefault(); + var dic = StaticData.BaseDictionary.Where(t=>t.dicKey== "TaskType" && t.ud1 == "I" && t.dicField== wareHouse.warehouseInstockType).FirstOrDefault(); + var equip = StaticData.BaseEquip.ToList(); + var startEquip = equip.Where(t => t.equipNo == equipNo).FirstOrDefault(); + //var currEquip= + if (palletInfo != null) + { + WcsTask newTask = new() + { + objid = Guid.NewGuid(), + taskType = Convert.ToInt32(dic.dicValue), + customerNo = customerNo, + taskStatus = 0, + materialId = material.storageId, + qty = Convert.ToInt32(palletInfo.bindAmount), + startPointId = startEquip.objid, + startPointNo = equipNo, + //endPointId = wareHouse.warehouseId, + }; + } + } + return ""; + } + } +} diff --git a/src/Khd.Core.Wcs/Wcs/SnowflakeIdGenerator.cs b/src/Khd.Core.Wcs/Wcs/SnowflakeIdGenerator.cs new file mode 100644 index 0000000..9cb6491 --- /dev/null +++ b/src/Khd.Core.Wcs/Wcs/SnowflakeIdGenerator.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Khd.Core.Wcs.Wcs +{ + public class SnowflakeIdGenerator + { + private long _lastTimestamp = 0; // 上一次生成的时间戳 + private readonly int _dataCenterId; // 数据中心ID + private readonly int _workerId; // 工作节点ID + private long _sequence = 0; // 自增序列号 + + public SnowflakeIdGenerator(int dataCenterId, int workerId) + { + if (dataCenterId < 0 || dataCenterId > 31) + throw new ArgumentException("Data center ID must be between 0 and 31."); + if (workerId < 0 || workerId > 31) + throw new ArgumentException("Worker ID must be between 0 and 31."); + + _dataCenterId = dataCenterId; // 初始化数据中心ID + _workerId = workerId; // 初始化工作节点ID + } + + public long GenerateId() + { + long timestamp = GetTimestamp(); // 获取当前时间戳 + + if (timestamp < _lastTimestamp) // 如果当前时间戳小于上一次生成的时间戳 + throw new Exception("Clock moved backwards. Refusing to generate ID."); + + if (timestamp == _lastTimestamp) // 如果当前时间戳与上一次生成的时间戳相同 + { + _sequence = (_sequence + 1) & 4095; // 自增序列号,并将其限制在0~4095之间 + if (_sequence == 0) + timestamp = WaitNextMillis(_lastTimestamp); // 如果自增序列号达到上限,等待下一毫秒的时间戳 + } + else + { + _sequence = 0; // 如果当前时间戳发生变化,重置自增序列号 + } + + _lastTimestamp = timestamp; // 更新上一次生成的时间戳 + + // 生成雪花Id,通过位运算将各个部分组合起来 + return ((timestamp - 1580000000000L) << 22) // 时间戳部分(中间的 - 1580000000000L 是为了减少占用位数) + | (_dataCenterId << 17) // 数据中心ID部分 + | (_workerId << 12) // 工作节点ID部分 + | _sequence; // 自增序列号部分 + } + + private long GetTimestamp() + { + return DateTimeOffset.UtcNow.Ticks / 10000 - 62135596800000L; // 获取当前时间的毫秒级时间戳 + } + + private long WaitNextMillis(long lastTimestamp) + { + while (GetTimestamp() <= lastTimestamp) ; // 等待下一毫秒的时间戳 + + return GetTimestamp(); // 返回新的时间戳 + } + } + + +} diff --git a/src/Khd.Core.Wcs/Wcs/UpLine.cs b/src/Khd.Core.Wcs/Wcs/UpLine.cs index c1ca405..fc25186 100644 --- a/src/Khd.Core.Wcs/Wcs/UpLine.cs +++ b/src/Khd.Core.Wcs/Wcs/UpLine.cs @@ -47,7 +47,7 @@ namespace Khd.Core.Wcs.Wcs { this._host = host; this._plc = plc; - this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 + //this.ScanPoint = StaticData.NodeSettingList.Where(t => t.siteNo == siteNo).ToList();//加载当前站点所对应的点位 this.sitenode = StaticData.SiteNodeList.FirstOrDefault(t => t.siteNo == siteNo);//获取当前站台信息 this.NodeSettingCarNo = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carno")); this.NodeSettingCarState = this.ScanPoint.FirstOrDefault(t => t.plcpointNo.Contains("carstate")); diff --git a/src/Khd.Core.Wpf/Khd.Core.Wpf.csproj b/src/Khd.Core.Wpf/Khd.Core.Wpf.csproj index ce4edfb..2cb6fce 100644 --- a/src/Khd.Core.Wpf/Khd.Core.Wpf.csproj +++ b/src/Khd.Core.Wpf/Khd.Core.Wpf.csproj @@ -9,6 +9,9 @@ + + + @@ -119,6 +122,12 @@ + + + + + + Always @@ -459,4 +468,7 @@ PreserveNewest + + +