2026-01-08 18:36:10 +08:00

186 lines
7.5 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;
using ZR.Service.mes.andon;
using ZR.Service.mes.andon.Iservice;
using static System.Formats.Asn1.AsnWriter;
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;
//private AndonAlarmLevelService andonAlarmLevelService = new AndonAlarmLevelService();
/// <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
{
//X1、X2、X3红按钮X4绿按钮X5红按钮
//Y1蜂鸣器、Y2红灯、Y3黄灯、Y4绿灯
//Y1->0; Y2->1; y3->2; y4->3
switch (portNumber)
{
// X1→ 红按钮
case 1:
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址蜂鸣器
_modbusClient.WriteSingleCoil(lightUnitId, 1, true); //1-Y2地址红灯
_modbusClient.WriteSingleCoil(lightUnitId, 2, false); //2-Y3地址黄灯
_modbusClient.WriteSingleCoil(lightUnitId, 3, false); //3-Y4地址绿灯
break;
// X2→ 红按钮
case 2:
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址蜂鸣器
_modbusClient.WriteSingleCoil(lightUnitId, 1, true); //1-Y2地址红灯
_modbusClient.WriteSingleCoil(lightUnitId, 2, false); //2-Y3地址黄灯
_modbusClient.WriteSingleCoil(lightUnitId, 3, false); //3-Y4地址绿灯
break;
// X3→ 红按钮
case 3:
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址蜂鸣器
_modbusClient.WriteSingleCoil(lightUnitId, 1, true); //1-Y2地址红灯
_modbusClient.WriteSingleCoil(lightUnitId, 2, false); //2-Y3地址黄灯
_modbusClient.WriteSingleCoil(lightUnitId, 3, false); //3-Y4地址绿灯
break;
// X4→ 绿按钮
case 4:
_modbusClient.WriteSingleCoil(lightUnitId, 0, false); //0-Y1地址蜂鸣器
_modbusClient.WriteSingleCoil(lightUnitId, 1, false); //1-Y2地址红灯
_modbusClient.WriteSingleCoil(lightUnitId, 2, false); //2-Y3地址黄灯
_modbusClient.WriteSingleCoil(lightUnitId, 3, true); //3-Y4地址绿灯
break;
// X5 → 红按钮
case 5:
_modbusClient.WriteSingleCoil(lightUnitId, 0, true); //0-Y1地址蜂鸣器
_modbusClient.WriteSingleCoil(lightUnitId, 1, true); //1-Y2地址红灯
_modbusClient.WriteSingleCoil(lightUnitId, 2, false); //2-Y3地址黄灯
_modbusClient.WriteSingleCoil(lightUnitId, 3, false); //3-Y4地址绿灯
break;
}
}
catch (Exception ex)
{
_logger?.LogError(ex, $"❌ X{portNumber}触发灯控方法失败");
}
}
/// <summary>
/// 释放资源精简Dispose
/// </summary>
public void Dispose()
{
StopListen();
_cts?.Dispose();
}
}
}