From 1b3d57f133b494114c1cdd30627c7057eecdf1b1 Mon Sep 17 00:00:00 2001
From: 啊鑫 <t2856754968@163.com>
Date: 星期一, 28 七月 2025 10:02:51 +0800
Subject: [PATCH] 修复时间戳解析和数据验证逻辑
---
config/ModbusDataParser.cs | 98 +++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 82 insertions(+), 16 deletions(-)
diff --git a/config/ModbusDataParser.cs b/config/ModbusDataParser.cs
index 7ca9e9b..3c5ac79 100644
--- a/config/ModbusDataParser.cs
+++ b/config/ModbusDataParser.cs
@@ -92,28 +92,32 @@
// 鍙屽瘎瀛樺櫒锛屾牴鎹瓧鑺傚簭缁勫悎
if (config.Encoding?.ToLower() == "littleendian")
{
- // 灏忕锛氫綆浣嶅湪鍓�
+ // 灏忕锛氫綆浣嶅瘎瀛樺櫒鍦ㄥ墠锛岄珮浣嶅瘎瀛樺櫒鍦ㄥ悗
value = (registers[0] & 0xFFFF) | ((long)(registers[1] & 0xFFFF) << 16);
}
else
{
- // 澶х锛氶珮浣嶅湪鍓嶏紙榛樿锛�
+ // PLC榛樿浣跨敤澶х鏍煎紡杩涜澶氬瘎瀛樺櫒缁勫悎锛氶珮浣嶅瘎瀛樺櫒鍦ㄥ墠锛屼綆浣嶅瘎瀛樺櫒鍦ㄥ悗
value = ((long)(registers[0] & 0xFFFF) << 16) | (registers[1] & 0xFFFF);
}
- // 妫�鏌ユ槸鍚︿负鏃犳晥鏁版嵁鏍囪瘑锛堝璐熷�肩粍鍚堬級
- if (value == 0xE2400001 || value > 0x7FFFFFFF)
+ Console.WriteLine($"[PARSER-DEBUG] 鍙屽瘎瀛樺櫒缁勫悎: [{registers[0]}, {registers[1]}] 鈫� 0x{value:X8} ({value})");
+
+ // 妫�鏌ユ槸鍚︿负鏃犳晥鏁版嵁鏍囪瘑
+ if (IsInvalidData(registers, value))
{
- // 鍙兘鏄棤鏁堟暟鎹紝杩斿洖0鎴栦娇鐢ㄧ壒娈婃爣璇�
+ Console.WriteLine($"[PARSER-DEBUG] 妫�娴嬪埌鏃犳晥鏁版嵁鏍囪瘑锛岃繑鍥�0");
return 0;
}
}
else
{
// 澶氬瘎瀛樺櫒锛氭寜澶х椤哄簭缁勫悎
+ Console.WriteLine($"[PARSER-DEBUG] 澶氬瘎瀛樺櫒缁勫悎 ({config.Length}涓�): [{string.Join(", ", registers.Take(config.Length))}]");
for (int i = 0; i < Math.Min(registers.Length, config.Length); i++)
{
value = (value << 16) | (registers[i] & 0xFFFF);
+ Console.WriteLine($"[PARSER-DEBUG] 姝ラ{i+1}: 0x{value:X} (瀵勫瓨鍣▄i}: {registers[i]})");
}
}
@@ -123,7 +127,9 @@
var scaledValue = value * config.Scale;
return Math.Round(scaledValue, config.DecimalPlaces);
}
-
+
+ // 濡傛灉娌℃湁閰嶇疆缂╂斁锛屾暣鏁版暟鎹粯璁よ繑鍥炲師濮嬪�硷紙涓嶅啀鑷姩搴旂敤灏忔暟杞崲锛�
+ // 鏍规嵁閰嶇疆鏂囦欢锛屾祴閲忔暟鎹凡缁忛厤缃簡Scale: 0.01锛屾墍浠ヤ細璧颁笂闈㈢殑鍒嗘敮
return value;
}
@@ -135,23 +141,27 @@
if (registers.Length == 0) return string.Empty;
var bytes = new List<byte>();
+ Console.WriteLine($"[PARSER-DEBUG] 瀛楃涓茶В鏋� ({config.Length}涓瘎瀛樺櫒): [{string.Join(", ", registers.Take(config.Length).Select(r => $"0x{r:X4}"))}]");
foreach (var register in registers.Take(config.Length))
{
if (config.Encoding?.ToLower() == "littleendian")
{
- // 灏忕锛氫綆瀛楄妭鍦ㄥ墠
+ // 灏忕锛氫綆瀛楄妭鍦ㄥ墠锛岄珮瀛楄妭鍦ㄥ悗
bytes.Add((byte)(register & 0xFF));
bytes.Add((byte)((register >> 8) & 0xFF));
}
else
{
- // 澶х锛氶珮瀛楄妭鍦ㄥ墠锛堥粯璁わ級
- // 娉ㄦ剰锛氭牴鎹疄闄匬LC鏁版嵁锛屽瓧鑺傞『搴忔槸鍙嶇殑
- var highByte = (byte)((register >> 8) & 0xFF);
- var lowByte = (byte)(register & 0xFF);
+ // PLC瀛楃涓插瓨鍌ㄦ牸寮忥細瀵勫瓨鍣ㄥ�奸渶瑕佸瓧鑺傚弽搴忓鐞�
+ // 渚嬪锛氬瘎瀛樺櫒0x6261涓紝0x62='b', 0x61='a'锛屼絾鏈熸湜杈撳嚭"ab"
+ // 鍥犳闇�瑕佸厛杈撳嚭浣庡瓧鑺�'a'锛屽啀杈撳嚭楂樺瓧鑺�'b'
+ var highByte = (byte)((register >> 8) & 0xFF); // 瀹為檯鏄浜屼釜瀛楃
+ var lowByte = (byte)(register & 0xFF); // 瀹為檯鏄涓�涓瓧绗�
- // 鍏堟坊鍔犱綆瀛楄妭锛屽啀娣诲姞楂樺瓧鑺傦紙閫傚簲PLC鐨勫瓧鑺傚簭锛�
+ Console.WriteLine($"[PARSER-DEBUG] 瀵勫瓨鍣�0x{register:X4} 鈫� 浣庡瓧鑺�:'{(char)lowByte}' 楂樺瓧鑺�:'{(char)highByte}'");
+
+ // 鎸夋湡鏈涢『搴忥細鍏堟坊鍔犱綆瀛楄妭锛屽啀娣诲姞楂樺瓧鑺�
if (lowByte != 0) bytes.Add(lowByte);
if (highByte != 0) bytes.Add(highByte);
}
@@ -163,7 +173,9 @@
bytes.RemoveAt(bytes.Count - 1);
}
- return Encoding.ASCII.GetString(bytes.ToArray());
+ var result = Encoding.ASCII.GetString(bytes.ToArray());
+ Console.WriteLine($"[PARSER-DEBUG] 瀛楃涓茶В鏋愮粨鏋�: '{result}'");
+ return result;
}
/// <summary>
@@ -208,20 +220,28 @@
{
if (registers.Length < 2) return 0.0f;
+ Console.WriteLine($"[PARSER-DEBUG] 娴偣鏁拌В鏋�: [{registers[0]}, {registers[1]}] (0x{registers[0]:X4}, 0x{registers[1]:X4})");
+
// IEEE 754鍗曠簿搴︽诞鐐规暟闇�瑕�2涓瘎瀛樺櫒锛�32浣嶏級
uint value;
if (config.Encoding?.ToLower() == "littleendian")
{
+ // 灏忕锛氫綆浣嶅瘎瀛樺櫒鍦ㄥ墠锛岄珮浣嶅瘎瀛樺櫒鍦ㄥ悗
value = (uint)(registers[0] | (registers[1] << 16));
+ Console.WriteLine($"[PARSER-DEBUG] 灏忕缁勫悎: 0x{value:X8}");
}
else
{
+ // PLC榛樿浣跨敤澶х鏍煎紡杩涜澶氬瘎瀛樺櫒缁勫悎锛氶珮浣嶅瘎瀛樺櫒鍦ㄥ墠锛屼綆浣嶅瘎瀛樺櫒鍦ㄥ悗
value = (uint)((registers[0] << 16) | registers[1]);
+ Console.WriteLine($"[PARSER-DEBUG] 澶х缁勫悎: 0x{value:X8}");
}
// 灏�32浣嶆暣鏁拌浆鎹负娴偣鏁�
- return BitConverter.ToSingle(BitConverter.GetBytes(value), 0);
+ var result = BitConverter.ToSingle(BitConverter.GetBytes(value), 0);
+ Console.WriteLine($"[PARSER-DEBUG] 娴偣鏁拌В鏋愮粨鏋�: {result}");
+ return result;
}
/// <summary>
@@ -241,12 +261,14 @@
/// <summary>
/// 瑙f瀽鏃堕棿鎴冲瓧绗︿覆锛堥拡瀵规暟瀛楀瓧绗︽暟鎹級
+ /// 澶х妯″紡瀛樺偍锛氫竴涓瓧鑺備袱涓瓧绗︼紝鎸夋枃妗h姹傜殑椤哄簭鎻愬彇瀛楃
/// </summary>
private static string ParseTimestampString(int[] registers, DataField config)
{
if (registers.Length == 0) return string.Empty;
var chars = new List<char>();
+ Console.WriteLine($"[PARSER-DEBUG] 鏃堕棿鎴冲瘎瀛樺櫒鏁版嵁: [{string.Join(", ", registers.Take(config.Length).Select(r => $"0x{r:X4}({r})"))}]");
foreach (var register in registers.Take(config.Length))
{
@@ -256,8 +278,12 @@
var highByte = (byte)((register >> 8) & 0xFF);
var lowByte = (byte)(register & 0xFF);
- // 鎸塒LC鏁版嵁鏍煎紡娣诲姞瀛楃锛堝厛浣庡瓧鑺傦紝鍚庨珮瀛楄妭锛�
- // 妫�鏌ユ槸鍚︿负鏁板瓧瀛楃锛圓SCII 48-57, '0'-'9'锛�
+ Console.WriteLine($"[PARSER-DEBUG] 瀵勫瓨鍣�0x{register:X4}: 楂樺瓧鑺�=0x{highByte:X2}('{(char)highByte}'), 浣庡瓧鑺�=0x{lowByte:X2}('{(char)lowByte}')");
+
+ // 鏍规嵁鐢ㄦ埛鎻愪緵鐨勮В鏋愬鐓ц〃锛氬ぇ绔ā寮忥紝浣庡瓧鑺傚瓨鍦ㄩ珮鍦板潃锛岃В鏋愭椂楂樹綆鍦板潃瑕侀鍊�
+ // 鍗筹細鍏堝彇浣庡瓧鑺傦紝鍐嶅彇楂樺瓧鑺�
+ // 渚嬪锛�12338 = 0x3032 鈫� 浣庡瓧鑺�0x32='2'锛岄珮瀛楄妭0x30='0' 鈫� "20"
+
if (lowByte >= 48 && lowByte <= 57)
{
chars.Add((char)lowByte);
@@ -269,6 +295,7 @@
}
var result = new string(chars.ToArray());
+ Console.WriteLine($"[PARSER-DEBUG] 鏃堕棿鎴宠В鏋愮粨鏋�: '{result}'");
return result;
}
@@ -327,6 +354,45 @@
#region 宸ュ叿鏂规硶
/// <summary>
+ /// 妫�娴嬫槸鍚︿负鏃犳晥鏁版嵁鏍囪瘑
+ /// </summary>
+ /// <param name="registers">鍘熷瀵勫瓨鍣ㄦ暟鎹�</param>
+ /// <param name="combinedValue">缁勫悎鍚庣殑鍊�</param>
+ /// <returns>鏄惁涓烘棤鏁堟暟鎹�</returns>
+ private static bool IsInvalidData(int[] registers, long combinedValue)
+ {
+ // 甯歌鏃犳晥鏁版嵁妯″紡妫�娴�
+
+ // 1. 妫�鏌ユ槸鍚︿负鍏‵F妯″紡锛堥�氬父琛ㄧず閫氫俊閿欒锛�
+ if (combinedValue == 0xFFFFFFFF)
+ {
+ return true;
+ }
+
+ // 2. 妫�鏌ユ槸鍚︿负鍏�0锛堝彲鑳借〃绀烘湭鍒濆鍖栵級
+ if (combinedValue == 0)
+ {
+ return true;
+ }
+
+ // 3. 鐗瑰畾鐨勯敊璇爜妯″紡锛欵240xxxx
+ if ((combinedValue & 0xFFFF0000) == 0xE2400000)
+ {
+ Console.WriteLine($"[PARSER-DEBUG] 妫�娴嬪埌E240閿欒鐮佹ā寮�: 0x{combinedValue:X8}");
+ return true;
+ }
+
+ // 4. 妫�鏌ユ槸鍚︿负鍏稿瀷鐨勯敊璇粍鍚堬細绗竴涓瘎瀛樺櫒涓哄ぇ璐熸暟锛堝-7616锛夛紝绗簩涓负灏忔鏁�
+ if (registers.Length >= 2 && registers[0] == -7616 && registers[1] == 1)
+ {
+ Console.WriteLine($"[PARSER-DEBUG] 妫�娴嬪埌鐗瑰畾閿欒妯″紡: [{registers[0]}, {registers[1]}]");
+ return true;
+ }
+
+ return false;
+ }
+
+ /// <summary>
/// 鑾峰彇鏁版嵁绫诲瀷鐨勯粯璁ゅ��
/// </summary>
/// <param name="dataType">鏁版嵁绫诲瀷瀛楃涓�</param>
--
Gitblit v1.9.3