响应处理

This commit is contained in:
quowingwang 2026-01-08 10:57:12 +08:00
parent e262528889
commit d832d4e20a
6 changed files with 100 additions and 55 deletions

View File

@ -89,6 +89,44 @@ namespace Infrastructure.Helper
return ParseReadRegistersResponse(response, numberOfRegisters);
}
/// <summary>
/// 读取离散输入功能码0x02对应DI/数字输入端口如X1-X8
/// </summary>
/// <param name="unitId">从站地址</param>
/// <param name="startAddress">起始地址0-based</param>
/// <param name="numberOfInputs">离散输入数量</param>
/// <returns>离散输入状态列表true=导通/按下false=断开/未按下)</returns>
public List<bool> ReadDiscreteInputs(byte unitId, ushort startAddress, ushort numberOfInputs)
{
var request = BuildReadRequest(unitId, 0x02, startAddress, numberOfInputs);
var response = SendAndReceive(request);
return ParseReadDiscreteInputsResponse(response, numberOfInputs);
}
/// <summary>
/// 解析离散输入响应功能码02逻辑和读线圈一致
/// </summary>
private List<bool> ParseReadDiscreteInputsResponse(byte[] response, ushort expectedCount)
{
// 功能码校验02=读离散输入)
if (response[7] != 0x02)
throw new Exception($"Modbus异常功能码={response[7]:X2}预期02");
var byteCount = response[8];
var expectedBytes = (expectedCount + 7) / 8; // 位转字节,向上取整
if (byteCount != expectedBytes)
throw new Exception($"响应字节数与预期不符:实际={byteCount},预期={expectedBytes}");
var discreteInputs = new List<bool>();
for (int i = 0; i < expectedCount; i++)
{
var byteIndex = 9 + i / 8; // 每个字节存8个位
var bitIndex = i % 8; // 字节内的位索引
var mask = (byte)(1 << bitIndex);
discreteInputs.Add((response[byteIndex] & mask) != 0);
}
return discreteInputs;
}
/// <summary>
/// 写入单个保持寄存器功能码0x06
/// </summary>

View File

@ -122,7 +122,7 @@ builder.Services.Configure<ApiBehaviorOptions>((o) =>
//手表通知配置
builder.Services.AddSingleton<SocketGatewayServer>(provider =>
{
var server = new SocketGatewayServer("192.168.1.56", 8877); // 你可以按需修改 IP 和端口
var server = new SocketGatewayServer("192.168.60.56", 8877); // 你可以按需修改 IP 和端口
server.Start(); // 项目启动时立即启动监听
//server.StartReceiving();
@ -144,8 +144,6 @@ builder.Services.AddSingleton<AlarmLightModbus>(provider =>
var modbus = new AlarmLightModbus();
modbus.Connect("192.168.60.105", 10001); // 你可以按需修改 IP 和端口
return modbus;
});
// 2. 注册调漆房灯控监听类
@ -160,6 +158,20 @@ builder.Services.AddSingleton<TiaoQiFangLight>(provider =>
return lightListener;
});
var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var serviceProvider = scope.ServiceProvider;
try
{
// 主动获取实例,强制执行上面的工厂方法
var tiaoQiFangLight = serviceProvider.GetRequiredService<TiaoQiFangLight>();
app.Logger.LogInformation("调漆房灯控监听已强制启动");
}
catch (Exception ex)
{
app.Logger.LogError(ex, "调漆房灯控监听启动失败");
}
}
InternalApp.ServiceProvider = app.Services;
InternalApp.Configuration = builder.Configuration;
InternalApp.WebHostEnvironment = app.Environment;

View File

@ -16,7 +16,8 @@
//
// "Conn": "Data Source=47.116.122.230;Port=3307;User ID=root;Password=123456;Initial Catalog=ZrAdmin;",
//"Conn": "Data Source=139.224.232.211;User ID=root;Password=doantech123;Initial Catalog=ZrAdmin;Port=3308;AllowLoadLocalInfile=true",
"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog=ZrAdmin;Port=3306;AllowLoadLocalInfile=true",
//"Conn": "Data Source=192.168.1.48;User ID=root;Password=123456;Initial Catalog=ZrAdmin;Port=3306;AllowLoadLocalInfile=true",
"Conn": "Data Source=127.0.0.1;User ID=root;Password=123456;Initial Catalog=ZrAdmin;Port=3306;AllowLoadLocalInfile=true",
//
// "Conn": "Data Source=192.168.60.251;Port=3306;User ID=root;Password=123456;Initial Catalog=ZrAdmin;",
//

View File

@ -41,9 +41,9 @@ namespace ZR.Admin.WebApi.background
await Task.Delay(1000, stoppingToken);
// 测试Socket推送功能
string strWatchAddress = "181-127-162-058";
var result = Watchup.StartPush("测试Socket推送功能", _socketGateway, strWatchAddress);
_logger.LogInformation($"Socket推送测试结果: {result}");
//string strWatchAddress = "181-127-162-058";
//var result = Watchup.StartPush("测试Socket推送功能", _socketGateway, strWatchAddress);
//_logger.LogInformation($"Socket推送测试结果: {result}");
//TestLight();
TestTiaoQiIOModel();
}

View File

@ -2,6 +2,7 @@
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -19,7 +20,7 @@ namespace ZR.Service.Utils.MyAlarmLigth
private const int DI_COUNT = 8;
// 依赖注入(仅保留核心依赖)
private readonly ModbusTcpClientHelper _modbusClient;
private readonly AlarmLightModbus _modbusClient;
private readonly ILogger<TiaoQiFangLight> _logger;
// 状态缓存+监听控制(精简命名)
@ -30,7 +31,7 @@ namespace ZR.Service.Utils.MyAlarmLigth
/// <summary>
/// 构造函数(精简参数,日志可选)
/// </summary>
public TiaoQiFangLight(ModbusTcpClientHelper modbusClient, ILogger<TiaoQiFangLight> logger = null)
public TiaoQiFangLight(AlarmLightModbus modbusClient, ILogger<TiaoQiFangLight> logger = null)
{
_modbusClient = modbusClient;
_logger = logger;
@ -50,7 +51,6 @@ namespace ZR.Service.Utils.MyAlarmLigth
_cts = new CancellationTokenSource();
_listenTask = Task.Run(() => ListenDiLoop(_cts.Token), _cts.Token);
_logger?.LogInformation($"✅ 启动X1-X8监听轮询间隔{POLLING_INTERVAL_MS}ms");
}
/// <summary>
@ -74,43 +74,45 @@ namespace ZR.Service.Utils.MyAlarmLigth
{
try
{
// 1. 读取X1-X8状态对齐测试代码的ReadInputRegisters写法
List<ushort> diValues = _modbusClient.ReadInputRegisters(MODBUS_SLAVE_ID, DI_START_ADDR, DI_COUNT);
// ====== 关键修改用ReadDiscreteInputs读取DI端口 ======
List<bool> diStates = _modbusClient.ReadDiscreteInputs(
MODBUS_SLAVE_ID,
DI_START_ADDR,
(ushort)DI_COUNT // 转为ushort匹配方法参数
);
// 2. 结果校验(精简判断逻辑)
if (diValues == null || diValues.Count != DI_COUNT)
// 结果校验
if (diStates == null || diStates.Count != DI_COUNT)
{
_logger?.LogError($"❌ 读取X1-X8失败返回值数量异常预期{DI_COUNT}个,实际{diValues?.Count ?? 0}个)");
await Task.Delay(POLLING_INTERVAL_MS, cancellationToken);
continue;
}
// 3. 检测状态变化(精简遍历逻辑)
for (int i = 0; i < DI_COUNT; i++)
{
bool isPressed = diValues[i] == 1;
bool isPressed = diStates[i]; // true=按下false=未按下
string portName = $"X{i + 1}";
// 仅“从未按下→按下”时触发(精简条件判断)
// 仅“从未按下→按下”时触发
if (isPressed && !_lastDiState[i])
{
_logger?.LogInformation($"📌 检测到{portName}按下,触发灯控方法");
TriggerLightMethod(i + 1); // X1=1直接传端口号
TriggerLightMethod(i + 1);
}
_lastDiState[i] = isPressed; // 更新缓存
}
}
// 分类捕获异常(对齐测试代码的异常分类)
catch (OperationCanceledException)
{
_logger?.LogInformation("监听循环被取消,正常退出");
break;
}
catch (Exception cmdEx)
{
_logger?.LogError(cmdEx, $"❌ 读取DI状态异常");
}
await Task.Delay(POLLING_INTERVAL_MS, cancellationToken);
}
}
/// <summary>
/// 触发灯控方法(精简逻辑,仅保留核心映射)
/// </summary>
@ -124,9 +126,11 @@ namespace ZR.Service.Utils.MyAlarmLigth
// 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}触发:红灯闪烁");
@ -138,16 +142,6 @@ namespace ZR.Service.Utils.MyAlarmLigth
case 5:
_logger?.LogInformation($"✅ X{portNumber}触发:绿灯常亮");
break;
// X6-X8 → 黄灯(精简默认逻辑)
case 6:
_logger?.LogInformation($"✅ X{portNumber}触发:黄灯常亮");
break;
case 7:
_logger?.LogInformation($"✅ X{portNumber}触发:黄灯常亮");
break;
case 8:
_logger?.LogInformation($"✅ X{portNumber}触发:黄灯常亮");
break;
}
}
catch (Exception ex)

View File

@ -830,27 +830,27 @@ namespace ZR.Service.mes.andon
public ApiResult InitAlarmLightStates()
{
//var lights = andonAlarmAreaLightDicService.GetList();
//if (lights.Any())
//{
// foreach (var item in lights)
// {
// if (!string.IsNullOrEmpty(item.Lightip))
// {
// byte bLightIp = Convert.ToByte(item.Lightip);
// if (bLightIp != 0)
// {
// LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, bLightIp);
// }
// }
// }
//}
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(14));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(08));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(07));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(13));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(04));
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(15));
var lights = andonAlarmAreaLightDicService.GetList();
if (lights.Any())
{
foreach (var item in lights)
{
if (!string.IsNullOrEmpty(item.Lightip))
{
byte bLightIp = Convert.ToByte(item.Lightip);
if (bLightIp != 0)
{
LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, bLightIp);
}
}
}
}
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(14));
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(08));
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(07));
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(13));
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(04));
//LightUp.CheckLightOnStatusAndTurnOn(_modbusClient, Convert.ToByte(15));
return ApiResult.Success("处理成功");
}
}