From 747a86bb94006aaca721cfc0c0ce7061643a9ea6 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期四, 20 八月 2026 12:19:35 +0800
Subject: [PATCH] gx

---
 jhm2028-service.js |   92 +++++++++++++++++++++++-----------------------
 1 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/jhm2028-service.js b/jhm2028-service.js
index 916225e..4db08c3 100644
--- a/jhm2028-service.js
+++ b/jhm2028-service.js
@@ -1,19 +1,19 @@
 #!/usr/bin/env node
 
 /**
- * JHM-2028 serial communication service.
+ * JHM-2028 串口调试服务。
  *
  * 当前项目正式运行入口是 `app.js`,通过 `tcp-service.js` 接收透传盒子的 TCP 数据。
  * 本文件保留为“串口直连调试参考脚本”,用于协议排查、串口联调和模拟数据验证。
  * 它不参与当前 TCP + MQTT 的生产主流程。
  *
- * Install:
+ * 安装依赖:
  *   npm install serialport
  *
- * Serial mode:
+ * 串口模式:
  *   node jhm2028-service.js --port COM3 --baudRate 4800
  *
- * Simulation mode:
+ * 模拟模式:
  *   node jhm2028-service.js --simulate "EE 55 01 00 00 01 72 74"
  */
 
@@ -80,25 +80,25 @@
 }
 
 function printHelp() {
-  console.log(`JHM-2028 Node.js serial communication service
+  console.log(`JHM-2028 Node.js 串口调试服务
 
-Usage:
+用法:
   node jhm2028-service.js --port COM3 [options]
   node jhm2028-service.js --simulate "EE 55 01 00 00 01 72 74"
 
-Options:
-  --port <name>         Serial port name, e.g. COM3
-  --baudRate <number>   Baud rate, default 4800
-  --dataBits <number>   Data bits, default 8
-  --stopBits <number>   Stop bits, default 1
-  --parity <value>      none | even | odd, default none
-  --raw                 Print raw incoming bytes in hex
-  --no-timestamp        Omit timestamp in JSON output
-  --simulate <hex>      Parse one or more hex bytes without opening a serial port
-  --help, -h            Show this help
+参数:
+  --port <name>         串口名称,例如 COM3
+  --baudRate <number>   波特率,默认 4800
+  --dataBits <number>   数据位,默认 8
+  --stopBits <number>   停止位,默认 1
+  --parity <value>      校验位:none | even | odd,默认 none
+  --raw                 以十六进制打印原始输入
+  --no-timestamp        JSON 输出中不带时间戳
+  --simulate <hex>      不打开串口,直接解析一段十六进制字节
+  --help, -h            显示帮助
 
-Protocol:
-  Frame = EE 55 NN XX1 XX2 XX3 XX4 CY
+协议格式:
+  帧格式 = EE 55 NN XX1 XX2 XX3 XX4 CY
   CY = (NN + XX1 + XX2 + XX3 + XX4) & 0xFF
 `);
 }
@@ -132,7 +132,7 @@
         raw,
         value: raw / 10,
         unit: '°C',
-        note: 'PDF example shows 0x00000172 => 370 => 37.0°C',
+        note: '协议文档示例:0x00000172 => 370 => 37.0°C',
       };
     }
 
@@ -141,7 +141,7 @@
       return {
         name: 'value_0x03',
         raw,
-        note: 'PDF indicates XX1<<24 + XX2<<16 + XX3<<8 + XX4',
+        note: '协议文档说明:数值为 XX1<<24 + XX2<<16 + XX3<<8 + XX4',
       };
     }
 
@@ -152,7 +152,7 @@
         name: 'dual_uint16_0x04',
         value1,
         value2,
-        note: 'PDF indicates first two bytes and last two bytes are separate values',
+        note: '协议文档说明:前两字节和后两字节分别表示独立数值',
       };
     }
 
@@ -172,7 +172,7 @@
         name: 'stateful_value_0x09',
         mode,
         raw,
-        note: 'PDF indicates XX1 is a flag (0x00/0x01) and XX2-XX4 compose the value',
+        note: '协议文档说明:XX1 为符号标志位(0x00/0x01),XX2-XX4 组成数值',
       };
     }
 
@@ -193,7 +193,7 @@
         flag,
         raw,
         value: raw / 10,
-        note: 'PDF indicates XX1 is 0x00 and XX2-XX4 value should be divided by 10',
+        note: '协议文档说明:XX1 固定为 0x00,XX2-XX4 组成的数值需除以 10',
       };
     }
 
@@ -202,7 +202,7 @@
         name: `command_${toHex(command)}`,
         raw: uint32BE(payload),
         payload: Array.from(payload),
-        note: 'Meaning not fully legible in source PDF; raw data preserved',
+        note: '原始协议文档语义不够清晰,先保留原始数据',
       };
   }
 }
@@ -238,7 +238,7 @@
   if (valid) {
     parsed.decoded = decodePayload(command, payload);
   } else {
-    parsed.error = 'Checksum mismatch';
+    parsed.error = '校验和不匹配';
   }
 
   return parsed;
@@ -249,12 +249,12 @@
   const hexPairs = normalized.split(/\s+/).filter(Boolean);
 
   if (hexPairs.length === 0) {
-    throw new Error('No hex bytes found in simulate input');
+    throw new Error('模拟输入中未找到十六进制字节');
   }
 
   const values = hexPairs.map((pair) => {
     if (pair.length > 2) {
-      throw new Error(`Invalid byte: ${pair}`);
+      throw new Error(`非法字节: ${pair}`);
     }
 
     return Number.parseInt(pair, 16);
@@ -317,23 +317,23 @@
 
 function validateOptions(options) {
   if (!options.simulate && !options.port) {
-    throw new Error('Missing serial port. Example: node jhm2028-service.js --port COM3');
+    throw new Error('缺少串口参数,例如:node jhm2028-service.js --port COM3');
   }
 
   if (![5, 6, 7, 8].includes(options.dataBits)) {
-    throw new Error('dataBits must be one of 5, 6, 7, 8');
+    throw new Error('dataBits 只能是 5、6、7、8 之一');
   }
 
   if (![1, 1.5, 2].includes(options.stopBits)) {
-    throw new Error('stopBits must be one of 1, 1.5, 2');
+    throw new Error('stopBits 只能是 1、1.5、2 之一');
   }
 
   if (!['none', 'even', 'odd', 'mark', 'space'].includes(options.parity)) {
-    throw new Error('parity must be one of none, even, odd, mark, space');
+    throw new Error('parity 只能是 none、even、odd、mark、space 之一');
   }
 
   if (!Number.isInteger(options.baudRate) || options.baudRate <= 0) {
-    throw new Error('baudRate must be a positive integer');
+    throw new Error('baudRate 必须是正整数');
   }
 }
 
@@ -342,17 +342,17 @@
 }
 
 function printStartup(options) {
-  console.log('JHM-2028 serial service started');
-  console.log(`Port: ${options.port}`);
-  console.log(`Config: ${options.baudRate} baud, ${options.dataBits} data bits, ${options.stopBits} stop bit(s), parity=${options.parity}`);
-  console.log(`Frame format: ${toHex(HEADER_1)} ${toHex(HEADER_2)} NN XX1 XX2 XX3 XX4 CY`);
-  console.log('Waiting for data...');
+  console.log('JHM-2028 串口调试服务已启动');
+  console.log(`串口: ${options.port}`);
+  console.log(`配置: ${options.baudRate} 波特率,${options.dataBits} 数据位,${options.stopBits} 停止位,parity=${options.parity}`);
+  console.log(`帧格式: ${toHex(HEADER_1)} ${toHex(HEADER_2)} NN XX1 XX2 XX3 XX4 CY`);
+  console.log('正在等待数据...');
 }
 
 function runSimulation(options) {
   const parser = new Jhm2028Parser({
     includeTimestamp: options.timestamp,
-    onRawChunk: options.raw ? (chunk) => console.log(`[raw] ${bytesToHex(chunk)}`) : null,
+    onRawChunk: options.raw ? (chunk) => console.log(`[原始数据] ${bytesToHex(chunk)}`) : null,
     onFrame: printJson,
   });
 
@@ -360,7 +360,7 @@
   parser.push(buffer);
 
   if (buffer.length % FRAME_LENGTH !== 0) {
-    console.error(`Warning: simulate input length is ${buffer.length} bytes, not a multiple of ${FRAME_LENGTH}`);
+    console.error(`警告:模拟输入长度为 ${buffer.length} 字节,不是 ${FRAME_LENGTH} 的整数倍`);
   }
 }
 
@@ -370,10 +370,10 @@
     return;
   }
 
-  console.log('\nClosing serial port...');
+  console.log('\n正在关闭串口...');
   port.close((error) => {
     if (error) {
-      console.error('Failed to close serial port:', error.message);
+      console.error('关闭串口失败:', error.message);
       process.exit(1);
       return;
     }
@@ -395,7 +395,7 @@
 
   const parser = new Jhm2028Parser({
     includeTimestamp: options.timestamp,
-    onRawChunk: options.raw ? (chunk) => console.log(`[raw] ${bytesToHex(chunk)}`) : null,
+    onRawChunk: options.raw ? (chunk) => console.log(`[原始数据] ${bytesToHex(chunk)}`) : null,
     onFrame: printJson,
   });
 
@@ -408,11 +408,11 @@
   });
 
   port.on('error', (error) => {
-    console.error('Serial port error:', error.message);
+    console.error('串口异常:', error.message);
   });
 
   port.on('close', () => {
-    console.log('Serial port closed');
+    console.log('串口已关闭');
   });
 
   process.on('SIGINT', () => {
@@ -425,7 +425,7 @@
 
   port.open((error) => {
     if (error) {
-      console.error('Failed to open serial port:', error.message);
+      console.error('打开串口失败:', error.message);
       process.exit(1);
     }
   });
@@ -444,7 +444,7 @@
     runSerialService(options);
   } catch (error) {
     console.error(error.message);
-    console.error('Use --help to see available options.');
+    console.error('可使用 --help 查看可用参数。');
     process.exit(1);
   }
 }

--
Gitblit v1.8.0