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.

356 lines
26 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Khd.Core.Domain.Dto.TaskType;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Khd.Core.Library;
using Khd.Core.Library.Mapper;
using Khd.Core.Plc.S7;
using Khd.Core.Wcs.Global;
using Masuit.Tools;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Khd.Core.Wcs.Wcs
{
/// <summary>
/// 二楼小包出入口
/// </summary>
public class SecondFloorLine
{
private readonly LoggerUtils _logger = new LoggerUtils();
private readonly IHost _host;
int FloorNo { get; set; }
public SecondFloorLine(IHost host, int floor)
{
this._host = host;
FloorNo = floor;
}
/// <summary>
/// 启动上件扫描监听
/// </summary>
public void StartPoint()
{
Thread FlowPointThread = new Thread(MonitorInLocatorPoint);
FlowPointThread.IsBackground = true;
FlowPointThread.Name = "SecondFloorLine";
FlowPointThread.Start();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线调度启动成功");
_logger.Info("二楼码垛输送线调度启动成功");
}
public void MonitorInLocatorPoint()
{
using var scope = _host.Services.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
var rfidPoint = StaticData.BasePlcpointList.First(t => t.id == 52);
var agvGetPoint = StaticData.BasePlcpointList.First(t => t.id == 53);
var agvPutPoint = StaticData.BasePlcpointList.First(t => t.id == 54);
BaseEquip agvEquip = StaticData.BaseEquip.First(t => t.objid == 8);
BaseEquip endEquip = StaticData.BaseEquip.First(t => t.objid == 36);
List<string> canNotIn = new List<string>();
while (true)
{
try
{
dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
var agvPutValue = StaticData.PlcDic[2].Read(agvPutPoint.plcpointAddress);//小包入口叫料
var agvGetValue = StaticData.PlcDic[2].Read(agvGetPoint.plcpointAddress);//小包出口的到位
var rfidValue = StaticData.PlcDic[2].ReadRFID(rfidPoint.plcpointAddress);//小包出口的RFID
if (agvGetValue != null && agvPutValue != null && rfidValue != null)//读Plc
{
if (Convert.ToInt32(agvPutValue) == 0)//小包入口叫料
{
bool canCreate = dbContext.WcsTask.Where(t => t.nextPointId == 8 || t.endPointId == endEquip.objid).Any();//有没有生成任务
//36 是小包入口的设备信息8是二楼Agv设备
if (!canCreate)//没有任务
{
BaseEquip? baseEquip = dbContext.BaseEquip.FirstOrDefault(t => t.equipType == 20 && t.emptyCount >= 1);//二楼周转区是否存在一个空托盘以上的
if (baseEquip != null)//二楼周转区有可以去小包入口的库位
{
var wcsTask = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
endPointId = endEquip.objid,//小包入口
endPointNo = endEquip.equipNo,
nextPointId = agvEquip.objid,//二楼叉车
nextPointNo = agvEquip.equipNo,
currPointId = baseEquip.objid,//周转区库位
currPointNo = baseEquip.equipNo,
taskStatus = 0,
useFlag = 1,
containerNo = null,
createBy = "WCS",
createTime = DateTime.Now,
floorNo = 2,
fromFloorNo = 2,
isEmpty = "1",
qty = baseEquip.emptyCount,//托盘的数量
taskType = StaticTaskType.SecondTransitToSmallPackage,//任务类型
};
dbContext.Add(wcsTask);
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(wcsTask);
dbContext.Add(wcsTaskLog);
dbContext.SaveChanges();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成请求空托盘任务成功:" + wcsTask.objid);
_logger.Info("二楼码垛输送线生成请求空托盘任务成功:" + wcsTask.objid);
}
else//二楼周转区没有空托盘
{
baseEquip = dbContext.BaseEquip.FirstOrDefault(t => t.equipType == 15 && t.emptyCount == SystemData.maxTray);//三楼三个周转区是否存在空托盘
if (baseEquip != null)//如果三楼有空托盘
{
BaseEquip ThirdLineEquip = dbContext.BaseEquip.First(t => t.objid == 3);//三楼接驳位
BaseEquip ThirdAgvEquip = StaticData.BaseEquip.First(t => t.objid == 9);//三楼叉车
if (ThirdLineEquip.equipStatus == 0)//三楼接驳位空闲
{
//生成3楼Agv出库任务
WcsTask wcsTask = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
containerNo = null,
createBy = "WCS",
createTime = DateTime.Now,
floorNo = 2,
fromFloorNo = 3,
isEmpty = "1",
qty = SystemData.maxTray,
taskType = StaticTaskType.ThirdTransitToSecond,
currPointId = baseEquip.objid,
currPointNo = baseEquip.equipNo,
nextPointId = ThirdAgvEquip.objid,
nextPointNo = ThirdAgvEquip.equipNo,
endPointId = endEquip.objid,
endPointNo = endEquip.equipNo,
taskStatus = 0,
useFlag = 1,
};
dbContext.Add(wcsTask);
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(wcsTask);
dbContext.Add(wcsTaskLog);
dbContext.SaveChanges();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成3楼Agv出库任务成功:" + wcsTask.objid);
_logger.Info("二楼码垛输送线生成3楼Agv出库任务成功:" + wcsTask.objid);
}
}
else
{
BaseEquip startEquip = dbContext.BaseEquip.First(t => t.objid == 40);//一楼的托盘库
if (startEquip.emptyCount > 1 && startEquip.emptyCount <= SystemData.maxTray)
{
BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "someOut");//多个出
BasePlcpoint linesignal01 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal01");//一楼接驳位到位
BasePlcpoint equipstate06 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "equipstate06");//提升机状态
BasePlcpoint trayStatusValue = StaticData.BasePlcpointList.First(t => t.plcpointNo == "trayStatus");//提升机状态
BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 1);//一楼接驳位
var lineSignal01Value = StaticData.PlcDic[0].Read(linesignal01.plcpointAddress);
var equipstate06Value = StaticData.PlcDic[0].Read(equipstate06.plcpointAddress);
if (FirstFloor.ReadEmptyLocation() && trayStatusValue != null && Convert.ToInt32(trayStatusValue) == 1 && Convert.ToInt32(lineSignal01Value) == 0 && Convert.ToInt32(equipstate06Value) == 0)
{
StaticData.PlcDic[0].WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());//托盘库多个出
WcsTask wcsTaskManual = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
endPointId = endEquip.objid,
endPointNo = endEquip.equipNo,
nextPointId = lineEquip.objid,
nextPointNo = lineEquip.equipNo,
currPointId = lineEquip.objid,
currPointNo = lineEquip.equipNo,
taskStatus = 0,
useFlag = 1,
containerNo = null,
createBy = "WCS",
createTime = DateTime.Now,
floorNo = endEquip.floorNo,
fromFloorNo = 1,
isEmpty = "1",
qty = startEquip.emptyCount,
taskType = StaticTaskType.SecondLiftToWaste,
};
dbContext.Add(wcsTaskManual);
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(wcsTaskManual);
dbContext.Add(wcsTaskLog);
dbContext.SaveChanges();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid);
_logger.Info("二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid);
}
}
else if (startEquip.emptyCount > SystemData.maxTray)//如果托盘库大于五个,出一个
{
BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "oneOut");//多个出
BasePlcpoint linesignal01 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "linesignal01");//一楼接驳位到位
BasePlcpoint equipstate06 = StaticData.BasePlcpointList.First(t => t.plcpointNo == "equipstate06");//提升机状态
BasePlcpoint trayStatusValue = StaticData.BasePlcpointList.First(t => t.plcpointNo == "trayStatus");//提升机状态
BaseEquip lineEquip = dbContext.BaseEquip.First(t => t.objid == 1);//一楼接驳位
var lineSignal01Value = StaticData.PlcDic[0].Read(linesignal01.plcpointAddress);
var equipstate06Value = StaticData.PlcDic[0].Read(equipstate06.plcpointAddress);
if (FirstFloor.ReadEmptyLocation() && trayStatusValue != null && Convert.ToInt32(trayStatusValue) == 1 && Convert.ToInt32(lineSignal01Value) == 0 && Convert.ToInt32(equipstate06Value) == 0)
{
StaticData.PlcDic[0].WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());//托盘库多个出
WcsTask wcsTaskManual = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
endPointId = endEquip.objid,
endPointNo = endEquip.equipNo,
nextPointId = lineEquip.objid,
nextPointNo = lineEquip.equipNo,
currPointId = lineEquip.objid,
currPointNo = lineEquip.equipNo,
taskStatus = 0,
useFlag = 1,
containerNo = null,
createBy = "WCS",
createTime = DateTime.Now,
floorNo = endEquip.floorNo,
fromFloorNo = 1,
isEmpty = "1",
qty = 1,
taskType = StaticTaskType.SecondLiftToWaste,
};
dbContext.Add(wcsTaskManual);
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(wcsTaskManual);
dbContext.Add(wcsTaskLog);
dbContext.SaveChanges();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid);
_logger.Info("二楼码垛输送线生成手动托盘任务成功:" + wcsTaskManual.objid);
}
}
else
{
//todo:没有空托盘
Console.WriteLine(DateTime.Now + ":二楼码垛输送线没有空托盘");
_logger.Info("二楼码垛输送线没有空托盘");
}
}
}
}
}
if (Convert.ToInt32(agvGetValue) == 1 && !string.IsNullOrEmpty(rfidValue))//小包出口成品入口
{
lock (SystemData.SecondTaskLock)
{
MesBasePalletInfo? mesBasePalletInfo = dbContext.MesBasePalletInfo.FirstOrDefault(t => t.palletInfoCode == rfidValue);
if (mesBasePalletInfo != null)
{
MesBaseBarcodeInfo? mesBaseBarcodeInfo = dbContext.MesBaseBarcodeInfo.FirstOrDefault(t => t.barcodeInfo == mesBasePalletInfo.materialBarcode);
if (mesBaseBarcodeInfo != null)
{
var wmsBaseLocations = dbContext.WmsBaseLocation
.Where(t => t.warehouseFloor == FloorNo)
.Where(t => t.activeFlag == "1")
.Where(t => t.delFlag == "0")
.Where(t => t.locationScrapType == "1")
.Where(t => t.locationStatus == "1")
.Where(t => t.warehouseId == 231)
.ToList();//所有可用库位
var wmsProductStocks = dbContext.WmsProductStock
.Where(t => t.warehouseId == 231)
.ToList();//仓库的库存
WmsBaseLocation? wmsBaseLocation = null;
if (wmsBaseLocations.Count > 0)
{
List<string> containerCodes = wmsBaseLocations
.Where(t => t.locDeep == 1)
.Select(t => t.containerCode).ToList();//深库位的有托盘
containerCodes.RemoveAll(t => string.IsNullOrEmpty(t));
List<WmsProductStock> productStocks = wmsProductStocks.Where(t => t.productId == mesBaseBarcodeInfo.materialId)
.Where(t => t.saleOrderId == mesBaseBarcodeInfo.saleOrderId)
.Where(t => t.palletInfoCode != null)
.Where(t => containerCodes.Contains(t.palletInfoCode)).ToList();
var bill = from a in productStocks
join b in wmsBaseLocations.Where(t => t.locDeep == 1) on a.palletInfoCode equals b.containerCode
select new { b };//等于当前任务的物料的托盘的库位信息
var outBill = from a in bill//深库位托盘和当前任务绑定物料一致的托盘库位
from b in wmsBaseLocations//所有库位
where b.locDeep == 2//浅库位
&& b.locRow == (a.b.locRow % 2 == 0 ? a.b.locRow - 1 : a.b.locRow + 1)
//如果是4则找3如果是1则找2
&& a.b.locColumn == b.locColumn//列数相同
&& string.IsNullOrEmpty(b.containerCode)
select new { a.b };//在上面的基础上获取对应托盘的外侧库位的空库位信息
wmsBaseLocation ??= outBill.Where(t => !canNotIn.Contains(t.b.locationCode)).FirstOrDefault()?.b;//先找相同物料的外侧库位
wmsBaseLocation ??= wmsBaseLocations.Where(t => !canNotIn.Contains(t.locationCode)).Where(t => string.IsNullOrEmpty(t.containerCode)).FirstOrDefault(t => t.locDeep == 1);//找不到再找深库位
wmsBaseLocation ??= wmsBaseLocations.Where(t => !canNotIn.Contains(t.locationCode)).Where(t => string.IsNullOrEmpty(t.containerCode)).FirstOrDefault();//找不到再找任意库位
if (wmsBaseLocation != null)//如果找到库位,生成入库任务
{
if (wmsBaseLocation.locDeep == 1)
{
var hasLocation = wmsBaseLocations
.Where(t => t.locRow == (wmsBaseLocation.locRow % 2 == 1 ? (wmsBaseLocation.locRow + 1) : (wmsBaseLocation.locRow - 1)))
.Where(t => t.locColumn == wmsBaseLocation.locColumn)
.Where(t => !string.IsNullOrEmpty(t.containerCode) || t.locationStatus != "1")
.Any();
if (hasLocation)
{
canNotIn.Add(wmsBaseLocation.locationCode);
Console.WriteLine(DateTime.Now + $":目标库位{canNotIn.Join(",")}的浅库位库位状态异常,无法入库");
_logger.Info($"目标库位{canNotIn.Join(",")}的浅库位库位状态异常,无法入库");
continue;
}
}
BaseEquip startEquip = StaticData.BaseEquip.First(t => t.objid == 37);
var wcsTask = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
currPointId = startEquip.objid,
currPointNo = startEquip.equipNo,
nextPointId = agvEquip.objid,
nextPointNo = agvEquip.equipNo,
endPointId = wmsBaseLocation.locationId,
endPointNo = wmsBaseLocation.locationCode,
taskStatus = 0,
useFlag = 1,
containerNo = rfidValue,
createBy = "WCS",
createTime = DateTime.Now,
floorNo = 2,
fromFloorNo = 2,
isEmpty = "0",
taskType = StaticTaskType.SecondSmallPackageToStorage,
qty = 1,
};
SystemData.LockOutLocation(wmsBaseLocation, dbContext);
dbContext.Add(wcsTask);
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(wcsTask);
dbContext.Add(wcsTaskLog);
dbContext.SaveChanges();
canNotIn.Clear();
Console.WriteLine(DateTime.Now + ":二楼码垛输送线生成入库托盘任务成功:" + wcsTask.objid);
_logger.Info("二楼码垛输送线生成入库托盘任务成功:" + wcsTask.objid);
}
else
{
//报警
}
}
}
}
}
}
}
}
catch (Exception ex)
{
if (ex is PlcException)
{
}
else
{
_logger.Error(ex.Message + "\n" + ex.StackTrace);
}
}
finally
{
Thread.Sleep(1000);
}
}
}
}
}