|
|
|
|
@ -0,0 +1,282 @@
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
namespace Khd.Core.Wcs.MyWcs
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// AGV任务逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class AgvTaskLogic
|
|
|
|
|
{
|
|
|
|
|
private readonly Dictionary<string, PlcPoint> _plcPoints;
|
|
|
|
|
private readonly Plc.S7.Plc _plc;
|
|
|
|
|
private readonly int _floorNo;
|
|
|
|
|
private readonly BaseEquip _baseEquip;
|
|
|
|
|
private readonly IHost _host;
|
|
|
|
|
private readonly BaseEquip _lineEquip;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 构造函数
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="FloorNo"> 楼层号 </param>
|
|
|
|
|
/// <param name="baseEquip"> 基站设备 </param>
|
|
|
|
|
/// <param name="lineEquip"> 线路设备 </param>
|
|
|
|
|
/// <param name="host"> IHost </param>
|
|
|
|
|
/// <param name="plc"> Plc </param>
|
|
|
|
|
public AgvTaskLogic(int FloorNo, BaseEquip baseEquip, BaseEquip lineEquip, IHost host, Plc.S7.Plc plc)
|
|
|
|
|
{
|
|
|
|
|
_plc = plc;
|
|
|
|
|
_floorNo = FloorNo;
|
|
|
|
|
_baseEquip = baseEquip;
|
|
|
|
|
_lineEquip = lineEquip;
|
|
|
|
|
_host = host;
|
|
|
|
|
_plcPoints = StaticData.PlcPoints[FloorNo];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 启动AGV任务逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
|
|
|
|
Thread ExecuteLogicThread = new(ExecuteTaskLogic)
|
|
|
|
|
{
|
|
|
|
|
IsBackground = true
|
|
|
|
|
};
|
|
|
|
|
ExecuteLogicThread.Start();
|
|
|
|
|
|
|
|
|
|
Thread ContinueLogicThread = new(ContinueTaskLogic)
|
|
|
|
|
{
|
|
|
|
|
IsBackground = true
|
|
|
|
|
};
|
|
|
|
|
ContinueLogicThread.Start();
|
|
|
|
|
Console.WriteLine($"{DateTime.Now}:{this._floorNo}楼Agv任务逻辑启动成功");
|
|
|
|
|
LogManager.Info($"{this._floorNo}楼Agv任务逻辑启动成功");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 执行AGV任务逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void ExecuteTaskLogic()
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using var scope = _host.Services.CreateScope();
|
|
|
|
|
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
|
|
|
|
|
var wcsTask = dbContext.WcsTask
|
|
|
|
|
.Where(t => t.floorNo == _floorNo)
|
|
|
|
|
.Where(t => t.nextPointId == _baseEquip.objid)
|
|
|
|
|
.OrderBy(t => t.createTime)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
if (wcsTask != null && wcsTask.taskStatus == 0)//未执行的任务
|
|
|
|
|
{
|
|
|
|
|
if (wcsTask.taskType % 2 == 1)//入库
|
|
|
|
|
{
|
|
|
|
|
var wmsBaseLocations = dbContext.WmsBaseLocation
|
|
|
|
|
.Where(t => t.activeFlag == "1")
|
|
|
|
|
.Where(t => t.delFlag == "0")
|
|
|
|
|
.Where(t => t.instockFlag == "0")
|
|
|
|
|
.Where(t => t.locationScrapType == "1")
|
|
|
|
|
.Where(t => t.locationStatus == "1")
|
|
|
|
|
.Where(t => t.outstockFlag == "0")
|
|
|
|
|
.Where(t => t.warehouseId == wcsTask.endPointId).ToList();
|
|
|
|
|
if (wmsBaseLocations.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
var wmsBaseLocation = wmsBaseLocations.First();
|
|
|
|
|
wcsTask.endPointId = wmsBaseLocation.locationId;
|
|
|
|
|
wcsTask.endPointNo = wmsBaseLocation.locationCode;
|
|
|
|
|
var request = new RequestAGVTaskDto()
|
|
|
|
|
{
|
|
|
|
|
reqCode = wcsTask.objid.ToString(),
|
|
|
|
|
taskMode = "2",
|
|
|
|
|
positionCodePath = new List<Position>
|
|
|
|
|
{
|
|
|
|
|
new Position
|
|
|
|
|
{
|
|
|
|
|
podCode=_lineEquip.equipNo
|
|
|
|
|
},
|
|
|
|
|
new Position
|
|
|
|
|
{
|
|
|
|
|
podCode=wmsBaseLocation.agvPositionCode
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
var reponse = SendTask(request);
|
|
|
|
|
if (reponse != null)
|
|
|
|
|
{
|
|
|
|
|
if (reponse.message == "成功")
|
|
|
|
|
{
|
|
|
|
|
LogManager.Info("AGV任务执行成功,任务ID:" + wcsTask.objid);
|
|
|
|
|
wcsTask.taskStatus = 1;
|
|
|
|
|
wcsTask.updateTime = DateTime.Now;
|
|
|
|
|
wmsBaseLocation.instockFlag = "1";
|
|
|
|
|
wmsBaseLocation.locationStatus = "2";
|
|
|
|
|
dbContext.Update(wmsBaseLocation);
|
|
|
|
|
dbContext.Update(wcsTask);
|
|
|
|
|
dbContext.SaveChanges();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogManager.Debug("AGV任务执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else//出库
|
|
|
|
|
{
|
|
|
|
|
var request = new RequestAGVTaskDto()
|
|
|
|
|
{
|
|
|
|
|
reqCode = wcsTask.objid.ToString(),
|
|
|
|
|
taskMode = "2",
|
|
|
|
|
positionCodePath = new List<Position>
|
|
|
|
|
{
|
|
|
|
|
new Position
|
|
|
|
|
{
|
|
|
|
|
podCode=wcsTask.startPointNo
|
|
|
|
|
},
|
|
|
|
|
new Position
|
|
|
|
|
{
|
|
|
|
|
podCode=wcsTask.nextPointNo
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
var reponse = SendTask(request);
|
|
|
|
|
if (reponse != null)
|
|
|
|
|
{
|
|
|
|
|
if (reponse.message == "成功")
|
|
|
|
|
{
|
|
|
|
|
LogManager.Info("AGV任务执行成功,任务ID:" + wcsTask.objid);
|
|
|
|
|
var wmsBaseLocations = dbContext.WmsBaseLocation.Where(t => t.agvPositionCode == wcsTask.startPointNo).ToList();
|
|
|
|
|
foreach (var item in wmsBaseLocations)
|
|
|
|
|
{
|
|
|
|
|
var wmsBaseWarehouse = dbContext.WmsBaseWarehouse.FirstOrDefault(t => t.warehouseId == item.warehouseId);
|
|
|
|
|
if (wmsBaseWarehouse != null && wmsBaseWarehouse.warehouseFloor == _floorNo)
|
|
|
|
|
{
|
|
|
|
|
item.outstockFlag = "1";
|
|
|
|
|
item.locationStatus = "6";
|
|
|
|
|
dbContext.Update(item);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wcsTask.taskStatus = 1;
|
|
|
|
|
wcsTask.updateTime = DateTime.Now;
|
|
|
|
|
dbContext.Update(wcsTask);
|
|
|
|
|
dbContext.SaveChanges();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogManager.Debug("AGV任务执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LogManager.Error(ex);
|
|
|
|
|
}
|
|
|
|
|
Thread.Sleep(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 继续执行AGV任务逻辑
|
|
|
|
|
/// </summary>
|
|
|
|
|
private void ContinueTaskLogic()
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
using var scope = _host.Services.CreateScope();
|
|
|
|
|
using var dbContext = scope.ServiceProvider.GetRequiredService<DefaultDbContext>();
|
|
|
|
|
var wcsTask = dbContext.WcsTask
|
|
|
|
|
.Where(t => t.floorNo == _floorNo)
|
|
|
|
|
.Where(t => t.nextPointId == _baseEquip.objid)
|
|
|
|
|
.Where(t=>t.taskStatus==2)
|
|
|
|
|
.OrderBy(t => t.createTime)
|
|
|
|
|
.FirstOrDefault();
|
|
|
|
|
if (wcsTask != null)
|
|
|
|
|
{
|
|
|
|
|
var request = new RequestAGVTaskDto();
|
|
|
|
|
request.reqCode = wcsTask.objid.ToString();
|
|
|
|
|
var reponse = ContinueTask(request);
|
|
|
|
|
if (reponse != null)
|
|
|
|
|
{
|
|
|
|
|
if (reponse.message == "成功")
|
|
|
|
|
{
|
|
|
|
|
LogManager.Info("AGV任务继续执行成功,任务ID:" + wcsTask.objid);
|
|
|
|
|
wcsTask.taskStatus = 3;
|
|
|
|
|
wcsTask.updateTime = DateTime.Now;
|
|
|
|
|
var wmsBaseLocation = dbContext.WmsBaseLocation.FirstOrDefault(t => t.locationId == wcsTask.endPointId);
|
|
|
|
|
if (wmsBaseLocation != null)
|
|
|
|
|
{
|
|
|
|
|
wmsBaseLocation.instockFlag = "0";
|
|
|
|
|
wmsBaseLocation.outstockFlag = "0";
|
|
|
|
|
wmsBaseLocation.locationStatus = "1";
|
|
|
|
|
dbContext.Update(wmsBaseLocation);
|
|
|
|
|
}
|
|
|
|
|
dbContext.Update(wcsTask);
|
|
|
|
|
dbContext.SaveChanges();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LogManager.Debug("AGV任务继续执行失败,任务ID:" + wcsTask.objid + ",失败原因:" + reponse.message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LogManager.Error(ex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发送任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private ReponseagvCallbackDto? SendTask(RequestAGVTaskDto request)
|
|
|
|
|
{
|
|
|
|
|
if (_baseEquip.serverPort == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("服务器端口不能为空");
|
|
|
|
|
}
|
|
|
|
|
string ip = _baseEquip.serverIp;
|
|
|
|
|
int port = _baseEquip.serverPort.Value;
|
|
|
|
|
string url = "";
|
|
|
|
|
string message = JsonConvert.SerializeObject(request);
|
|
|
|
|
string result = HttpHelper.SendPostMessage(ip, port, url, message);
|
|
|
|
|
return JsonConvert.DeserializeObject<ReponseagvCallbackDto>(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 继续执行任务
|
|
|
|
|
/// </summary>
|
|
|
|
|
private ReponseagvcontinueTaskDto? ContinueTask(RequestAGVTaskDto request)
|
|
|
|
|
{
|
|
|
|
|
if (_baseEquip.serverPort == null)
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("服务器端口不能为空");
|
|
|
|
|
}
|
|
|
|
|
string ip = _baseEquip.serverIp;
|
|
|
|
|
int port = _baseEquip.serverPort.Value;
|
|
|
|
|
string url = "";
|
|
|
|
|
string message = JsonConvert.SerializeObject(request);
|
|
|
|
|
string result = HttpHelper.SendPostMessage(ip, port, url, message);
|
|
|
|
|
return JsonConvert.DeserializeObject<ReponseagvcontinueTaskDto>(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|