diff --git a/src/Khd.Core.Domain/Dto/webapi/genAgvSchedulingTask.cs b/src/Khd.Core.Domain/Dto/webapi/genAgvSchedulingTask.cs
index aad5202..c7a6dc1 100644
--- a/src/Khd.Core.Domain/Dto/webapi/genAgvSchedulingTask.cs
+++ b/src/Khd.Core.Domain/Dto/webapi/genAgvSchedulingTask.cs
@@ -52,20 +52,12 @@ namespace Khd.Core.Domain.Dto.webapi
///
/// 位置路径:AGV关键路径位置集合,与任务类型中模板配置的位置路径一一对应。待现场地图部署、配置完成后可获取。
///
- public string positionCodePath { get; set; }
- ///
- /// 货架编号,不指定货架可以为空
- ///
- public string podCode { get; set; }
+ public List positionCodePath { get; set; }
///
/// “180”,”0”,”90”,”-90” 分别对应地图的”左”,”右”,”上”,”下” ,不指定方向可以为空
///
public string podDir { get; set; }
///
- /// 货架类型, 传空时表示随机找个货架
- ///
- public string podTyp { get; set; }
- ///
/// 物料批次或货架上的物料唯一编码,
///
public string materialLot { get; set; }
@@ -99,6 +91,18 @@ namespace Khd.Core.Domain.Dto.webapi
public string positionSelStrategy { get; set; }
public string data { get; set; }
}
+ public class Position
+ {
+ ///
+ /// 货架编号,不指定货架可以为空
+ ///
+ public string podCode { get; set; }
+ ///
+ /// 货架类型, 传空时表示随机找个货架
+ ///
+ public string podTyp { get; set; }
+
+ }
public class ReponseMessage
{
diff --git a/src/Khd.Core.Domain/Models/WmsBaseLocation.cs b/src/Khd.Core.Domain/Models/WmsBaseLocation.cs
index e396fae..f30c543 100644
--- a/src/Khd.Core.Domain/Models/WmsBaseLocation.cs
+++ b/src/Khd.Core.Domain/Models/WmsBaseLocation.cs
@@ -27,11 +27,16 @@ namespace Khd.Core.Domain.Models
///
[Column("warehouse_id")]
public long warehouseId { get; set; }
-
+
+ ///
+ /// agv的点位编码
+ ///
+ [Column("agv_position_code")]
+ public string agvPositionCode { get; set; }
///
/// 库位编码
///
- [Column("location_code")]
+ [Column("location_code")]
public string locationCode { get; set; }
///
diff --git a/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj b/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj
index 6ccdfe6..3887259 100644
--- a/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj
+++ b/src/Khd.Core.Wcs/Khd.Core.Wcs.csproj
@@ -11,6 +11,7 @@
+
diff --git a/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs
index 830f9ff..113ccff 100644
--- a/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs
+++ b/src/Khd.Core.Wcs/Wcs/CreateTaskByRecord.cs
@@ -84,7 +84,10 @@ namespace Khd.Core.Wcs.Wcs
{
try
{
- CreateTask();
+ //原料&辅料出库
+ CreateRawTask();
+ //成品&半成品出库
+ CreateProductTask();
}
catch (Exception ex)
{
@@ -96,37 +99,6 @@ namespace Khd.Core.Wcs.Wcs
}
}
}
-
- private void CreateTask()
- {
- using var scope = _host.Services.CreateScope();
- using var dbContext = scope.ServiceProvider.GetRequiredService();
-
- try
- {
-
- //入库
- var rawInstock = dbContext.WmsProductInstock.Where(t => t.taskCode == "1").ToList();
- if (rawInstock.Count > 0)
- {
- foreach (var item in rawInstock)
- {
- }
-
- }
-
- //原料&辅料出库
- CreateMaterialTask();
- //成品&半成品出库
- CreateProductTask();
- }
- catch (Exception ex)
- {
- //LogManager.Info($"错误日志输出 >>> OutWarePoint类 WriteMaterialMessage 方法报错 {ex}");
- LogManager.Error(ex);
- }
-
- }
///
/// 成品出库
///
@@ -182,28 +154,23 @@ namespace Khd.Core.Wcs.Wcs
dbContext.Add(newTask);
dbContext.SaveChanges();
}
- //回写出库记录表
- //item.executeStatus = "1";
- //item.updateDate = DateTime.Now;
- //dbContext.WmsProductOutstock.Update(item);
- //dbContext.SaveChanges();
+ //回写wms记录表
dbContext.WmsProductOutstock.Where(t => t.productOutstockId == item.productOutstockId).Update(t => new WmsProductOutstock()
{
executeStatus = "1",
updateDate = DateTime.Now
});
}
-
}
- public void CreateMaterialTask()
+ public void CreateRawTask()
{
using var scope = _host.Services.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService();
-
+ //原材料库存
var rawStock = dbContext.WmsRawStock.Where(t => t.activeFlag == "0").ToList();
+ //原材料出库记录
var rawOutStock = dbContext.WmsRawOutstock.Where(t => t.executeStatus == "0").ToList();
-
foreach (var item in rawOutStock)
{
//自动获取id
@@ -223,8 +190,7 @@ namespace Khd.Core.Wcs.Wcs
createTime = DateTime.Now
};
dbContext.Add(stockLock);
- //var palletInfo = StaticData.MesBasePalletInfo.Where(t => t.materialId == item.productId).FirstOrDefault() ;
- if (true)//辅料
+ if (item.warehouseId==5)//五楼辅料出库
{
//辅料出库时,需创建订单表数据
orderID = id.NextId();
@@ -239,11 +205,6 @@ namespace Khd.Core.Wcs.Wcs
};
dbContext.Add(order);
}
- else
- {
- //半成品
-
- }
var dic = StaticData.BaseDictionary.Where(t => t.dicKey == "TaskType" && t.ud1 == "O").FirstOrDefault();
WcsTask rawTask = new()
{
@@ -264,16 +225,11 @@ namespace Khd.Core.Wcs.Wcs
};
dbContext.Add(rawTask);
-
//获取最早入库时间
var firstDate = rawStock.Where(t => t.materialId == item.productId && t.warehouseId == item.warehouseId).OrderBy(t => t.createDate).FirstOrDefault();
var rkDate = firstDate.createDate;
- //回写出库记录表
- //item.executeStatus = "1";
- //item.updateDate = DateTime.Now;
- //dbContext.WmsProductOutstock.Update(item);
- //dbContext.SaveChanges();
+ //回写wms出库记录表
dbContext.WmsRawOutstock.Where(t => t.rawOutstockId == item.rawOutstockId).Update(t => new WmsProductOutstock()
{
executeStatus = "1",
diff --git a/src/Khd.Core.Wcs/Wcs/SecondFloorAGV.cs b/src/Khd.Core.Wcs/Wcs/SecondFloorAGV.cs
new file mode 100644
index 0000000..26a4c1d
--- /dev/null
+++ b/src/Khd.Core.Wcs/Wcs/SecondFloorAGV.cs
@@ -0,0 +1,468 @@
+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;
+using Z.EntityFramework.Plus;
+
+namespace Khd.Core.Wcs.Wcs
+{
+ ///
+ /// 二楼AGV调度
+ ///
+ public class SecondFloorAGV
+ {
+ 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; }
+ string EquipNo = "";
+ List taskInType = new List { 1, 3, 5, 7 };
+ List taskOutType = new List { 2, 4, 6, 8 };
+ public SecondFloorAGV(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
+ {
+ this._host = host;
+ this._plc = plc;
+ FloorNo = floor;
+ EquipNo = equipNo;
+ 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 IsPallet = this._plc.Read(LineIsPallet.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()
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ List taskInType = new List { 1, 3, 5, 7 };
+ List taskOutType = new List { 2, 4, 6, 8 };
+ while (true)
+ {
+ try
+ {
+ var taskList = GetTask(FloorNo, EquipNo);
+ if (taskList.Count == 0)
+ {
+ LogManager.Info(FloorNo + "楼AGV无任务");
+ }
+ foreach (var item in taskList)
+ {
+ if (taskInType.Contains(item.taskType.GetValueOrDefault()))//入库
+ {
+ var loc = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
+
+ //2楼成品
+ if (item.taskType == 5|| item.taskType==11 )//成品入库||成品移库
+ {
+ var stock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1").ToList();
+ //获取有物料的库位
+ var locStock = from l in loc
+ join s in stock on l.locationCode equals s.locationCode
+ select new
+ {
+ LocId = l.locationId,
+ locCode = l.locationCode,
+ LocDeep = l.locDeep,
+ productBatch = s.productBatch
+ };
+ //获取空库位
+ var nullLocList = loc.Where(r => !locStock.Select(t => t.locCode).Contains(r.locationCode) && r.warehouseId == 1).ToList();
+ var location = nullLocList.OrderBy(t => t.locColumn).FirstOrDefault();
+
+ item.currPointId = 8;
+ item.currPointNo = "AGV01";
+ item.nextPointId = location.locationId;
+ item.nextPointNo = location.locationCode;
+ //dbContext.Update(item);
+ }
+ //下发agv出库指令
+ SendAndUpdateTask(item);
+ }
+ else
+ {
+ var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
+ //出库
+ if (item.taskType == 6)//成品出库
+ {
+ //获取库存
+ var proStock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1" && t.stockType == "3").ToList();
+
+ var dic = dbContext.BaseDictionary.Where(t => t.dicKey == "OutStockDate").FirstOrDefault();
+ var DateRange = Convert.ToInt32(dic.dicValue);
+ var stockList = from t in proStock.Where(r => r.productId == item.materialId)
+ join b in locList on t.locationCode equals b.locationCode
+ into temp
+ from newStock in temp.DefaultIfEmpty()
+ select new
+ {
+ proID = t.productStockId,
+ locID = newStock.locationId,
+ locCode = t.locationCode,
+ layerNum = newStock.layerNum,
+ locColumn = newStock.locColumn,
+ locRow = newStock.locRow,
+ locDeep = newStock.locDeep,
+ inStockDate = newStock.createTime,
+ };
+ //先查出最早入库时间
+ var inStockModel = stockList.OrderBy(t => t.inStockDate).FirstOrDefault();
+ var inStockDate = inStockModel.inStockDate;
+ //查出符合条件的成品
+ var outStockList = stockList.Where(t => t.inStockDate >= inStockDate && t.inStockDate <= inStockDate.GetValueOrDefault().AddDays(DateRange)).ToList();
+ var outModel = outStockList.OrderBy(t => t.locColumn).ThenByDescending(t => t.locDeep).FirstOrDefault();
+ if (outModel.locDeep == 1)
+ {
+ //自动获取id
+ Jc.SnowId.JcSnowId id = new Jc.SnowId.JcSnowId(1, 1);
+ var objid = id.NextId();
+ var isExiStock = stockList.Where(t=>t.locRow==outModel.locRow && t.locColumn==outModel.locColumn && t.locDeep ==2).FirstOrDefault();
+ if (isExiStock != null)
+ {
+ //创建成品移库任务
+ WcsTask newTask = new()
+ {
+ objid = objid,
+ taskType = 11,
+ containerNo = "",
+ taskStatus = 0,
+ materialId = isExiStock.locID,
+ qty = 1,
+ startPointId = isExiStock.locID,
+ startPointNo = "",
+ currPointId = isExiStock.locID,
+ currPointNo = "",
+ };
+ dbContext.Add(newTask);
+ dbContext.SaveChanges();
+ return;
+ }
+ }
+ //锁定库位
+ dbContext.WmsBaseLocation.Where(t => t.locationCode == outModel.locCode).Update(t => new WmsBaseLocation()
+ {
+ locationStatus = "1",
+ updateTime = DateTime.Now,
+ updateBy = "agv出库",
+ });
+ //下发agv出库指令
+ SendAndUpdateTask(item);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error(ex);
+ }
+ finally
+ {
+ Thread.Sleep(1000);
+ }
+ }
+ }
+
+ public List GetTask(int floorNo, string equipNo)
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ List wcsTask = new List();
+ var wareHouseList = StaticData.WmsBaseWarehouse.ToList();
+ var equip = StaticData.BaseEquip.Where(t => t.floorNo == floorNo && t.equipType == 4).FirstOrDefault();
+ try
+ {
+ //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
+ var taskList = StaticData.WcsTask.Where(t => t.nextPointId == equip.objid && t.currPointId != equip.objid && (t.taskType==1|| t.taskType == 2|| t.taskType == 5 || t.taskType == 6)).ToList();
+ if (taskList.Count() == 0)
+ { return null; }
+ wcsTask = taskList;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Info(floorNo + "楼AGV异常" + ex.Message);
+ throw;
+ }
+ return wcsTask;
+ }
+ public void SendAndUpdateTask(WcsTask task)
+ {
+ //获取
+ if (task == null) return;
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ WcsToWms wcsToWms = new WcsToWms();
+ //首先判断是否已下发指令
+ var cmd = dbContext.WcsCmd.Where(t => t.taskId == task.objid).FirstOrDefault();
+ var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
+ //指令表存在说明已下发
+ if (cmd == null)
+ { //获取下发agv指令
+ string ip = ""; int port = 0; string url = "";
+ RequestAGVTaskDto agvtask = new RequestAGVTaskDto();
+ agvtask.reqCode = task.objid.ToString();
+ //var json = JsonConvert.SerializeObject(agvtask);
+ //HttpHelper.SendPostMessage(ip, port, url, json);
+ agvtask.positionCodePath = new List();
+ Position p = new Position();
+ WmsBaseLocation putPos = new WmsBaseLocation(); //放料点
+ WmsBaseLocation setPos = new WmsBaseLocation(); //取料点
+ if (task.taskType == 5) //入库
+ {
+ setPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault();
+ }
+ else
+ {
+ setPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault();
+ }
+ putPos = locList.Where(t => t.locationId == task.nextPointId).FirstOrDefault();
+ p.podCode = setPos.agvPositionCode;
+ p.podTyp = "";
+ agvtask.positionCodePath.Add(p);
+ p.podCode = putPos.agvPositionCode;
+ p.podTyp = "";
+ //取料点
+ agvtask.positionCodePath.Add(p);
+ agvtask.taskTyp = "";
+ //给agv创建任务
+ wcsToWms.genAgvSchedulingTask(agvtask);
+ //未下发给agv下发指令
+ WcsCmd taskCmd = new WcsCmd()
+ {
+ taskId = task.objid,
+ cmdType = task.taskType,
+ serialNo = task.serialNo,
+ equipmentNo = task.equipmentNo,
+ cmdStatus = 1,
+ createBy = FloorNo + "楼AGV",
+ createTime = DateTime.Now,
+ };
+ dbContext.Add(taskCmd);
+ dbContext.SaveChanges();
+ }
+ else
+ {
+ //获取接驳位是否有托盘
+ var IsPallet = this._plc.Read(this.LineIsPallet.plcpointAddress);
+ if (cmd.sendFlag == 0)
+ {
+ if (taskInType.Contains(task.taskType.GetValueOrDefault()))//入库
+ {
+ //入库时有托盘继续任务
+ if (Convert.ToInt32(IsPallet) == 1)
+ {
+ continueTaskDto continueTask = new continueTaskDto();
+ continueTask.taskCode = task.objid.ToString();
+ wcsToWms.continueTask(continueTask);
+ //未下发给agv下发指令
+ WcsCmd taskCmd = new WcsCmd()
+ {
+ taskId = task.objid,
+ sendFlag = 1,
+ createBy = FloorNo + "楼AGV",
+ createTime = DateTime.Now,
+ };
+ dbContext.Update(taskCmd);
+ dbContext.SaveChanges();
+ }
+ }
+ else
+ {
+ //出库时没有托盘继续任务
+ if (Convert.ToInt32(IsPallet) == 0)
+ {
+ continueTaskDto continueTask = new continueTaskDto();
+ continueTask.taskCode = task.objid.ToString();
+ wcsToWms.continueTask(continueTask);
+ //更新任务
+ dbContext.WcsCmd.Where(t => t.taskId == task.objid).Update(t => new WcsCmd()
+ {
+ sendFlag = 1,
+ updateTime = DateTime.Now,
+ updateBy = "agv出库",
+ });
+ }
+ }
+ }
+ }
+ //更新任务表
+ dbContext.WcsTask.Where(t => t.objid == task.objid).Update(t => new WcsTask()
+ {
+ currPointId = task.currPointId,
+ currPointNo = task.currPointNo,
+ nextPointId = task.nextPointId,
+ nextPointNo= task.nextPointNo,
+ updateTime = DateTime.Now,
+ updateBy = "agv出库",
+ }) ;
+ }
+ /////
+ ///// 下发任务
+ /////
+ /////
+ //public void SendTask1(WcsTask task)
+ //{
+ // using var scope = _host.Services.CreateScope();
+ // using var dbContext = scope.ServiceProvider.GetRequiredService();
+ // //入库类型
+ // //List taskInType = new List { 1, 3, 5, 7 };
+ // //List taskOutType = new List { 2, 4, 6, 8 };
+ // //获取
+ // if (task == null) return;
+ // if (taskInType.Contains(task.taskType.GetValueOrDefault()))//入库
+ // {
+ // WcsToWms wcsToWms = new WcsToWms();
+ // //首先判断是否已下发指令
+ // var cmd = StaticData.WcsCmd.Where(t => t.taskId == task.objid).FirstOrDefault();
+ // //指令表存在说明已下发
+ // if (cmd == null)
+ // { //获取下发agv指令
+ // string ip = ""; int port = 0; string url = "";
+ // RequestAGVTaskDto agvtask = new RequestAGVTaskDto();
+ // agvtask.reqCode = task.serialNo.ToString();
+ // //var json = JsonConvert.SerializeObject(agvtask);
+ // //HttpHelper.SendPostMessage(ip, port, url, json);
+ // wcsToWms.genAgvSchedulingTask(agvtask);
+ // //未下发给agv下发指令
+ // WcsCmd taskCmd = new WcsCmd()
+ // {
+ // taskId = task.objid,
+ // cmdType = task.taskType,
+ // serialNo = task.serialNo,
+ // equipmentNo = task.equipmentNo,
+ // cmdStatus = 1,
+ // createBy = FloorNo + "楼AGV",
+ // createTime = DateTime.Now,
+ // };
+ // dbContext.Add(taskCmd);
+ // dbContext.SaveChanges();
+ // }
+ // else
+ // {
+
+ // var IsPallet = this._plc.Read(this.LineIsPallet.plcpointAddress);
+ // if (cmd.sendFlag == 0)
+ // {
+ // if (Convert.ToInt32(IsPallet) == 1)
+ // {
+
+ // continueTaskDto continueTask = new continueTaskDto();
+ // continueTask.taskCode = task.objid.ToString();
+ // wcsToWms.continueTask(continueTask);
+ // //未下发给agv下发指令
+ // WcsCmd taskCmd = new WcsCmd()
+ // {
+ // taskId = task.objid,
+ // cmdType = task.taskType,
+ // serialNo = task.serialNo,
+ // equipmentNo = task.equipmentNo,
+ // sendFlag = 1,
+ // createBy = FloorNo + "楼AGV",
+ // createTime = DateTime.Now,
+ // };
+ // dbContext.Update(taskCmd);
+ // dbContext.SaveChanges();
+
+ // }
+ // }
+ // }
+
+ // }
+ // else
+ // {
+ // var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
+ // //出库
+ // if (task.taskType == 6)//成品出库
+ // {
+ // //获取库存
+ // var proStock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1" && t.stockType == "3" && t.productId == task.materialId).ToList();
+
+ // var dic = dbContext.BaseDictionary.Where(t => t.dicKey == "OutStockDate").FirstOrDefault();
+ // var DateRange = Convert.ToInt32(dic.dicValue);
+ // var stockList = from t in proStock
+ // join b in locList on t.locationCode equals b.locationCode
+ // into temp
+ // from newStock in temp.DefaultIfEmpty()
+ // select new
+ // {
+ // proID = t.productStockId,
+ // locID = newStock.locationId,
+ // locCode = t.locationCode,
+ // layerNum = newStock.layerNum,
+ // locColumn = newStock.locColumn,
+ // locRow = newStock.locRow,
+ // locDeep = newStock.locDeep,
+ // inStockDate = newStock.createTime,
+ // };
+ // //先查出最早入库时间
+ // var inStockModel = stockList.OrderBy(t => t.inStockDate).FirstOrDefault();
+ // var inStockDate = inStockModel.inStockDate;
+ // //查出符合条件的成品
+ // var outStockList = stockList.Where(t => t.inStockDate >= inStockDate && t.inStockDate <= inStockDate.GetValueOrDefault().AddDays(DateRange)).ToList();
+ // var outModel = outStockList.OrderBy(t => t.locColumn).ThenByDescending(t => t.locDeep).FirstOrDefault();
+
+
+ // dbContext.WmsBaseLocation.Where(t => t.locationCode == outModel.locCode).Update(t => new WmsBaseLocation()
+ // {
+ // locationStatus = "1",
+ // updateTime = DateTime.Now,
+ // updateBy = "agv出库",
+ // });
+
+ // dbContext.WcsTask.Where(t => t.objid == task.objid).Update(t => new WcsTask()
+ // {
+ // currPointId = outModel.locID,
+ // currPointNo = outModel.locCode,
+ // updateTime = DateTime.Now,
+ // updateBy = "agv出库",
+ // });
+ // //下发agv出库指令
+
+
+ // }
+ // else if (task.taskType == 2)//原材料出库
+ // {
+
+ // }
+ // }
+ //}
+ }
+}
diff --git a/src/Khd.Core.Wcs/Wcs/SecondFloorLine.cs b/src/Khd.Core.Wcs/Wcs/SecondFloorLine.cs
new file mode 100644
index 0000000..02ca2ee
--- /dev/null
+++ b/src/Khd.Core.Wcs/Wcs/SecondFloorLine.cs
@@ -0,0 +1,233 @@
+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;
+using Z.EntityFramework.Plus;
+
+namespace Khd.Core.Wcs.Wcs
+{
+ ///
+ /// 二楼码垛输送线调度
+ ///
+ public class SecondFloorPoint
+ {
+ 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; }
+ string EquipNo = "";
+ public SecondFloorPoint(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
+ {
+ this._host = host;
+ this._plc = plc;
+ FloorNo = floor;
+ EquipNo = equipNo;
+ 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()
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ 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 wcsTask = GetTask(palletNo, FloorNo, EquipNo);
+ //判断是否为出库任务
+ if ( wcsTask.taskType == 5)
+ {
+ var nextEquip = StaticData.BaseEquip.Where(t=>t.floorNo==FloorNo && t.equipType==4).FirstOrDefault();
+ //更新任务下一点位为AGV
+ wcsTask.nextPointId = nextEquip.objid;
+ wcsTask.nextPointNo = nextEquip.equipNo;
+ wcsTask.updateTime = DateTime.Now;
+ wcsTask.updateBy = FloorNo+"楼输送线";
+ dbContext.Update(wcsTask);
+ dbContext.SaveChanges();
+ ////入库任务
+ ////下发agv任务
+ //SendTask(wcsTask);
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error(ex);
+ }
+ finally
+ {
+ Thread.Sleep(1000);
+ }
+ }
+ }
+ //获取输送线上的任务
+ public WcsTask GetTask(string containerNo, int floorNo, string equipNo)
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ var wcsTask = new WcsTask();
+ var wareHouseList = StaticData.WmsBaseWarehouse.ToList();
+ try
+ {
+ //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
+ var task = StaticData.WcsTask.Where(t => t.containerNo == containerNo).FirstOrDefault();
+ if (task == null)
+ {
+ var palletInfo = StaticData.MesBasePalletInfo.Where(t => t.palletInfoCode == containerNo).FirstOrDefault();
+ //查询该条码绑定的物料信息
+ var material = StaticData.WmsWarehouseMaterial.Where(t => t.storageId == palletInfo.materialId).FirstOrDefault();
+ var wareHouse = wareHouseList.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 endPoint = wareHouseList.Where(t => t.warehouseFloor == floorNo).FirstOrDefault();
+ //var currEquip=
+ if (palletInfo != null)
+ {
+ //自动获取id
+ Jc.SnowId.JcSnowId id = new Jc.SnowId.JcSnowId(1, 1);
+ var objid = id.NextId();
+ WcsTask newTask = new()
+ {
+ objid = objid,
+ taskType = Convert.ToInt32(dic.dicValue),
+ containerNo = containerNo,
+ taskStatus = 0,
+ materialId = material.storageId,
+ qty = Convert.ToInt32(palletInfo.bindAmount),
+ startPointId = startEquip.objid,
+ startPointNo = equipNo,
+ currPointId = startEquip.objid,
+ currPointNo = equipNo,
+ endPointId = endPoint.warehouseId,
+ endPointNo = endPoint.warehouseCode,
+ };
+ dbContext.Add(newTask);
+ dbContext.SaveChanges();
+
+ wcsTask = newTask;
+ }
+ else
+ {
+ LogManager.Info(floorNo + "楼接驳位,托盘"+ containerNo + "未绑定!" );
+ }
+ }
+ else
+ {
+ wcsTask = StaticData.WcsTask.Where(t => t.currPointNo == equipNo).FirstOrDefault();
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Info(floorNo + "楼接驳位异常"+ ex.Message);
+ throw;
+ }
+ return wcsTask;
+ }
+ ///
+ /// 下发任务
+ ///
+ ///
+ public void SendTask(WcsTask task)
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ //入库类型
+ List taskInType = new List { 1, 3, 5, 7 };
+ List taskOutType = new List { 2, 4, 6, 8 };
+ try
+ {
+ //获取
+ if (task == null) return;
+ if (taskInType.Contains(task.taskType.GetValueOrDefault()))
+ {
+ //首先判断是否已下发指令
+ var cmd = StaticData.WcsCmd.Where(t => t.taskId == task.objid).FirstOrDefault();
+ //指令表存在说明已下发
+ if (cmd != null) return;
+ //获取下发agv指令
+ string ip = ""; int port = 0; string url = "";
+ RequestAGVTaskDto agvtask = new RequestAGVTaskDto();
+ agvtask.reqCode = task.serialNo.ToString();
+ var json = JsonConvert.SerializeObject(agvtask);
+ HttpHelper.SendPostMessage(ip, port, url, json);
+ //未下发给agv下发指令
+ WcsCmd taskCmd = new WcsCmd()
+ {
+ taskId = task.objid,
+ cmdType = task.taskType,
+ serialNo = task.serialNo,
+ equipmentNo = task.equipmentNo,
+ cmdStatus = 1,
+ createBy = "",
+ createTime = DateTime.Now,
+ };
+ dbContext.Add(taskCmd);
+ dbContext.SaveChanges();
+ }
+ }
+ catch (Exception)
+ {
+
+ throw;
+ }
+ }
+ }
+}
diff --git a/src/Khd.Core.Wcs/Wcs/SecondFloorPoint.cs b/src/Khd.Core.Wcs/Wcs/SecondFloorPoint.cs
new file mode 100644
index 0000000..b9c09c8
--- /dev/null
+++ b/src/Khd.Core.Wcs/Wcs/SecondFloorPoint.cs
@@ -0,0 +1,149 @@
+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;
+using Z.EntityFramework.Plus;
+
+namespace Khd.Core.Wcs.Wcs
+{
+ ///
+ /// 二楼接驳位调度
+ ///
+ public class SecondFloorLine
+ {
+ 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; }
+ string EquipNo = "";
+ public SecondFloorLine(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
+ {
+ this._host = host;
+ this._plc = plc;
+ FloorNo = floor;
+ EquipNo = equipNo;
+ 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()
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ 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 wcsTask = GetTask(palletNo, FloorNo, EquipNo);
+ //判断是否为出库任务
+ if (wcsTask.taskType == 3)
+ {
+ this._plc.Write(LineWcsrun.plcpointAddress, 1);
+ //更新任务
+ dbContext.WcsTask.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTask()
+ {
+ currPointId = 2,
+ currPointNo = "F02",
+ //提升机
+ nextPointId = 6,
+ nextPointNo = "T01",
+ updateTime = DateTime.Now,
+ updateBy = "二楼接驳位",
+ });
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Error(ex);
+ }
+ finally
+ {
+ Thread.Sleep(1000);
+ }
+ }
+ }
+ //获取输送线上的任务
+ public WcsTask GetTask(string containerNo, int floorNo, string equipNo)
+ {
+ using var scope = _host.Services.CreateScope();
+ using var dbContext = scope.ServiceProvider.GetRequiredService();
+ var wcsTask = new WcsTask();
+ var wareHouseList = StaticData.WmsBaseWarehouse.ToList();
+ try
+ {
+ //获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
+ var task = StaticData.WcsTask.Where(t => t.containerNo == containerNo).FirstOrDefault();
+ if (task == null)
+ {
+ wcsTask = task;
+ }
+ else
+ {
+ wcsTask = StaticData.WcsTask.Where(t => t.currPointNo == equipNo).FirstOrDefault();
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Info(floorNo + "楼接驳位异常" + ex.Message);
+ throw;
+ }
+ return wcsTask;
+ }
+ }
+}
diff --git a/src/Khd.Core.Wcs/Wcs/SecondThirdFloorAGV.cs b/src/Khd.Core.Wcs/Wcs/ThirdFloorAGV.cs
similarity index 99%
rename from src/Khd.Core.Wcs/Wcs/SecondThirdFloorAGV.cs
rename to src/Khd.Core.Wcs/Wcs/ThirdFloorAGV.cs
index 4dd1c08..18e5c0d 100644
--- a/src/Khd.Core.Wcs/Wcs/SecondThirdFloorAGV.cs
+++ b/src/Khd.Core.Wcs/Wcs/ThirdFloorAGV.cs
@@ -16,9 +16,9 @@ using Z.EntityFramework.Plus;
namespace Khd.Core.Wcs.Wcs
{
///
- /// 二楼调度
+ /// 三楼agv调度
///
- public class SecondThirdFloorAGV
+ public class ThirdFloorAGV
{
List ScanPoint { get; set; }//点位信息
private readonly IHost _host;
@@ -34,7 +34,7 @@ namespace Khd.Core.Wcs.Wcs
string EquipNo = "";
List taskInType = new List { 1, 3, 5, 7 };
List taskOutType = new List { 2, 4, 6, 8 };
- public SecondThirdFloorAGV(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
+ public ThirdFloorAGV(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
{
this._host = host;
this._plc = plc;
diff --git a/src/Khd.Core.Wcs/Wcs/SecondThirdFloorPoint.cs b/src/Khd.Core.Wcs/Wcs/ThirdFloorPoint.cs
similarity index 98%
rename from src/Khd.Core.Wcs/Wcs/SecondThirdFloorPoint.cs
rename to src/Khd.Core.Wcs/Wcs/ThirdFloorPoint.cs
index 8f36d30..4bbb4b2 100644
--- a/src/Khd.Core.Wcs/Wcs/SecondThirdFloorPoint.cs
+++ b/src/Khd.Core.Wcs/Wcs/ThirdFloorPoint.cs
@@ -15,9 +15,9 @@ using System.Threading.Tasks;
namespace Khd.Core.Wcs.Wcs
{
///
- /// 二楼调度
+ /// 三楼接驳位调度
///
- public class SecondThirdFloorPoint
+ public class ThirdFloorPoint
{
List ScanPoint { get; set; }//点位信息
private readonly IHost _host;
@@ -31,7 +31,7 @@ namespace Khd.Core.Wcs.Wcs
Thread FlowPointThread;
int FloorNo { get; set; }
string EquipNo = "";
- public SecondThirdFloorPoint(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
+ public ThirdFloorPoint(IHost host, Plc.S7.Plc plc, int floor, string equipNo)
{
this._host = host;
this._plc = plc;