162 lines
5.7 KiB
C#
Raw Normal View History

2026-01-06 08:49:12 +08:00
using Infrastructure.Helper;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
2026-01-08 10:57:12 +08:00
using System.Linq;
2026-01-06 08:49:12 +08:00
using System.Threading;
using System.Threading.Tasks;
namespace ZR.Service.Utils.MyAlarmLigth
{
/// <summary>
/// 调漆房IO端口监听+灯控类X1-X8监听 → 触发对应灯控方法)
/// </summary>
public class TiaoQiFangLight : IDisposable
{
// 核心配置(仅保留必要参数,对齐测试代码风格)
private const byte MODBUS_SLAVE_ID = 0x01;
private const ushort DI_START_ADDR = 0x0000;
private const int POLLING_INTERVAL_MS = 200;
private const int DI_COUNT = 8;
// 依赖注入(仅保留核心依赖)
2026-01-08 10:57:12 +08:00
private readonly AlarmLightModbus _modbusClient;
2026-01-06 08:49:12 +08:00
private readonly ILogger<TiaoQiFangLight> _logger;
// 状态缓存+监听控制(精简命名)
private readonly bool[] _lastDiState = new bool[DI_COUNT];
private CancellationTokenSource _cts;
private Task _listenTask;
/// <summary>
/// 构造函数(精简参数,日志可选)
/// </summary>
2026-01-08 10:57:12 +08:00
public TiaoQiFangLight(AlarmLightModbus modbusClient, ILogger<TiaoQiFangLight> logger = null)
2026-01-06 08:49:12 +08:00
{
_modbusClient = modbusClient;
_logger = logger;
Array.Fill(_lastDiState, false); // 初始化未按下
}
/// <summary>
/// 启动监听(精简逻辑,无冗余判断)
/// </summary>
public void StartListen()
{
if (_listenTask?.IsCompleted == false)
{
_logger?.LogWarning("调漆房IO监听已启动无需重复执行");
return;
}
_cts = new CancellationTokenSource();
_listenTask = Task.Run(() => ListenDiLoop(_cts.Token), _cts.Token);
}
/// <summary>
/// 停止监听(精简释放逻辑)
/// </summary>
public void StopListen()
{
if (_cts == null) return;
_cts.Cancel();
_listenTask?.Wait(1000);
_logger?.LogInformation("❌ 停止X1-X8监听");
}
/// <summary>
/// 核心轮询监听DI状态精简循环逻辑对齐测试代码异常处理
/// </summary>
private async Task ListenDiLoop(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
try
{
2026-01-08 10:57:12 +08:00
// ====== 关键修改用ReadDiscreteInputs读取DI端口 ======
List<bool> diStates = _modbusClient.ReadDiscreteInputs(
MODBUS_SLAVE_ID,
DI_START_ADDR,
(ushort)DI_COUNT // 转为ushort匹配方法参数
);
// 结果校验
if (diStates == null || diStates.Count != DI_COUNT)
2026-01-06 08:49:12 +08:00
{
await Task.Delay(POLLING_INTERVAL_MS, cancellationToken);
continue;
}
for (int i = 0; i < DI_COUNT; i++)
{
2026-01-08 10:57:12 +08:00
bool isPressed = diStates[i]; // true=按下false=未按下
2026-01-06 08:49:12 +08:00
string portName = $"X{i + 1}";
2026-01-08 10:57:12 +08:00
// 仅“从未按下→按下”时触发
2026-01-06 08:49:12 +08:00
if (isPressed && !_lastDiState[i])
{
2026-01-08 10:57:12 +08:00
TriggerLightMethod(i + 1);
2026-01-06 08:49:12 +08:00
}
_lastDiState[i] = isPressed; // 更新缓存
}
}
2026-01-08 10:57:12 +08:00
catch (OperationCanceledException)
{
_logger?.LogInformation("监听循环被取消,正常退出");
break;
}
2026-01-06 08:49:12 +08:00
catch (Exception cmdEx)
{
}
await Task.Delay(POLLING_INTERVAL_MS, cancellationToken);
}
}
/// <summary>
/// 触发灯控方法(精简逻辑,仅保留核心映射)
/// </summary>
private void TriggerLightMethod(int portNumber)
{
byte lightUnitId = 0x01; // 警灯站号可按需替换为ReadAlarmlightNumber
try
{
switch (portNumber)
{
// X1-X4 → 红灯
case 1:
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
2026-01-08 10:57:12 +08:00
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址
2026-01-06 08:49:12 +08:00
break;
case 2:
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
2026-01-08 10:57:12 +08:00
_modbusClient.WriteSingleCoil(lightUnitId, 1, false);
2026-01-06 08:49:12 +08:00
break;
case 3:
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
break;
case 4:
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
break;
// X5 → 绿灯
case 5:
_logger?.LogInformation($"✅ X{portNumber}触发:绿灯常亮");
break;
}
}
catch (Exception ex)
{
_logger?.LogError(ex, $"❌ X{portNumber}触发灯控方法失败");
}
}
/// <summary>
/// 释放资源精简Dispose
/// </summary>
public void Dispose()
{
StopListen();
_cts?.Dispose();
}
}
}