2026-01-08 10:57:12 +08:00

162 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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, false);
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();
}
}
}