啊鑫
2025-08-01 bc55470b84ecaa1e2f6397a3ec33f0c7192224c5
UniversalModbusManager.cs
@@ -363,13 +363,13 @@
            
            LogWarning($"将在 {delay}ms 后尝试第 {_retryCount} 次重连");
            Task.Delay(delay, _cancellationTokenSource.Token).ContinueWith(async _ =>
            Task.Delay(delay, _cancellationTokenSource?.Token ?? CancellationToken.None).ContinueWith(async _ =>
            {
                if (!_cancellationTokenSource.Token.IsCancellationRequested)
                if (!(_cancellationTokenSource?.Token.IsCancellationRequested ?? true))
                {
                    await ConnectAsync();
                }
            }, _cancellationTokenSource.Token);
            }, _cancellationTokenSource?.Token ?? CancellationToken.None);
        }
        #endregion
@@ -536,12 +536,27 @@
                    // 读取原始寄存器数据
                    var registers = await Task.Run(() => 
                        _modbusClient.ReadHoldingRegisters(fieldConfig.Address, fieldConfig.Length));
                    // 验证寄存器读取结果的有效性
                    ValidateRegisterData(fieldName, fieldConfig, registers);
                    // 检查读取结果是否为null
                    if (registers == null)
                    {
                        LogWarning($"字段 '{fieldName}' 读取结果为null,地址: {fieldConfig.Address}, 长度: {fieldConfig.Length}");
                        continue;
                    }
                    // 记录原始寄存器数据用于调试
                    LogDebug($"[RAW-DATA] 字段 '{fieldName}' 原始寄存器: [{string.Join(", ", registers)}] (十六进制: [{string.Join(", ", registers.Select(r => $"0x{r:X4}"))}])");
                    // 详细记录每个寄存器的字节分解
                    for (int i = 0; i < registers.Length; i++)
                    {
                        var reg = registers[i];
                        var highByte = (byte)((reg >> 8) & 0xFF);
                        var lowByte = (byte)(reg & 0xFF);
                        LogDebug($"[RAW-DATA] 寄存器{i}: {reg} (0x{reg:X4}) → 高字节:{highByte}('{(char)highByte}') 低字节:{lowByte}('{(char)lowByte}')");
                    }
                    // 验证数据长度
@@ -601,6 +616,98 @@
        #endregion
        #region 数据验证方法
        /// <summary>
        /// 验证寄存器数据的有效性
        /// </summary>
        /// <param name="fieldName">字段名</param>
        /// <param name="fieldConfig">字段配置</param>
        /// <param name="registers">读取的寄存器数据</param>
        private void ValidateRegisterData(string fieldName, DataField fieldConfig, int[]? registers)
        {
            if (registers == null)
            {
                LogWarning($"[VALIDATE] 字段 '{fieldName}' 寄存器数据为null");
                return;
            }
            LogDebug($"[VALIDATE] 字段 '{fieldName}' 原始数据验证:");
            LogDebug($"[VALIDATE] - 地址: {fieldConfig.Address}, 期望长度: {fieldConfig.Length}, 实际长度: {registers.Length}");
            LogDebug($"[VALIDATE] - 数据类型: {fieldConfig.DataType}");
            // 检查数据长度
            if (registers.Length != fieldConfig.Length)
            {
                LogWarning($"[VALIDATE] 字段 '{fieldName}' 数据长度不匹配: 期望{fieldConfig.Length}, 实际{registers.Length}");
            }
            // 检查是否包含有效数据
            var hasNonZeroData = registers.Any(r => r != 0);
            if (!hasNonZeroData)
            {
                LogWarning($"[VALIDATE] 字段 '{fieldName}' 所有寄存器都为0,可能是无效数据");
            }
            // 检查数据范围(16位有符号整数范围)
            var outOfRangeCount = registers.Count(r => r < -32768 || r > 32767);
            if (outOfRangeCount > 0)
            {
                LogWarning($"[VALIDATE] 字段 '{fieldName}' 有{outOfRangeCount}个寄存器值超出16位有符号整数范围");
            }
            // 特殊数据模式检测
            DetectSpecialDataPatterns(fieldName, registers);
        }
        /// <summary>
        /// 检测特殊的数据模式
        /// </summary>
        /// <param name="fieldName">字段名</param>
        /// <param name="registers">寄存器数据</param>
        private void DetectSpecialDataPatterns(string fieldName, int[] registers)
        {
            // 检测全FF模式(通信错误)
            if (registers.All(r => r == -1 || r == 0xFFFF))
            {
                LogWarning($"[PATTERN] 字段 '{fieldName}' 检测到全FF模式,可能是通信错误");
            }
            // 检测常见的错误码模式
            if (registers.Length >= 2)
            {
                var combined = ((long)((uint)registers[0] & 0xFFFF) << 16) | ((uint)registers[1] & 0xFFFF);
                if (combined == 0xE2400001)
                {
                    LogInfo($"[PATTERN] 字段 '{fieldName}' 检测到已知的无效数据标识 0xE2400001");
                }
            }
            // 检测ASCII字符模式(用于字符串和时间戳字段)
            if (registers.Any(r => IsLikelyAsciiData(r)))
            {
                LogDebug($"[PATTERN] 字段 '{fieldName}' 包含可能的ASCII字符数据");
            }
        }
        /// <summary>
        /// 检查寄存器值是否可能包含ASCII字符
        /// </summary>
        /// <param name="register">寄存器值</param>
        /// <returns>是否可能是ASCII数据</returns>
        private bool IsLikelyAsciiData(int register)
        {
            if (register == 0) return false;
            var highByte = (byte)((register >> 8) & 0xFF);
            var lowByte = (byte)(register & 0xFF);
            // 检查是否为可打印ASCII字符范围(32-126)
            return (highByte >= 32 && highByte <= 126) || (lowByte >= 32 && lowByte <= 126);
        }
        #endregion
        #region 数据发送方法
        /// <summary>
@@ -632,7 +739,7 @@
        /// <summary>
        /// 处理连接丢失
        /// </summary>
        private async Task HandleConnectionLoss()
        private Task HandleConnectionLoss()
        {
            if (_isConnected)
            {
@@ -647,6 +754,8 @@
                    ScheduleReconnect();
                }
            }
            return Task.CompletedTask;
        }
        #endregion