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.

468 lines
29 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.Application;
using Khd.Core.Application.Interface;
using Khd.Core.Domain.Models;
using Khd.Core.EntityFramework;
using Khd.Core.Library.Mapper;
using Khd.Core.Plc;
using Khd.Core.Plc.S7;
using Khd.Core.Wcs.Global;
using Masuit.Tools.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Diagnostics;
using Z.EntityFramework.Plus;
namespace Khd.Core.Wcs.Wcs
{
/// <summary>
/// 一楼线程(包括接驳位,提升机调度)
/// </summary>
public class FirstFloor
{
private readonly IHost _host;
private Plc.S7.Plc _plc;
private readonly long F01 = 1;
private readonly long T01 = 6;
/// <summary>
/// 一楼RFID 读
/// </summary>
private readonly BasePlcpoint RFID001;
private readonly BasePlcpoint automatic;
/// <summary>
/// 到位信号 读
/// </summary>
private readonly BasePlcpoint linesignal01;
/// <summary>
/// 提升机流水号 读
/// </summary>
private readonly BasePlcpoint serialno06;
/// <summary>
/// 提升机状态 读
/// </summary>
private readonly BasePlcpoint equipstate06;
/// <summary>
/// 提升机任务状态 读
/// </summary>
private readonly BasePlcpoint hoistertrayin06;
/// <summary>
/// 提升机当前楼层 写
/// </summary>
private readonly BasePlcpoint currentfloor06;
/// <summary>
/// 提升机目的楼层 写
/// </summary>
private readonly BasePlcpoint targetfloor06;
/// <summary>
/// 提升机反馈流水号
/// </summary>
private readonly BasePlcpoint reserialno06;
/// <summary>
/// 是否可以写去向
/// </summary>
private readonly BasePlcpoint canwritewcsrun06;
public FirstFloor(IHost host, Plc.S7.Plc plc)
{
this._host = host;
this._plc = plc;
//一楼RFID 读
this.RFID001 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("FirstFloorLine") && t.plcpointNo.Contains("RFID001"));
//到位信号 读
this.linesignal01 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("FirstFloorLine") && t.plcpointNo.Contains("linesignal01"));
//一楼提升机流水号 读
this.serialno06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("serialno06"));
this.automatic = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("automatic"));
//一楼提升机状态 读
this.equipstate06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("equipstate06"));
//一楼提升机任务状态 读
this.hoistertrayin06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("hoistertrayin06"));
//一楼提升机当前楼层 写
this.currentfloor06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("currentfloor06"));
//一楼提升机目的楼层 写
this.targetfloor06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("targetfloor06"));
//一楼提升机到位信号 读
this.reserialno06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("reserialno06"));
this.canwritewcsrun06 = StaticData.BasePlcpointList.First(t => t.equipmentNo.Contains("Hoister") && t.plcpointNo.Contains("canwritewcsrun06"));
}
/// <summary>
/// 启动上件扫描监听
/// </summary>
public void StartPoint()
{
Thread firstFloorLine = new(FirstFloorLine)
{
IsBackground = true
};
firstFloorLine.Start();
Console.WriteLine(DateTime.Now + ":一楼接驳位线程启动成功");
LogManager.Info("一楼接驳位线程启动成功");
Thread firstFloorHoister = new(FirstFloorHoister)
{
IsBackground = true
};
firstFloorHoister.Start();
Console.WriteLine(DateTime.Now + ":一楼提升机线程启动成功");
LogManager.Info("一楼提升机线程启动成功");
}
/// <summary>
/// 启动一楼接驳位线程
/// </summary>
private void FirstFloorLine()
{
List<int?> Itpyes = new() { 1, 3, 5, 7 };
using var scope = _host.Services.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
while (true)
{
try
{
dbContext.ChangeTracker.Entries().ToList().ForEach(e => e.Reload());
var RFID001Value = this._plc.ReadRFID(this.RFID001.plcpointAddress); //一楼RFID 读
var linesignal01Value = this._plc.Read(this.linesignal01.plcpointAddress); //到位信号 读
//正常读到plc值
if (linesignal01Value != null && RFID001Value != null)
{
//正常托盘到位
if (Convert.ToInt32(linesignal01Value) == 1)
{
//判断task表里没有该rfid的未完成的入库
//信息,未下发去向
var task = dbContext.WcsTask.Where(t => t.containerNo == RFID001Value && t.taskStatus < 1).FirstOrDefault();
if (task == null)
{
//根据托盘号获取物料码
var material = dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).FirstOrDefault();
if (material != null)
{
var lastTask = dbContext.WcsTaskLog.Where(t => t.containerNo == RFID001Value).OrderByDescending(t => t.createTime).FirstOrDefault();
if (lastTask != null)
{
if (lastTask.materialId == material.materialId && lastTask.ud3 != "10")
{
lastTask.ud2 = "1";
lastTask.ud3 = "1";
dbContext.Update(lastTask);
dbContext.SaveChanges();
LogManager.Info("一楼接驳位线程:托盘" + RFID001Value + "绑定信息未更新,请人工确认是否再次入库");
Console.WriteLine(DateTime.Now + ":一楼接驳位线程:托盘" + RFID001Value + "绑定信息未更新,请人工确认是否再次入库");
Thread.Sleep(3000);
continue;
}
}
var warehouseId = dbContext.WmsWarehouseMaterial.Where(t => t.storageType == "1" && t.storageId == material.materialId).FirstOrDefault()?.warehouseId;
if (warehouseId != null)
{
var TargetFloor = dbContext.WmsBaseWarehouse.Where(t => t.warehouseId == warehouseId).FirstOrDefault();
if (TargetFloor != null)
{
//插入task表
var dic = StaticData.BaseDictionary.Where(t => t.dicKey == "TaskType" && t.agvType == "I" && t.dicField == TargetFloor.warehouseInstockType).FirstOrDefault();
if (dic != null)
{
var newTask = new WcsTask()
{
objid = StaticData.SnowId.NextId(),
serialNo = SystemData.GetSerialNo(dbContext),
equipmentNo = "F01",
taskType = Convert.ToInt32(dic.dicValue),
taskStatus = 0,
containerNo = RFID001Value,
materialNo = material.materialCode,
materialId = material.materialId,
qty = Convert.ToInt32(material.bindAmount),
startPointId = F01,
startPointNo = "TSJ_01",
currPointId = F01,
currPointNo = "TSJ_01",
nextPointId = T01,
nextPointNo = "TSJ_01",
endPointId = warehouseId,
fromFloorNo = 1,
floorNo = TargetFloor.warehouseFloor,
useFlag = 1,
createBy = "一楼接驳位",
createTime = DateTime.Now,
remark = "一楼创建入库任务"
};
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(newTask);
dbContext.Add(wcsTaskLog);
dbContext.Add(newTask);
dbContext.SaveChanges();
}
}
}
}
}
else if (Itpyes.Contains(task.taskType))//按照正常任务下发
{
if (task.nextPointId != T01)
{
task.currPointId = F01;
task.currPointNo = "TSJ_01";
task.nextPointId = T01;
task.nextPointNo = "TSJ_01";
task.taskStatus = 0;
task.updateBy = "一楼接驳位线程";
task.updateTime = DateTime.Now;
task.remark = "一楼创建入库任务";
WcsTaskLog wcsTaskLog = CoreMapper.Map<WcsTaskLog>(task);
dbContext.Update(wcsTaskLog);
dbContext.Update(task);
dbContext.SaveChanges();
}
}
//出库
else
{
dbContext.WcsTask.Where(t => t.objid == task.objid).Delete();
dbContext.WcsTaskLog.Where(t => t.objid == task.objid).Update(t => new WcsTaskLog { taskStatus = 4 });
//没有绑定信息
//WmsProductOutstock? wmsProductOutstock = dbContext.WmsProductOutstock.FirstOrDefault(t => t.palletInfoCode == RFID001Value&& t.executeStatus =="1");
//WmsRawOutstock? wmsRawOutstock = dbContext.WmsRawOutstock.FirstOrDefault(t => t.palletInfoCode == RFID001Value && t.executeStatus == "1");
//if (wmsProductOutstock != null || wmsRawOutstock != null)
//{
// //清空托盘绑定
// var material = dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).FirstOrDefault();
// if (material != null)
// {
// material.bindAmount = 0;
// material.materialBarcode = null;
// material.materialCode = null;
// material.materialId = null;
// material.materialName = null;
// material.updateBy = "WCS";
// material.updateTime = DateTime.Now;
// dbContext.Update(material);
// if (wmsRawOutstock != null)
// {
// wmsRawOutstock.executeStatus = "2";
// dbContext.Update(wmsRawOutstock);
// }
// else if(wmsProductOutstock != null)
// {
// wmsProductOutstock.executeStatus = "2";
// dbContext.Update(wmsProductOutstock);
// }
// //dbContext.MesBasePalletInfo.Where(t => t.palletInfoCode == RFID001Value).Delete();
// dbContext.SaveChanges();
// }
//}
}
}
}
}
catch (Exception ex)
{
if (ex is PlcException)
{
foreach (var item in StaticData.PlcDic)
{
if (item.Value.IP == ex.Message)
{
StaticData.PlcDic[item.Key] = new Plc.S7.Plc(item.Value.CPU, item.Value.IP, item.Value.Port, item.Value.Rack, item.Value.Slot);
StaticData.PlcDic[item.Key].Open();
}
}
}
LogManager.Error(ex);
}
Thread.Sleep(1000);
}
}
/// <summary>
/// 提升机线程
/// </summary>
private void FirstFloorHoister()
{
while (true)
{
try
{
//var automatic06Value = this._plc.Read(this.automatic.plcpointAddress);//提升机自动状态
//if (automatic06Value != null && Convert.ToInt32(automatic06Value) == 1)
//{
using var scope = _host.Services.CreateScope();
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
var serialno06Value = this._plc.Read(this.serialno06.plcpointAddress); //提升机流水号 读
var equipstate06Value = this._plc.Read(this.equipstate06.plcpointAddress); //提升机状态 读
var hoisterTrayIn06Value = this._plc.Read(this.hoistertrayin06.plcpointAddress); //提升机货物到位状态 读
var currentfloor06Value = this._plc.Read(this.currentfloor06.plcpointAddress); //提升机当前楼层 读
var targetfloor06Value = this._plc.Read(this.targetfloor06.plcpointAddress); //提升机目的楼层 写
var reserialno06 = this._plc.Read(this.reserialno06.plcpointAddress); //反馈流水号
var canwritewcsrun06value = this._plc.Read(this.canwritewcsrun06.plcpointAddress);
//正常读到plc值
if (targetfloor06Value != null && canwritewcsrun06value != null && serialno06Value != null && equipstate06Value != null && currentfloor06Value != null && reserialno06 != null && hoisterTrayIn06Value != null)
{
//提升机空闲
if (Convert.ToInt32(equipstate06Value) == 0)
{
var wcsTasks = dbContext.WcsTask.Where(t => t.nextPointId == T01).OrderBy(t => t.createTime).ToList();
foreach (var wcsTask in wcsTasks)
{
if (wcsTasks.Where(t => t.taskStatus > 0).Where(t => t.objid != wcsTask.objid).Any())
{
LogManager.Info("提升机线程:有其他任务正在执行,跳过当前任务");
continue;
}
BaseEquip lineEquip = StaticData.BaseEquip.First(t => t.objid == wcsTask.floorNo);
if (wcsTask.taskStatus == 0 && Convert.ToInt32(hoisterTrayIn06Value) == 0)//创建状态,并且里面没有货物
{
if (lineEquip.equipStatus == 1)
{
LogManager.Info("提升机线程:" + wcsTask.floorNo + "楼接驳位有AGV任务跳过当前任务");
continue;
}
BasePlcpoint floorPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "RFID00" + wcsTask.fromFloorNo);
if (wcsTask.containerNo == this._plc.ReadRFID(floorPoint.plcpointAddress))
{
if (Convert.ToInt32(currentfloor06Value) == wcsTask.fromFloorNo)
{
//if (Convert.ToInt32(canwritewcsrun06value) == 0)
{
wcsTask.taskStatus = 2;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行中";
BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.fromFloorNo && t.plcpointNo.Contains("wcsrun"));
this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());
this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString());
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" });
lineEquip.equipStatus = 1;
dbContext.Update(lineEquip);
dbContext.SaveChanges();
}
}
else
{
wcsTask.taskStatus = 1;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行中";
this._plc.WriteToPoint(this.targetfloor06.plcpointAddress, wcsTask.fromFloorNo.ToString(), this.targetfloor06.plcpointLength.ToString());//目的地楼层
this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString());
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 1, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" });
lineEquip.equipStatus = 1;
dbContext.Update(lineEquip);
dbContext.SaveChanges();
}
}
}
if (wcsTask.taskStatus == 1 && Convert.ToInt32(reserialno06) == wcsTask.serialNo)
{
BasePlcpoint floorPoint = StaticData.BasePlcpointList.First(t => t.plcpointNo == "RFID00" + wcsTask.fromFloorNo);
if (wcsTask.containerNo == this._plc.ReadRFID(floorPoint.plcpointAddress))
{
//if (Convert.ToInt32(canwritewcsrun06value) == 0)
{
if (Convert.ToInt32(currentfloor06Value) == wcsTask.fromFloorNo)//提升机当前楼层为初始地楼层
{
wcsTask.taskStatus = 2;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行中";
BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.fromFloorNo && t.plcpointNo.Contains("wcsrun"));
this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "1", basePlcpoint.plcpointLength.ToString());
this._plc.WriteToPoint(this.serialno06.plcpointAddress, wcsTask.serialNo.ToString(), this.serialno06.plcpointLength.ToString());
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 2, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行中" });
dbContext.SaveChanges();
}
}
}
}
if (wcsTask.taskStatus == 2 && Convert.ToInt32(reserialno06) == wcsTask.serialNo)
{
if (Convert.ToInt32(hoisterTrayIn06Value) == 1)//托盘已经进提升机
{
wcsTask.taskStatus = 3;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行完成";
this._plc.WriteToPoint(this.targetfloor06.plcpointAddress, wcsTask.floorNo.ToString(), this.targetfloor06.plcpointLength.ToString());//目的地楼层
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 3, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" });
dbContext.SaveChanges();
}
}
if (wcsTask.taskStatus == 3 && Convert.ToInt32(currentfloor06Value) == wcsTask.floorNo && Convert.ToInt32(reserialno06) == wcsTask.serialNo)//任务状态为3且当前楼层为任务的目的楼层
{
//if (Convert.ToInt32(canwritewcsrun06value) == 0)
{
wcsTask.taskStatus = 4;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行完成";
BasePlcpoint basePlcpoint = StaticData.BasePlcpointList.First(t => t.floorNo == wcsTask.fromFloorNo && t.plcpointNo.Contains("wcsrun"));
this._plc.WriteToPoint(basePlcpoint.plcpointAddress, "2", basePlcpoint.plcpointLength.ToString());//去向为2表示提升机已到达目的地让货出去
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 4, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" });
dbContext.SaveChanges();
}
}
else if (wcsTask.taskStatus == 4)
{
BaseEquip floorEquip = StaticData.BaseEquip.First(t => t.objid == wcsTask.floorNo);
wcsTask.nextPointId = floorEquip.objid;
wcsTask.nextPointNo = floorEquip.equipNo;
wcsTask.taskStatus = 5;
wcsTask.updateBy = "提升机线程";
wcsTask.updateTime = DateTime.Now;
wcsTask.remark = "提升机任务执行完成";
lineEquip.equipStatus = 0;
dbContext.Update(lineEquip);
dbContext.SaveChanges();
dbContext.Update(wcsTask);
dbContext.WcsTaskLog.Where(t => t.objid == wcsTask.objid).Update(t => new WcsTaskLog { taskStatus = 5, nextPointId = floorEquip.objid, nextPointNo = floorEquip.equipNo, updateBy = "提升机线程", updateTime = DateTime.Now, remark = "提升机任务执行完成" });
dbContext.SaveChanges();
}
break;
}
}
}
//}
}
catch (Exception ex)
{
if (ex is PlcException)
{
try
{
foreach (var item in StaticData.PlcDic)
{
if (item.Value.IP == ex.Message)
{
StaticData.PlcDic[item.Key] = new Plc.S7.Plc(item.Value.CPU, item.Value.IP, item.Value.Port, item.Value.Rack, item.Value.Slot);
StaticData.PlcDic[item.Key].Open();
}
}
}
catch
{
}
}
LogManager.Error(ex);
}
Thread.Sleep(5000);
}
}
}
}