using Serilog;
|
using WIDESEAWCS_QuartzJob;
|
|
namespace WIDESEAWCS_Tasks
|
{
|
/// <summary>
|
/// 输送线目标地址选择器
|
/// </summary>
|
/// <remarks>
|
/// </remarks>
|
public class ConveyorLineTargetAddressSelector
|
{
|
/// <summary>
|
/// 日志记录器
|
/// </summary>
|
/// <remarks>
|
/// 通过 Microsoft.Extensions.Logging 接口注入,用于结构化日志输出。
|
/// </remarks>
|
private readonly ILogger _logger;
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
/// <param name="logger">日志记录器,由依赖注入容器自动注入</param>
|
public ConveyorLineTargetAddressSelector(ILogger logger)
|
{
|
_logger = logger; // 保存日志记录器实例,供后续方法使用
|
}
|
|
/// <summary>
|
/// 处理入库场景的下一地址请求
|
/// </summary>
|
/// <remarks>
|
/// 入库任务到达某个位置时调用此方法,判断目标设备是否需要物料。
|
/// 入库对应上层工位(Layer.Upper),因为物料从上层进入仓库。
|
/// </remarks>
|
/// <param name="conveyorLine">输送线设备对象,用于写入目标地址和 ACK 信号</param>
|
/// <param name="nextAddress">下一地址/目标设备编码,用于识别目标设备类型</param>
|
/// <param name="childDeviceCode">当前子设备编码,用于精确定位写入哪个子设备</param>
|
public bool HandleInboundNextAddress(CommonConveyorLine conveyorLine, string nextAddress, string childDeviceCode)
|
{
|
// 记录入库场景的调试日志,包含子设备和目标地址信息
|
WriteDebug(conveyorLine, "入库下一地址", childDeviceCode, nextAddress);
|
|
var cvState = conveyorLine.GetValue<ConveyorLineDBNameNew, byte>(ConveyorLineDBNameNew.CV_State, nextAddress);
|
bool isAvailable = cvState == 2;
|
if (isAvailable)
|
{
|
return conveyorLine.SetValue(ConveyorLineDBNameNew.Target, Convert.ToInt16(nextAddress), childDeviceCode);
|
}
|
return false;
|
}
|
|
/// <summary>
|
/// 处理出库场景的下一地址请求
|
/// </summary>
|
/// <remarks>
|
/// 出库任务到达某个位置时调用此方法,判断目标设备是否需要出料。
|
/// 出库对应下层工位(Layer.Lower),因为物料从下层离开仓库。
|
/// </remarks>
|
/// <param name="conveyorLine">输送线设备对象,用于写入目标地址和 ACK 信号</param>
|
/// <param name="nextAddress">下一地址/目标设备编码,用于识别目标设备类型</param>
|
/// <param name="childDeviceCode">当前子设备编码,用于精确定位写入哪个子设备</param>
|
public bool HandleOutboundNextAddress(CommonConveyorLine conveyorLine, string nextAddress, string childDeviceCode)
|
{
|
// 记录出库场景的调试日志,包含子设备和目标地址信息
|
WriteDebug(conveyorLine, "出库下一地址", childDeviceCode, nextAddress);
|
|
var cvState = conveyorLine.GetValue<ConveyorLineDBNameNew, byte>(ConveyorLineDBNameNew.CV_State, nextAddress);
|
bool isAvailable = cvState == 2;
|
if (isAvailable)
|
{
|
return conveyorLine.SetValue(ConveyorLineDBNameNew.Target, Convert.ToInt16(nextAddress), childDeviceCode);
|
}
|
return false;
|
}
|
/// <summary>
|
/// 写入调试日志(同时输出到两个日志系统)
|
/// </summary>
|
/// <remarks>
|
/// 统一入口点日志格式,同时向 Microsoft.Extensions.Logging 和 QuartzLogger 写入,
|
/// 保证日志既能在控制台查看也能在文件中追溯。
|
/// </remarks>
|
/// <param name="conveyorLine">输送线设备对象,用于获取设备编码写入 QuartzLogger</param>
|
/// <param name="scenario">场景描述,如"入库下一地址"或"出库下一地址"</param>
|
/// <param name="childDeviceCode">子设备编码</param>
|
/// <param name="nextAddress">目标设备编码</param>
|
private void WriteDebug(CommonConveyorLine conveyorLine, string scenario, string childDeviceCode, string nextAddress)
|
{
|
// 写入结构化日志(可被 Serilog 等日志框架捕获)
|
QuartzLogHelper.LogDebug(_logger, "Handle{Scenario}:子设备: {ChildDeviceCode},目标地址: {NextAddress}", $"Handle{scenario}:子设备: {childDeviceCode},目标地址: {nextAddress}", conveyorLine.DeviceCode, scenario, childDeviceCode, nextAddress);
|
}
|
}
|
}
|