168 lines
6.2 KiB
C#
168 lines
6.2 KiB
C#
using Infrastructure.Helper;
|
||
using Microsoft.Extensions.Logging;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
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;
|
||
|
||
// 依赖注入(仅保留核心依赖)
|
||
private readonly AlarmLightModbus _modbusClient;
|
||
private readonly ILogger<TiaoQiFangLight> _logger;
|
||
|
||
// 状态缓存+监听控制(精简命名)
|
||
private readonly bool[] _lastDiState = new bool[DI_COUNT];
|
||
private CancellationTokenSource _cts;
|
||
private Task _listenTask;
|
||
|
||
/// <summary>
|
||
/// 构造函数(精简参数,日志可选)
|
||
/// </summary>
|
||
public TiaoQiFangLight(AlarmLightModbus modbusClient, ILogger<TiaoQiFangLight> logger = null)
|
||
{
|
||
_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
|
||
{
|
||
// ====== 关键修改:用ReadDiscreteInputs读取DI端口 ======
|
||
List<bool> diStates = _modbusClient.ReadDiscreteInputs(
|
||
MODBUS_SLAVE_ID,
|
||
DI_START_ADDR,
|
||
(ushort)DI_COUNT // 转为ushort匹配方法参数
|
||
);
|
||
|
||
// 结果校验
|
||
if (diStates == null || diStates.Count != DI_COUNT)
|
||
{
|
||
await Task.Delay(POLLING_INTERVAL_MS, cancellationToken);
|
||
continue;
|
||
}
|
||
|
||
for (int i = 0; i < DI_COUNT; i++)
|
||
{
|
||
bool isPressed = diStates[i]; // true=按下,false=未按下
|
||
string portName = $"X{i + 1}";
|
||
|
||
// 仅“从未按下→按下”时触发
|
||
if (isPressed && !_lastDiState[i])
|
||
{
|
||
TriggerLightMethod(i + 1);
|
||
}
|
||
_lastDiState[i] = isPressed; // 更新缓存
|
||
}
|
||
}
|
||
catch (OperationCanceledException)
|
||
{
|
||
_logger?.LogInformation("监听循环被取消,正常退出");
|
||
break;
|
||
}
|
||
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}触发:红灯闪烁");
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址
|
||
break;
|
||
case 2:
|
||
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 1, true);
|
||
break;
|
||
case 3:
|
||
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 2, true);
|
||
break;
|
||
case 4:
|
||
_logger?.LogInformation($"✅ X{portNumber}触发:红灯闪烁");
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 3, true);
|
||
break;
|
||
// X5 → 绿灯
|
||
case 5:
|
||
_logger?.LogInformation($"✅ X{portNumber}触发:绿灯常亮");
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 0, false);
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 1, false);
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 2, false);
|
||
_modbusClient.WriteSingleCoil(lightUnitId, 3, false);
|
||
break;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger?.LogError(ex, $"❌ X{portNumber}触发灯控方法失败");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 释放资源(精简Dispose)
|
||
/// </summary>
|
||
public void Dispose()
|
||
{
|
||
StopListen();
|
||
_cts?.Dispose();
|
||
}
|
||
}
|
||
} |