|
|
|
|
@ -0,0 +1,192 @@
|
|
|
|
|
#region << 版 本 注 释 >>
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------
|
|
|
|
|
* 版权所有 (c) 2026 WenJY 保留所有权利。
|
|
|
|
|
* CLR版本:4.0.30319.42000
|
|
|
|
|
* 机器名称:Mr.Wen's MacBook Pro
|
|
|
|
|
* 命名空间:Sln.Wcs.HoistDispatchHub
|
|
|
|
|
* 唯一标识:764B880E-8084-48A5-B773-95E8EA044319
|
|
|
|
|
*
|
|
|
|
|
* 创建者:WenJY
|
|
|
|
|
* 电子邮箱:
|
|
|
|
|
* 创建时间:2026-06-01 13:24:25
|
|
|
|
|
* 版本:V1.0.0
|
|
|
|
|
* 描述:
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------------------
|
|
|
|
|
* 修改人:
|
|
|
|
|
* 时间:
|
|
|
|
|
* 修改说明:
|
|
|
|
|
*
|
|
|
|
|
* 版本:V1.0.0
|
|
|
|
|
*--------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
#endregion << 版 本 注 释 >>
|
|
|
|
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
using Sln.Wcs.HoistAdapter.Domain.Dto.GetHoistStatus;
|
|
|
|
|
using Sln.Wcs.HoistAdapter.Domain.Dto.HoistControl;
|
|
|
|
|
using Sln.Wcs.HoistAdapter.Domain.Dto.HoistTaskExecutor;
|
|
|
|
|
using Sln.Wcs.HoistAdapter.Domain.Enum;
|
|
|
|
|
using Sln.Wcs.HoistAdapter.Service;
|
|
|
|
|
using Sln.Wcs.Model.Domain;
|
|
|
|
|
using Sln.Wcs.Serilog;
|
|
|
|
|
|
|
|
|
|
namespace Sln.Wcs.HoistDispatcher;
|
|
|
|
|
|
|
|
|
|
public class HoistDispatchHub
|
|
|
|
|
{
|
|
|
|
|
private readonly SerilogHelper _logger;
|
|
|
|
|
private readonly IHoistService _hoistAdapter;
|
|
|
|
|
public HoistDispatchHub(IHoistService hoistAdapter, SerilogHelper logger)
|
|
|
|
|
{
|
|
|
|
|
_hoistAdapter = hoistAdapter;
|
|
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 提升机启动:放置完成下发
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="hoistCode"></param>
|
|
|
|
|
public void TaskRun(BaseDeviceInfo deviceInfo)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
HoistControlResultDto res = _hoistAdapter.HoistControl(new HoistControlDto()
|
|
|
|
|
{
|
|
|
|
|
hoistCode = deviceInfo.hostCode,
|
|
|
|
|
deviceSerialNo = deviceInfo.deviceSerialNo,
|
|
|
|
|
action = ControlAction.Start
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res.code == HoistStatusEnum.成功)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机启动指令(放置完成)下发成功");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机启动指令(放置完成)下发失败:{res.msg},SDK返回信息:{res.data.message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机启动指令(放置完成)下发异常:{e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 提升机任务下发执行:可根据现场节拍进行提前下发(AGV 确定接驳位后即可下发)
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="deviceInfo"></param>
|
|
|
|
|
/// <param name="liveTaskDetail"></param>
|
|
|
|
|
public void TaskDispatch(BaseDeviceInfo deviceInfo,LiveTaskDetail liveTaskDetail)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//解析起始点,组合 PLC 所需的起始点
|
|
|
|
|
TryParsePointCode(liveTaskDetail.startPoint, out string startBuilding, out string startFloor,
|
|
|
|
|
out string startLocation);
|
|
|
|
|
TryParsePointCode(liveTaskDetail.endPoint, out string endBuilding, out string endFloor,
|
|
|
|
|
out string endLocation);
|
|
|
|
|
int endPoint = Convert.ToInt32(deviceInfo.deviceSerialNo + startFloor + endFloor);
|
|
|
|
|
|
|
|
|
|
//调用适配层下发 提升机调度任务
|
|
|
|
|
HoistTaskExeResultDto res = _hoistAdapter.HoistTaskExecutor(new HoistTaskExeDto()
|
|
|
|
|
{
|
|
|
|
|
hoistCode = deviceInfo.hostCode,
|
|
|
|
|
taskCode = liveTaskDetail.taskCode,
|
|
|
|
|
deviceSerialNo = deviceInfo.deviceSerialNo,
|
|
|
|
|
endPoint = endPoint,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (res.code == HoistStatusEnum.成功)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机任务{liveTaskDetail.taskCode}下发成功:目标位置-{endPoint}");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机任务{liveTaskDetail.taskCode}下发失败:{res.msg},SDK返回信息:{res.data.message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"提升机任务下发异常:{e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取空闲提升机
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="hostCode"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<BaseDeviceInfo> GetFreeHoistAsync(string hostCode)
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
RefreshDeviceParams(hostCode, out List<BaseDeviceInfo> deviceInfos);
|
|
|
|
|
|
|
|
|
|
var freeHoist = deviceInfos?.FirstOrDefault(info =>
|
|
|
|
|
info.deviceParams.Any(item =>
|
|
|
|
|
item.paramName.Contains("提升机反馈任务状态") && item.paramValue == 0
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (freeHoist != null)
|
|
|
|
|
return freeHoist;
|
|
|
|
|
|
|
|
|
|
await Task.Delay(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 刷新设备参数:根据设备参数地址通过 PLC 获取参数值
|
|
|
|
|
/// hostCode为空时获取配置的所有参数值
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="hostCode"></param>
|
|
|
|
|
/// <param name="deviceParams"></param>
|
|
|
|
|
private void RefreshDeviceParams(string hostCode,out List<BaseDeviceInfo> deviceParams)
|
|
|
|
|
{
|
|
|
|
|
deviceParams = null;
|
|
|
|
|
|
|
|
|
|
GetHoistStatusResultDto getRes = _hoistAdapter.GetHoistStatus(new GetHoistStatusDto(){hoistCode = hostCode});
|
|
|
|
|
|
|
|
|
|
if (getRes.code == HoistStatusEnum.成功)
|
|
|
|
|
{
|
|
|
|
|
deviceParams = JsonConvert.DeserializeObject<List<BaseDeviceInfo>>(getRes.data.deviceParamStr);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logger.Info($"设备参数获取失败:{getRes.msg}");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 解析起始点内容
|
|
|
|
|
/// 14#_L2_02 => 14栋、2层、02货位
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="taskCode"></param>
|
|
|
|
|
/// <param name="building"></param>
|
|
|
|
|
/// <param name="floor"></param>
|
|
|
|
|
/// <param name="location"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private bool TryParsePointCode(string taskCode, out string building, out string floor, out string location)
|
|
|
|
|
{
|
|
|
|
|
building = null;
|
|
|
|
|
floor = null;
|
|
|
|
|
location = null;
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(taskCode))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// 使用正则表达式匹配格式:数字+#+_+L+数字+_+数字(至少一位)
|
|
|
|
|
// 示例:14#_L2_03
|
|
|
|
|
var match = System.Text.RegularExpressions.Regex.Match(taskCode, @"^(\d+)#_L(\d+)_(\d+)$");
|
|
|
|
|
if (!match.Success)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
building = match.Groups[1].Value;
|
|
|
|
|
floor = match.Groups[2].Value;
|
|
|
|
|
location = match.Groups[3].Value;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|