You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
16 KiB
C#
309 lines
16 KiB
C#
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 Z.EntityFramework.Plus;
|
|
|
|
namespace Khd.Core.Wcs.Wcs
|
|
{
|
|
/// <summary>
|
|
/// 二楼AGV调度
|
|
/// </summary>
|
|
public class SecondFloorAGV
|
|
{
|
|
List<BasePlcpoint> ScanPoint { get; set; }//点位信息
|
|
private readonly IHost _host;
|
|
private readonly Plc.S7.Plc _plc;
|
|
private readonly BasePlcpoint LineRFID;
|
|
private readonly BasePlcpoint LineWcsrun;
|
|
private readonly BasePlcpoint LineSignal;
|
|
private readonly BasePlcpoint LineIsPallet;
|
|
private readonly BasePlcpoint LineSerialNO;
|
|
int FloorNo { get; set; }
|
|
string EquipNo = "";
|
|
int EquipID = 8; //2楼AGV
|
|
List<int> taskInType = new List<int> { 1, 3, 5, 7 };
|
|
List<int> taskOutType = new List<int> { 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.First(t => t.plcpointNo.Contains("RFID"));
|
|
this.LineWcsrun = this.ScanPoint.First(t => t.plcpointNo.Contains("wcsrun"));
|
|
this.LineSignal = this.ScanPoint.First(t => t.plcpointNo.Contains("linesignal"));
|
|
this.LineIsPallet = this.ScanPoint.First(t => t.plcpointNo.Contains("ispallet"));
|
|
this.LineSerialNO = this.ScanPoint.First(t => t.plcpointNo.Contains("serialno"));
|
|
|
|
//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);
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 启动上件扫描监听
|
|
/// </summary>
|
|
public void StartPoint()
|
|
{
|
|
|
|
Thread FlowPointThread = new Thread(MonitorInLocatorPoint);
|
|
FlowPointThread.Start();
|
|
Console.WriteLine(DateTime.Now + ":二楼AGV上件扫描监听启动成功");
|
|
LogManager.Info("二楼AGV上件扫描监听启动成功");
|
|
}
|
|
|
|
public void MonitorInLocatorPoint()
|
|
{
|
|
using var scope = _host.Services.CreateScope();
|
|
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
//获取条码号,如果该条码任务存在就继续任务,如果条码不存在,创建入库任务并调度agv
|
|
var taskList = StaticData.WcsTask.Where(t => t.nextPointId == EquipID && t.currPointId != EquipID && (t.taskType == 11 || t.taskType == 5 || t.taskType == 6)).ToList();
|
|
if (taskList.Count == 0)
|
|
{
|
|
LogManager.Info(FloorNo + "楼AGV无任务");
|
|
}
|
|
foreach (var item in taskList)
|
|
{
|
|
if (item.taskType == 5 || item.taskType == 11)//入库
|
|
{
|
|
var loc = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
|
|
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();
|
|
if (location == null) return;
|
|
item.currPointId = 8;
|
|
item.currPointNo = "AGV01";
|
|
item.nextPointId = location.locationId;
|
|
item.nextPointNo = location.locationCode;
|
|
//锁定库位
|
|
dbContext.WmsBaseLocation.Where(t => t.locRow == location.locRow && t.locColumn == location.locColumn && t.layerNum == location.layerNum).Update(t => new WmsBaseLocation()
|
|
{
|
|
locationStatus = "6",
|
|
updateTime = DateTime.Now,
|
|
updateBy = "agv出库",
|
|
});
|
|
//下发agv出库指令
|
|
SendAndUpdateTask(item);
|
|
}
|
|
else if (item.taskType == 6)
|
|
{
|
|
var locList = dbContext.WmsBaseLocation.Where(t => t.activeFlag == "1").ToList();
|
|
var outProStock = dbContext.WmsProductOutstock.Where(t => t.productOutstockId == item.orderId).FirstOrDefault();
|
|
//获取库存
|
|
var proStock = dbContext.WmsProductStock.Where(t => t.activeFlag == "1" && t.stockType == "3" && t.planCode == outProStock.planCode && t.saleorderCode == outProStock.saleorderCode).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
|
|
|
|
var objid = StaticData.SnowId.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,
|
|
currPointId = isExiStock.locID,
|
|
endPointId = 12,
|
|
endPointNo = "WH02",
|
|
};
|
|
dbContext.Add(newTask);
|
|
dbContext.SaveChanges();
|
|
return;
|
|
}
|
|
}
|
|
//锁定库位
|
|
dbContext.WmsBaseLocation.Where(t => t.locRow == outModel.locRow && t.locColumn == outModel.locColumn && t.layerNum == outModel.layerNum).Update(t => new WmsBaseLocation()
|
|
{
|
|
locationStatus = "6",
|
|
updateTime = DateTime.Now,
|
|
updateBy = "agv出库",
|
|
});
|
|
//下发agv出库指令
|
|
SendAndUpdateTask(item);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogManager.Error(ex);
|
|
}
|
|
finally
|
|
{
|
|
Thread.Sleep(1000);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SendAndUpdateTask(WcsTask task)
|
|
{
|
|
//获取
|
|
if (task == null) return;
|
|
using var scope = _host.Services.CreateScope();
|
|
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
|
|
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 (locList.Count == 0) return;
|
|
//指令表存在说明已下发
|
|
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>();
|
|
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.positionCode = setPos?.agvPositionCode;
|
|
p.type = "";
|
|
agvtask.positionCodePath.Add(p);
|
|
p.positionCode = putPos?.agvPositionCode;
|
|
p.type = "";
|
|
//取料点
|
|
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出库",
|
|
});
|
|
}
|
|
}
|
|
}
|