feat: modbus enableCRC
This commit is contained in:
		
							parent
							
								
									051046e891
								
							
						
					
					
						commit
						d67cda3462
					
				
							
								
								
									
										10
									
								
								config.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								config.json
									
									
									
									
									
								
							| @ -1,8 +1,10 @@ | ||||
| { | ||||
|   "hostPort": "COM10", | ||||
|   "devicePort": "COM11", | ||||
|   "baudRate": 19200, | ||||
|   "hostPort": "/dev/cu.usbserial-350", | ||||
|   "devicePort": "/dev/cu.usbserial-230", | ||||
|   "baudRate": 9600, | ||||
|   "dataBits": 8, | ||||
|   "stopBits": 1, | ||||
|   "parity": "none" | ||||
|   "parity": "none", | ||||
|   "protocol": "custom", | ||||
|   "enableCRC": false | ||||
| } | ||||
| @ -5,10 +5,11 @@ | ||||
|   "bin": "dist/index.js", | ||||
|   "scripts": { | ||||
|     "build": "tsc", | ||||
|     "dev": "ts-node src/idnex.ts", | ||||
|     "dev": "ts-node src/index.ts", | ||||
|     "start": "node dist/index.js", | ||||
|     "exe": "nexe dist/index.js --build --resource /Users/daoyouyun/.codes/serial-proxy/nodejs/node-v20.18.0-win-x64.zip --output serial-proxy.exe", | ||||
|     "pkg": "pkg . --targets=node18-win-x64 --output=serial-proxy.exe" | ||||
|     "pkg": "pkg . --targets=node18-win-x64 --output=serial-proxy.exe", | ||||
|     "pkg-arm": "pkg dist/index.js --targets=node18-win-arm64 --output=serial-proxy.exe" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "serialport": "^11.0.0" | ||||
|  | ||||
							
								
								
									
										57
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								src/index.ts
									
									
									
									
									
								
							| @ -10,6 +10,8 @@ interface Config { | ||||
|   dataBits: 8 | 5 | 6 | 7 | undefined; | ||||
|   stopBits: 1 | 2 | 1.5 | undefined; | ||||
|   parity: 'none' | 'even' | 'odd' | 'mark' | 'space'; | ||||
|   protocol: 'custom' | 'modbus'; | ||||
|   enableCRC?: boolean; | ||||
| } | ||||
| 
 | ||||
| function loadConfig(): Config { | ||||
| @ -30,7 +32,9 @@ function loadConfig(): Config { | ||||
|       logFile: raw.logFile || path.resolve(process.cwd(), 'serial.log'), | ||||
|       dataBits: raw.dataBits || 8, | ||||
|       stopBits: raw.stopBits || 1, | ||||
|       parity: raw.parity || 'none' | ||||
|       parity: raw.parity || 'none', | ||||
|       protocol: raw.protocol === 'modbus' ? 'modbus' : 'custom', | ||||
|       enableCRC: raw.enableCRC === true | ||||
|     }; | ||||
| 
 | ||||
|     return config; | ||||
| @ -40,30 +44,52 @@ function loadConfig(): Config { | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| function formatTime(date: Date): string { | ||||
|   const pad = (n: number) => n.toString().padStart(2, '0'); | ||||
|   return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ` | ||||
|        + `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`; | ||||
| } | ||||
| 
 | ||||
| function formatLogLine(direction: string, data: Buffer): string { | ||||
| function formatLogLine(direction: string, data: Buffer, protocol: 'custom' | 'modbus'): string { | ||||
|   const timestamp = formatTime(new Date()); | ||||
|   const hex = data.toString('hex').toUpperCase().replace(/(.{2})/g, '$1 ').trim(); | ||||
| 
 | ||||
|   if (protocol === 'modbus') { | ||||
|     return `${timestamp} ${direction} HEX: ${hex}`; | ||||
|   } else { | ||||
|     const ascii = data.toString().replace(/[^\x20-\x7E]/g, '.'); | ||||
|     return `${timestamp} ${direction} HEX: ${hex} ASCII: ${ascii}`; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| function logAndPrint(stream: fs.WriteStream, direction: string, data: Buffer) { | ||||
|   const line = formatLogLine(direction, data); | ||||
| function logAndPrint(stream: fs.WriteStream, direction: string, data: Buffer, protocol: 'custom' | 'modbus') { | ||||
|   const line = formatLogLine(direction, data, protocol); | ||||
|   stream.write(line + '\n'); | ||||
|   console.log(line); | ||||
| } | ||||
| 
 | ||||
| function calculateCRC16(buffer: Buffer): Buffer { | ||||
|   let crc = 0xFFFF; | ||||
| 
 | ||||
|   for (let i = 0; i < buffer.length; i++) { | ||||
|     crc ^= buffer[i]; | ||||
|     for (let j = 0; j < 8; j++) { | ||||
|       if ((crc & 0x0001) !== 0) { | ||||
|         crc >>= 1; | ||||
|         crc ^= 0xA001; | ||||
|       } else { | ||||
|         crc >>= 1; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   const lo = crc & 0xFF; | ||||
|   const hi = (crc >> 8) & 0xFF; | ||||
|   return Buffer.from([lo, hi]); | ||||
| } | ||||
| 
 | ||||
| function startProxy(config: Config) { | ||||
| 
 | ||||
| 
 | ||||
|   const { hostPort, devicePort, baudRate, dataBits, stopBits, parity, logFile } = config; | ||||
|   const { hostPort, devicePort, baudRate, dataBits, stopBits, parity, logFile, protocol, enableCRC } = config; | ||||
| 
 | ||||
|   const logStream = fs.createWriteStream(logFile, { flags: 'a' }); | ||||
| 
 | ||||
| @ -71,12 +97,19 @@ function startProxy(config: Config) { | ||||
|   const device = new SerialPort({ path: devicePort, baudRate, dataBits, stopBits, parity }); | ||||
| 
 | ||||
|   host.on('data', data => { | ||||
|     logAndPrint(logStream, '[主机 → 设备]', data); | ||||
|     device.write(data); | ||||
|     let outData = data; | ||||
| 
 | ||||
|     if (protocol === 'modbus' && enableCRC) { | ||||
|       const crc = calculateCRC16(data); | ||||
|       outData = Buffer.concat([data, crc]); | ||||
|     } | ||||
| 
 | ||||
|     logAndPrint(logStream, '[主机 → 设备]', outData, protocol); | ||||
|     device.write(outData); | ||||
|   }); | ||||
| 
 | ||||
|   device.on('data', data => { | ||||
|     logAndPrint(logStream, '[设备 → 主机]', data); | ||||
|     logAndPrint(logStream, '[设备 → 主机]', data, protocol); | ||||
|     host.write(data); | ||||
|   }); | ||||
| 
 | ||||
| @ -87,6 +120,8 @@ function startProxy(config: Config) { | ||||
|   主机端:${hostPort} | ||||
|   设备端:${devicePort} | ||||
|   波特率:${baudRate} | ||||
|   协议类型:${protocol} | ||||
|   CRC 校验:${enableCRC ? '启用' : '关闭'} | ||||
|   日志文件:${logFile}`);
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user