change - 提升机调度逻辑修改

dev
WenJY 1 week ago
parent 0927dce3a6
commit a1f7315d68

@ -34,6 +34,11 @@ public class HoistControlDto
/// </summary>
public string hoistCode { get; set; }
/// <summary>
/// 设备序号
/// </summary>
public int deviceSerialNo{get;set;}
/// <summary>
/// 动作
/// </summary>

@ -37,6 +37,11 @@ public class HoistTaskExeDto
/// </summary>
public string taskCode { get; set; }
/// <summary>
/// 设备序号
/// </summary>
public int deviceSerialNo{get;set;}
/// <summary>
/// 起点
/// </summary>

@ -114,6 +114,7 @@ public class HoistService:IHoistService
{
hoistCode = hoistTaskExeDto.hoistCode,
taskCode = hoistTaskExeDto.taskCode,
deviceSerialNo = hoistTaskExeDto.deviceSerialNo,
startPoint = hoistTaskExeDto.startPoint,
endPoint = hoistTaskExeDto.endPoint,

@ -0,0 +1,192 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.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;
}
}

@ -1,112 +0,0 @@
#region << 版 本 注 释 >>
/*--------------------------------------------------------------------
* (c) 2026 WenJY
* CLR4.0.30319.42000
* Mr.Wen's MacBook Pro
* Sln.Wcs.HoistDispatcher
* 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.Enum;
using Sln.Wcs.HoistAdapter.Service;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Plc.Service;
using Sln.Wcs.Repository.service;
using Sln.Wcs.Serilog;
namespace Sln.Wcs.HoistDispatcher;
public class HoistDispatcher
{
private readonly SerilogHelper _logger;
private readonly IHoistService _hoistAdapter;
public HoistDispatcher(IHoistService hoistAdapter, SerilogHelper logger)
{
_hoistAdapter = hoistAdapter;
_logger = logger;
}
public void Run()
{
_logger.Info("提升机调度就绪,输入 start 启动stop 停止quit 退出");
while (true)
{
var input = Console.ReadLine()?.Trim().ToLower();
switch (input)
{
case "start":
Start();
break;
case "stop":
Stop();
break;
case "quit":
Stop();
return;
default:
_logger.Info("未知指令,可用: start | stop | quit");
break;
}
}
}
private void Start()
{
}
private void Stop()
{
}
public void Run(string hostCode,string tagCode,int startPoint,int endPoint)
{
//收到提升机调度任务
// 1、读取 RFID 条码
// 2、下发提升机任务起点、终点
// 3、等待提升机完成任务
RefreshDeviceParams(hostCode,out List<BaseDeviceInfo> deviceInfos);
}
public 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}");
}
}
}

@ -34,6 +34,11 @@ public class HoistControlDto
/// </summary>
public string hoistCode { get; set; }
/// <summary>
/// 设备序号
/// </summary>
public int deviceSerialNo{get;set;}
/// <summary>
/// 动作
/// </summary>

@ -37,6 +37,11 @@ public class HoistTaskExeDto
/// </summary>
public string taskCode { get; set; }
/// <summary>
/// 设备序号
/// </summary>
public int deviceSerialNo{get;set;}
/// <summary>
/// 起点
/// </summary>

@ -24,6 +24,7 @@
#endregion << 版 本 注 释 >>
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Sln.Wcs.HoistSdk.Config;
using Sln.Wcs.HoistSdk.Dto.GetHoistStatus;
using Sln.Wcs.HoistSdk.Dto.HoistControl;
@ -50,8 +51,9 @@ public class HoistSdk:IHoistSdk
HoistControlResultDto result = new HoistControlResultDto();
try
{
string paramAddress = GetPlcParam(hoistControlDto.hoistCode,hoistControlDto.deviceSerialNo,"放置完成");
var plc = _plcs.Where(x => x.ConfigKey.Equals(hoistControlDto.hoistCode)).ToList().First();
var res = plc.writeInt16ByAddress(_hoistConfig.hoist_control_addr, (int)hoistControlDto.action);
var res = plc.writeInt16ByAddress(paramAddress, (int)hoistControlDto.action);
if (res)
{
result.code = "0";
@ -73,7 +75,29 @@ public class HoistSdk:IHoistSdk
public HoistTaskExeResultDto HoistTaskExecutor(HoistTaskExeDto hoistTaskExeDto)
{
throw new NotImplementedException();
HoistTaskExeResultDto result = new HoistTaskExeResultDto();
try
{
string paramAddress = GetPlcParam(hoistTaskExeDto.hoistCode,hoistTaskExeDto.deviceSerialNo,"任务执行指令");
var plc = _plcs.Where(x => x.ConfigKey.Equals(hoistTaskExeDto.hoistCode)).ToList().First();
var res = plc.writeInt16ByAddress(paramAddress, hoistTaskExeDto.endPoint);
if (res)
{
result.code = "0";
result.message = "写入成功";
}
else
{
result.code = "99";
result.message = "写入失败";
}
}
catch (Exception e)
{
result.code = "99";
result.message = e.Message;
}
return result;
}
public GetHoistStatusResultDto GetHoistStatus(GetHoistStatusDto hoistStatusDto)
@ -97,18 +121,18 @@ public class HoistSdk:IHoistSdk
if (item.hostCode == hoistStatusDto.hoistCode)
{
// var plc = _plcs.Where(x => x.ConfigKey.Equals(item.hostCode)).FirstOrDefault();
// if (plc == null)
// {
// result.code = "99";
// result.message = $"未找到PLC: {item.hostCode}";
// result.hoistCode = hoistStatusDto.hoistCode;
// return result;
// }
//
var plc = _plcs.Where(x => x.ConfigKey.Equals(item.hostCode)).FirstOrDefault();
if (plc == null)
{
result.code = "99";
result.message = $"未找到PLC: {item.hostCode}";
result.hoistCode = hoistStatusDto.hoistCode;
return result;
}
foreach (var param in item.deviceParams)
{
//int value = plc.readInt16ByAddress(param.paramAddress);
int value = plc.readInt16ByAddress(param.paramAddress);
param.paramValue = param.objId;
@ -138,5 +162,20 @@ public class HoistSdk:IHoistSdk
}
return result;
}
private string GetPlcParam(string hostCode,int deviceSerialNo,string paramName)
{
List<dynamic> paramStr = JsonConvert.DeserializeObject<List<dynamic>>(_hoistConfig.hoist_plc_param);
dynamic deviceInfo = paramStr.Where(x => x.hostCode == hostCode && x.deviceSerialNo == deviceSerialNo)
.FirstOrDefault();
List<dynamic> deviceParams = (deviceInfo.deviceParams as JArray)?.ToObject<List<dynamic>>();
dynamic deviceParam = deviceParams
.Where(x => ((string)x.paramName).Contains(paramName) && (int)x.operationType == 2).FirstOrDefault();
return deviceParam.paramAddress;
}
}

@ -60,12 +60,16 @@ namespace Sln.Wcs.Model.Domain
public string deviceName { get; set; }
/// <summary>
/// Desc:主机编号
/// Default:
/// Nullable:False
/// 设备别名
/// </summary>
[SugarColumn(ColumnName = "host_code")]
public string hostCode { get; set; }
[SugarColumn(ColumnName = "device_alias")]
public string deviceAlias { get; set; }
/// <summary>
/// 设备序号
/// </summary>
[SugarColumn(ColumnName = "device_serialNo")]
public int deviceSerialNo { get; set; }
/// <summary>
/// Desc:设备类型0-输送线1-AGV2-提升机
@ -82,6 +86,14 @@ namespace Sln.Wcs.Model.Domain
/// </summary>
[SugarColumn(ColumnName = "device_status")]
public int? deviceStatus { get; set; }
/// <summary>
/// Desc:主机编号
/// Default:
/// Nullable:False
/// </summary>
[SugarColumn(ColumnName = "host_code")]
public string hostCode { get; set; }
/// <summary>
/// Desc:是否标识1-是0-否

@ -52,6 +52,8 @@ namespace Sln.Wcs.Repository.service.Impl
deviceName = device.deviceName,
deviceType = device.deviceType,
deviceStatus = device.deviceStatus,
deviceSerialNo = device.deviceSerialNo,
deviceAlias = device.deviceAlias,
hostCode = device.hostCode,
isFlag = device.isFlag,
remark = device.remark,

@ -13,8 +13,11 @@ using Sln.Wcs.HikRoBotAdapter.Domain.Dto.GenAgvSchedulingTask;
using Sln.Wcs.HikRoBotAdapter.Service;
using Sln.Wcs.HikRoBotAdapter.Service.Impl;
using Sln.Wcs.HoistAdapter.Service;
using Sln.Wcs.HoistDispatcher;
using Sln.Wcs.HoistSdk;
using Sln.Wcs.HoistSdk.Dto.GetHoistStatus;
using Sln.Wcs.HoistSdk.Dto.HoistControl;
using Sln.Wcs.HoistSdk.Enum;
using Sln.Wcs.Model.Domain;
using Sln.Wcs.Repository;
using Sln.Wcs.Repository.service;
@ -70,9 +73,6 @@ namespace Sln.Wcs
// }
// });
var service = serviceProvider.GetService<HoistDispatcher.HoistDispatcher>();
service.Run(string.Empty,"tagCode",1,2);
Task.Delay(-1).Wait();
}
@ -89,11 +89,11 @@ namespace Sln.Wcs
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HikRoBotAdapter.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HikRoBotSdk.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistAdapter.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistDispatcher.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistSdk.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Plc.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Business.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.Strategy.dll")),
Assembly.LoadFrom(Path.Combine(basePath, "Sln.Wcs.HoistDispatcher.dll")),
};
services.Scan(scan => scan.FromAssemblies(assemblies)

Loading…
Cancel
Save