diff --git a/Infrastructure/Helper/ModbusTcpClientHelper.cs b/Infrastructure/Helper/ModbusTcpClientHelper.cs
index 0610361d..2a17928a 100644
--- a/Infrastructure/Helper/ModbusTcpClientHelper.cs
+++ b/Infrastructure/Helper/ModbusTcpClientHelper.cs
@@ -89,6 +89,44 @@ namespace Infrastructure.Helper
return ParseReadRegistersResponse(response, numberOfRegisters);
}
+ ///
+ /// 读取离散输入(功能码0x02,对应DI/数字输入端口,如X1-X8)
+ ///
+ /// 从站地址
+ /// 起始地址(0-based)
+ /// 离散输入数量
+ /// 离散输入状态列表(true=导通/按下,false=断开/未按下)
+ public List ReadDiscreteInputs(byte unitId, ushort startAddress, ushort numberOfInputs)
+ {
+ var request = BuildReadRequest(unitId, 0x02, startAddress, numberOfInputs);
+ var response = SendAndReceive(request);
+ return ParseReadDiscreteInputsResponse(response, numberOfInputs);
+ }
+
+ ///
+ /// 解析离散输入响应(功能码02,逻辑和读线圈一致)
+ ///
+ private List 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();
+ 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;
+ }
///
/// 写入单个保持寄存器(功能码0x06)
///
diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs
index c3a8a2d6..bea59cec 100644
--- a/ZR.Admin.WebApi/Program.cs
+++ b/ZR.Admin.WebApi/Program.cs
@@ -122,7 +122,7 @@ builder.Services.Configure((o) =>
//手表通知配置
builder.Services.AddSingleton(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(provider =>
var modbus = new AlarmLightModbus();
modbus.Connect("192.168.60.105", 10001); // 你可以按需修改 IP 和端口
-
-
return modbus;
});
// 2. 注册调漆房灯控监听类
@@ -160,6 +158,20 @@ builder.Services.AddSingleton(provider =>
return lightListener;
});
var app = builder.Build();
+using (var scope = app.Services.CreateScope())
+{
+ var serviceProvider = scope.ServiceProvider;
+ try
+ {
+ // 主动获取实例,强制执行上面的工厂方法
+ var tiaoQiFangLight = serviceProvider.GetRequiredService();
+ app.Logger.LogInformation("调漆房灯控监听已强制启动");
+ }
+ catch (Exception ex)
+ {
+ app.Logger.LogError(ex, "调漆房灯控监听启动失败");
+ }
+}
InternalApp.ServiceProvider = app.Services;
InternalApp.Configuration = builder.Configuration;
InternalApp.WebHostEnvironment = app.Environment;
diff --git a/ZR.Admin.WebApi/appsettings.development.json b/ZR.Admin.WebApi/appsettings.development.json
index fc981bf8..1e6aba5c 100644
--- a/ZR.Admin.WebApi/appsettings.development.json
+++ b/ZR.Admin.WebApi/appsettings.development.json
@@ -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;",
//内网连接服务器
diff --git a/ZR.Admin.WebApi/background/SocketBackgroundService.cs b/ZR.Admin.WebApi/background/SocketBackgroundService.cs
index 1732a968..58082ae3 100644
--- a/ZR.Admin.WebApi/background/SocketBackgroundService.cs
+++ b/ZR.Admin.WebApi/background/SocketBackgroundService.cs
@@ -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();
}
diff --git a/ZR.Service/Utils/MyAlarmLigth/TiaoQiFangLight.cs b/ZR.Service/Utils/MyAlarmLigth/TiaoQiFangLight.cs
index c3da8c9e..cead249a 100644
--- a/ZR.Service/Utils/MyAlarmLigth/TiaoQiFangLight.cs
+++ b/ZR.Service/Utils/MyAlarmLigth/TiaoQiFangLight.cs
@@ -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 _logger;
// 状态缓存+监听控制(精简命名)
@@ -30,7 +31,7 @@ namespace ZR.Service.Utils.MyAlarmLigth
///
/// 构造函数(精简参数,日志可选)
///
- public TiaoQiFangLight(ModbusTcpClientHelper modbusClient, ILogger logger = null)
+ public TiaoQiFangLight(AlarmLightModbus modbusClient, ILogger 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)");
}
///
@@ -74,43 +74,45 @@ namespace ZR.Service.Utils.MyAlarmLigth
{
try
{
- // 1. 读取X1-X8状态(对齐测试代码的ReadInputRegisters写法)
- List diValues = _modbusClient.ReadInputRegisters(MODBUS_SLAVE_ID, DI_START_ADDR, DI_COUNT);
+ // ====== 关键修改:用ReadDiscreteInputs读取DI端口 ======
+ List 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);
}
}
-
///
/// 触发灯控方法(精简逻辑,仅保留核心映射)
///
@@ -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)
diff --git a/ZR.Service/mes/andon/AndonAlarmRecordService.cs b/ZR.Service/mes/andon/AndonAlarmRecordService.cs
index 8e5f6807..3b086aff 100644
--- a/ZR.Service/mes/andon/AndonAlarmRecordService.cs
+++ b/ZR.Service/mes/andon/AndonAlarmRecordService.cs
@@ -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("处理成功");
}
}