ts-communication 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +246 -14
  3. package/dist/Invt/InvtModbusTcp.d.ts +88 -0
  4. package/dist/Invt/InvtModbusTcp.js +255 -0
  5. package/dist/XCommunication.d.ts +18 -0
  6. package/dist/XCommunication.js +29 -0
  7. package/dist/ab/AbEtherNetIp.d.ts +1 -0
  8. package/dist/ab/AbEtherNetIp.js +2 -0
  9. package/dist/core/CommunicationLock.d.ts +88 -0
  10. package/dist/core/CommunicationLock.js +156 -0
  11. package/dist/core/Core.d.ts +27 -1
  12. package/dist/core/Core.js +375 -71
  13. package/dist/core/DeviceSerialPort.d.ts +64 -0
  14. package/dist/core/DeviceSerialPort.js +283 -0
  15. package/dist/core/DeviceUdpNet.d.ts +56 -0
  16. package/dist/core/DeviceUdpNet.js +307 -0
  17. package/dist/core/INetMessage.d.ts +145 -0
  18. package/dist/core/INetMessage.js +240 -0
  19. package/dist/debug/PingTest.d.ts +11 -0
  20. package/dist/debug/PingTest.js +59 -0
  21. package/dist/debug/tcpClient.d.ts +11 -0
  22. package/dist/debug/tcpClient.js +116 -0
  23. package/dist/debug/tcpServer.d.ts +12 -0
  24. package/dist/debug/tcpServer.js +102 -0
  25. package/dist/delta/DeltaTcpNet.d.ts +65 -0
  26. package/dist/delta/DeltaTcpNet.js +346 -0
  27. package/dist/ge/GeSRTPNet.d.ts +49 -0
  28. package/dist/ge/GeSRTPNet.js +337 -0
  29. package/dist/inovance/InovanceEasyNet.d.ts +8 -0
  30. package/dist/inovance/InovanceEasyNet.js +103 -0
  31. package/dist/inovance/InovanceSerial.d.ts +55 -0
  32. package/dist/inovance/InovanceSerial.js +145 -0
  33. package/dist/inovance/InovanceSerialOverTcp.d.ts +39 -0
  34. package/dist/inovance/InovanceSerialOverTcp.js +172 -0
  35. package/dist/inovance/InovanceTcpNet.d.ts +2 -4
  36. package/dist/inovance/InovanceTcpNet.js +40 -13
  37. package/dist/melsec/MelsecMcAsciiNet.d.ts +49 -0
  38. package/dist/melsec/MelsecMcAsciiNet.js +196 -0
  39. package/dist/melsec/MelsecMcAsciiUdp.d.ts +54 -0
  40. package/dist/melsec/MelsecMcAsciiUdp.js +204 -0
  41. package/dist/melsec/MelsecMcNet.d.ts +1 -8
  42. package/dist/melsec/MelsecMcNet.js +4 -14
  43. package/dist/melsec/MelsecMcUdp.d.ts +52 -0
  44. package/dist/melsec/MelsecMcUdp.js +191 -0
  45. package/dist/modbus/ModbusAscii.d.ts +24 -3
  46. package/dist/modbus/ModbusAscii.js +109 -3
  47. package/dist/modbus/ModbusAsciiOverTcp.d.ts +21 -3
  48. package/dist/modbus/ModbusAsciiOverTcp.js +67 -3
  49. package/dist/modbus/ModbusRtu.d.ts +101 -13
  50. package/dist/modbus/ModbusRtu.js +355 -21
  51. package/dist/modbus/ModbusRtuOverTcp.d.ts +23 -3
  52. package/dist/modbus/ModbusRtuOverTcp.js +68 -3
  53. package/dist/modbus/ModbusTcpNet.d.ts +16 -3
  54. package/dist/modbus/ModbusTcpNet.js +192 -60
  55. package/dist/modbus/ModbusUdpNet.d.ts +26 -3
  56. package/dist/modbus/ModbusUdpNet.js +125 -2
  57. package/dist/omron/OmronFinsNet.d.ts +1 -2
  58. package/dist/omron/OmronFinsNet.js +210 -69
  59. package/dist/omron/OmronFinsUdp.d.ts +41 -0
  60. package/dist/omron/OmronFinsUdp.js +146 -0
  61. package/dist/siemens/SiemensS7Net.d.ts +6 -0
  62. package/dist/siemens/SiemensS7Net.js +45 -6
  63. package/dist/xinjie/XinJETcpNet.d.ts +18 -0
  64. package/dist/xinjie/XinJETcpNet.js +106 -0
  65. package/package.json +16 -3
@@ -1,4 +1,22 @@
1
- import { ModbusRtuOverTcp } from './ModbusRtuOverTcp';
2
- /** Modbus ASCII frame carried over TCP. */
3
- export declare class ModbusAsciiOverTcp extends ModbusRtuOverTcp {
1
+ import { DeviceClient, DataFormat } from '../core/Core';
2
+ import { OperateResult } from '../core/Core';
3
+ import { INetMessage } from '../core/INetMessage';
4
+ /**
5
+ * Modbus ASCII over TCP 客户端
6
+ * TCP 传输 ASCII 帧
7
+ */
8
+ export declare class ModbusAsciiOverTcp extends DeviceClient {
9
+ Station: number;
10
+ AddressStartWithZero: boolean;
11
+ BroadcastStation: number;
12
+ get DataFormat(): DataFormat;
13
+ set DataFormat(value: DataFormat);
14
+ constructor(ipAddress?: string, port?: number, station?: number);
15
+ protected GetNewNetMessage(): INetMessage;
16
+ private packCommand;
17
+ private unpackResponse;
18
+ protected sendRequest(command: Buffer): Promise<OperateResult<Buffer>>;
19
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
20
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
21
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
4
22
  }
@@ -1,8 +1,72 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModbusAsciiOverTcp = void 0;
4
- const ModbusRtuOverTcp_1 = require("./ModbusRtuOverTcp");
5
- /** Modbus ASCII frame carried over TCP. */
6
- class ModbusAsciiOverTcp extends ModbusRtuOverTcp_1.ModbusRtuOverTcp {
4
+ const Core_1 = require("../core/Core");
5
+ const Core_2 = require("../core/Core");
6
+ const INetMessage_1 = require("../core/INetMessage");
7
+ const ModbusAscii_1 = require("./ModbusAscii");
8
+ /**
9
+ * Modbus ASCII over TCP 客户端
10
+ * TCP 传输 ASCII 帧
11
+ */
12
+ class ModbusAsciiOverTcp extends Core_1.DeviceClient {
13
+ Station = 1;
14
+ AddressStartWithZero = true;
15
+ BroadcastStation = -1;
16
+ get DataFormat() {
17
+ return this.ByteTransform.DataFormat;
18
+ }
19
+ set DataFormat(value) {
20
+ this.ByteTransform.DataFormat = value;
21
+ }
22
+ constructor(ipAddress, port = 502, station = 1) {
23
+ super(ipAddress, port);
24
+ this.Station = station;
25
+ this.ByteTransform.DataFormat = Core_1.DataFormat.CDAB;
26
+ }
27
+ GetNewNetMessage() {
28
+ return new INetMessage_1.ModbusAsciiMessage();
29
+ }
30
+ packCommand(command) {
31
+ const core = Buffer.concat([Buffer.from([this.Station]), command]);
32
+ const lrc = ModbusAscii_1.ModbusAscii.calculateLrc(core);
33
+ const hex = Buffer.concat([core, Buffer.from([lrc])]).toString('hex').toUpperCase();
34
+ return Buffer.from(':' + hex + '\r\n', 'ascii');
35
+ }
36
+ unpackResponse(send, response) {
37
+ return ModbusAscii_1.ModbusAscii.ExtraAsciiResponseContent(send, response, this.BroadcastStation);
38
+ }
39
+ async sendRequest(command) {
40
+ const packed = this.packCommand(command);
41
+ const result = await this.request(packed);
42
+ if (!result.IsSuccess)
43
+ return result;
44
+ return this.unpackResponse(packed, result.Content);
45
+ }
46
+ async Read(address, length) {
47
+ const cmd = Buffer.alloc(5);
48
+ cmd[0] = 3;
49
+ cmd.writeUInt16BE(parseInt(address), 1);
50
+ cmd.writeUInt16BE(length, 3);
51
+ return this.sendRequest(cmd);
52
+ }
53
+ async ReadInt16(address, length = 1) {
54
+ const result = await this.Read(address, length);
55
+ if (!result.IsSuccess)
56
+ return Core_2.OperateResult.CreateFailedResult(result);
57
+ const values = [];
58
+ for (let i = 0; i < length; i++)
59
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
60
+ return Core_2.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
61
+ }
62
+ async ReadFloat(address, length = 1) {
63
+ const result = await this.Read(address, length * 2);
64
+ if (!result.IsSuccess)
65
+ return Core_2.OperateResult.CreateFailedResult(result);
66
+ const values = [];
67
+ for (let i = 0; i < length; i++)
68
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
69
+ return Core_2.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
70
+ }
7
71
  }
8
72
  exports.ModbusAsciiOverTcp = ModbusAsciiOverTcp;
@@ -1,15 +1,103 @@
1
- import { ModbusTcpNet } from './ModbusTcpNet';
2
- import { OperateResult } from '../core/Core';
3
- /** Modbus RTU serial client. */
4
- export declare class ModbusRtu extends ModbusTcpNet {
5
- PortName: string;
6
- BaudRate: number;
7
- DataBits: number;
8
- StopBits: number | string;
9
- Parity: number | string;
10
- private serial;
1
+ import { DeviceSerialPort } from '../core/DeviceSerialPort';
2
+ import { OperateResult, DataFormat } from '../core/Core';
3
+ import { INetMessage } from '../core/INetMessage';
4
+ /**
5
+ * Modbus RTU 串口客户端
6
+ * Modbus-Rtu serial client with CRC16 check
7
+ */
8
+ export declare class ModbusRtu extends DeviceSerialPort {
9
+ Station: number;
10
+ AddressStartWithZero: boolean;
11
+ get IsStringReverse(): boolean;
12
+ set IsStringReverse(value: boolean);
13
+ StationCheckMatch: boolean;
14
+ Crc16CheckEnable: boolean;
15
+ BroadcastStation: number;
16
+ WordReadBatchLength: number;
17
+ DisableFunctionCode06: boolean;
18
+ EnableWriteMaskCode: boolean;
19
+ get DataFormat(): DataFormat;
20
+ set DataFormat(value: DataFormat);
11
21
  constructor(station?: number);
12
- SerialPortInni(portName: string, baudRate?: number, dataBits?: number, stopBits?: number | string, parity?: number | string): this;
13
- Open(): Promise<OperateResult<any>>;
14
- Close(): Promise<OperateResult<void>>;
22
+ protected GetNewNetMessage(): INetMessage;
23
+ /**
24
+ * 打包命令:添加站号和 CRC16 校验
25
+ */
26
+ protected PackCommandWithHeader(command: Buffer): Buffer;
27
+ /**
28
+ * 解包响应:验证 CRC16 和站号
29
+ */
30
+ protected UnpackResponseContent(send: Buffer, response: Buffer): OperateResult<Buffer>;
31
+ /**
32
+ * CRC16 校验(多项式 0xA001)
33
+ */
34
+ static crc16(data: Buffer): Buffer;
35
+ /**
36
+ * 验证 CRC16
37
+ */
38
+ static checkCrc16(data: Buffer): boolean;
39
+ /**
40
+ * 提取 RTU 响应内容
41
+ */
42
+ static ExtraRtuResponseContent(send: Buffer, response: Buffer, crcCheck?: boolean, broadcastStation?: number): OperateResult<Buffer>;
43
+ /**
44
+ * 提取实际数据
45
+ */
46
+ static ExtractActualData(core: Buffer): OperateResult<Buffer>;
47
+ /**
48
+ * 获取 Modbus 异常描述
49
+ */
50
+ static GetModbusExceptionDescription(code: number): string;
51
+ /**
52
+ * 地址解析
53
+ */
54
+ private addr;
55
+ /**
56
+ * 构建读取命令
57
+ */
58
+ private buildReadCommand;
59
+ /**
60
+ * 读取字节数据
61
+ */
62
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
63
+ /**
64
+ * 读取线圈
65
+ */
66
+ ReadCoil(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
67
+ /**
68
+ * 读取离散输入
69
+ */
70
+ ReadDiscrete(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
71
+ /**
72
+ * 写入单个线圈
73
+ */
74
+ WriteCoil(address: string, value: boolean): Promise<OperateResult<void>>;
75
+ /**
76
+ * 写入多个线圈
77
+ */
78
+ WriteCoils(address: string, values: boolean[]): Promise<OperateResult<void>>;
79
+ /**
80
+ * 写入单个寄存器
81
+ */
82
+ WriteRegister(address: string, value: number): Promise<OperateResult<void>>;
83
+ /**
84
+ * 写入多个寄存器
85
+ */
86
+ WriteRegisters(address: string, values: number[]): Promise<OperateResult<void>>;
87
+ /**
88
+ * 读取 Int16
89
+ */
90
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
91
+ /**
92
+ * 读取 UInt16
93
+ */
94
+ ReadUInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
95
+ /**
96
+ * 读取 Int32
97
+ */
98
+ ReadInt32(address: string, length?: number): Promise<OperateResult<number | number[]>>;
99
+ /**
100
+ * 读取 Float
101
+ */
102
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
15
103
  }
@@ -1,27 +1,361 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModbusRtu = void 0;
4
- const ModbusTcpNet_1 = require("./ModbusTcpNet");
4
+ const DeviceSerialPort_1 = require("../core/DeviceSerialPort");
5
5
  const Core_1 = require("../core/Core");
6
- /** Modbus RTU serial client. */
7
- class ModbusRtu extends ModbusTcpNet_1.ModbusTcpNet {
8
- PortName = '';
9
- BaudRate = 9600;
10
- DataBits = 8;
11
- StopBits = 1;
12
- Parity = 'none';
13
- serial;
14
- constructor(station = 1) { super(); this.Station = station; }
15
- SerialPortInni(portName, baudRate = 9600, dataBits = 8, stopBits = 1, parity = 'none') { this.PortName = portName; this.BaudRate = baudRate; this.DataBits = dataBits; this.StopBits = stopBits; this.Parity = parity; return this; }
16
- async Open() { try {
17
- const mod = await import('serialport');
18
- this.serial = new mod.SerialPort({ path: this.PortName, baudRate: this.BaudRate, dataBits: this.DataBits, stopBits: Number(this.StopBits), parity: String(this.Parity) });
19
- return Core_1.OperateResult.CreateSuccessResult();
20
- }
21
- catch (e) {
22
- return new Core_1.OperateResult(`Unable to open serial port: ${e.message}`);
23
- } }
24
- async Close() { if (this.serial)
25
- await new Promise(r => this.serial.close(() => r())); this.serial = undefined; return Core_1.OperateResult.CreateSuccessResult(); }
6
+ const INetMessage_1 = require("../core/INetMessage");
7
+ const ModbusTcpNet_1 = require("./ModbusTcpNet");
8
+ /**
9
+ * Modbus RTU 串口客户端
10
+ * Modbus-Rtu serial client with CRC16 check
11
+ */
12
+ class ModbusRtu extends DeviceSerialPort_1.DeviceSerialPort {
13
+ Station = 1;
14
+ AddressStartWithZero = true;
15
+ get IsStringReverse() {
16
+ return this.ByteTransform.IsStringReverseByteWord;
17
+ }
18
+ set IsStringReverse(value) {
19
+ this.ByteTransform.IsStringReverseByteWord = value;
20
+ }
21
+ StationCheckMatch = true;
22
+ Crc16CheckEnable = true;
23
+ BroadcastStation = -1;
24
+ WordReadBatchLength = 120;
25
+ DisableFunctionCode06 = false;
26
+ EnableWriteMaskCode = true;
27
+ get DataFormat() {
28
+ return this.ByteTransform.DataFormat;
29
+ }
30
+ set DataFormat(value) {
31
+ this.ByteTransform.DataFormat = value;
32
+ }
33
+ constructor(station = 1) {
34
+ super();
35
+ this.Station = station;
36
+ this.ByteTransform.DataFormat = Core_1.DataFormat.CDAB;
37
+ this.ReceiveEmptyDataCount = 8; // RTU 帧间隔检测
38
+ }
39
+ GetNewNetMessage() {
40
+ return new INetMessage_1.ModbusRtuMessage(this.StationCheckMatch);
41
+ }
42
+ /**
43
+ * 打包命令:添加站号和 CRC16 校验
44
+ */
45
+ PackCommandWithHeader(command) {
46
+ const frame = Buffer.concat([Buffer.from([this.Station]), command]);
47
+ const crc = ModbusRtu.crc16(frame);
48
+ return Buffer.concat([frame, crc]);
49
+ }
50
+ /**
51
+ * 解包响应:验证 CRC16 和站号
52
+ */
53
+ UnpackResponseContent(send, response) {
54
+ return ModbusRtu.ExtraRtuResponseContent(send, response, this.Crc16CheckEnable, this.BroadcastStation);
55
+ }
56
+ /**
57
+ * CRC16 校验(多项式 0xA001)
58
+ */
59
+ static crc16(data) {
60
+ let crc = 0xFFFF;
61
+ for (const byte of data) {
62
+ crc ^= byte;
63
+ for (let i = 0; i < 8; i++) {
64
+ if (crc & 1) {
65
+ crc = (crc >>> 1) ^ 0xA001;
66
+ }
67
+ else {
68
+ crc = crc >>> 1;
69
+ }
70
+ }
71
+ }
72
+ return Buffer.from([crc & 0xFF, (crc >>> 8) & 0xFF]);
73
+ }
74
+ /**
75
+ * 验证 CRC16
76
+ */
77
+ static checkCrc16(data) {
78
+ if (data.length < 2)
79
+ return false;
80
+ const received = data.subarray(0, data.length - 2);
81
+ const crcReceived = data.subarray(data.length - 2);
82
+ const crcCalculated = ModbusRtu.crc16(received);
83
+ return crcReceived[0] === crcCalculated[0] && crcReceived[1] === crcCalculated[1];
84
+ }
85
+ /**
86
+ * 提取 RTU 响应内容
87
+ */
88
+ static ExtraRtuResponseContent(send, response, crcCheck = true, broadcastStation = -1) {
89
+ // 广播站不需要响应
90
+ if (broadcastStation >= 0 && send[0] === broadcastStation) {
91
+ return Core_1.OperateResult.CreateSuccessResult(Buffer.alloc(0));
92
+ }
93
+ if (response.length < 5) {
94
+ return new Core_1.OperateResult(`Receive data length too short: ${response.length}`, -1);
95
+ }
96
+ let frame = response;
97
+ // CRC 校验
98
+ if (crcCheck && !ModbusRtu.checkCrc16(frame)) {
99
+ // 尝试去掉第一个字节后再验证(可能有干扰)
100
+ if (frame.length > 1) {
101
+ frame = frame.subarray(1);
102
+ if (!ModbusRtu.checkCrc16(frame)) {
103
+ return new Core_1.OperateResult(`Modbus CRC check failed: ${response.toString('hex')}`, -2);
104
+ }
105
+ }
106
+ else {
107
+ return new Core_1.OperateResult(`Modbus CRC check failed: ${response.toString('hex')}`, -2);
108
+ }
109
+ }
110
+ // 去除 CRC
111
+ const dataWithoutCrc = frame.subarray(0, frame.length - 2);
112
+ // 检查站号
113
+ if (send[0] !== dataWithoutCrc[0]) {
114
+ return new Core_1.OperateResult(`Station not match, request: ${send[0]}, response: ${dataWithoutCrc[0]}`, -3);
115
+ }
116
+ // 检查功能码
117
+ const sendFunctionCode = send[1];
118
+ const receiveFunctionCode = dataWithoutCrc[1];
119
+ // 异常响应
120
+ if (receiveFunctionCode === (sendFunctionCode | 0x80)) {
121
+ const exceptionCode = dataWithoutCrc[2];
122
+ return new Core_1.OperateResult(ModbusRtu.GetModbusExceptionDescription(exceptionCode), exceptionCode);
123
+ }
124
+ // 功能码不匹配
125
+ if (sendFunctionCode !== receiveFunctionCode) {
126
+ return new Core_1.OperateResult(`Function code not match: ${sendFunctionCode} != ${receiveFunctionCode}`, -4);
127
+ }
128
+ // 提取数据部分
129
+ return ModbusRtu.ExtractActualData(dataWithoutCrc);
130
+ }
131
+ /**
132
+ * 提取实际数据
133
+ */
134
+ static ExtractActualData(core) {
135
+ const functionCode = core[1];
136
+ // 读取响应:01/02/03/04
137
+ if (functionCode === 0x01 || functionCode === 0x02 || functionCode === 0x03 || functionCode === 0x04 || functionCode === 0x17) {
138
+ const length = core[2];
139
+ return Core_1.OperateResult.CreateSuccessResult(core.subarray(3, 3 + length));
140
+ }
141
+ // 写入响应:05/06/0F/10/16
142
+ if (functionCode === 0x05 || functionCode === 0x06 || functionCode === 0x0F || functionCode === 0x10 || functionCode === 0x16) {
143
+ return Core_1.OperateResult.CreateSuccessResult(core.subarray(2));
144
+ }
145
+ return Core_1.OperateResult.CreateSuccessResult(core.subarray(2));
146
+ }
147
+ /**
148
+ * 获取 Modbus 异常描述
149
+ */
150
+ static GetModbusExceptionDescription(code) {
151
+ const descriptions = {
152
+ 0x01: 'Illegal Function',
153
+ 0x02: 'Illegal Data Address',
154
+ 0x03: 'Illegal Data Value',
155
+ 0x04: 'Slave Device Failure',
156
+ 0x05: 'Acknowledge',
157
+ 0x06: 'Slave Device Busy',
158
+ 0x08: 'Memory Parity Error',
159
+ 0x0A: 'Gateway Path Unavailable',
160
+ 0x0B: 'Gateway Target Device Failed to Respond'
161
+ };
162
+ return descriptions[code] || `Unknown Exception: 0x${code.toString(16).toUpperCase()}`;
163
+ }
164
+ /**
165
+ * 地址解析
166
+ */
167
+ addr(input, code) {
168
+ const p = (0, ModbusTcpNet_1.parseModbusAddress)(input, this.Station, code);
169
+ if (p.IsSuccess && !this.AddressStartWithZero) {
170
+ p.Content.address--;
171
+ }
172
+ return p;
173
+ }
174
+ /**
175
+ * 构建读取命令
176
+ */
177
+ buildReadCommand(address, length, functionCode) {
178
+ const a = this.addr(address, functionCode);
179
+ if (!a.IsSuccess)
180
+ return Core_1.OperateResult.CreateFailedResult(a);
181
+ const cmd = Buffer.alloc(5);
182
+ cmd[0] = a.Content.code;
183
+ cmd.writeUInt16BE(a.Content.address, 1);
184
+ cmd.writeUInt16BE(length, 3);
185
+ return Core_1.OperateResult.CreateSuccessResult(cmd);
186
+ }
187
+ /**
188
+ * 读取字节数据
189
+ */
190
+ async Read(address, length) {
191
+ const cmdResult = this.buildReadCommand(address, length, 3);
192
+ if (!cmdResult.IsSuccess)
193
+ return cmdResult;
194
+ return this.ReadFromCoreServer(cmdResult.Content);
195
+ }
196
+ /**
197
+ * 读取线圈
198
+ */
199
+ async ReadCoil(address, length = 1) {
200
+ const cmdResult = this.buildReadCommand(address, length, 1);
201
+ if (!cmdResult.IsSuccess)
202
+ return Core_1.OperateResult.CreateFailedResult(cmdResult);
203
+ const result = await this.ReadFromCoreServer(cmdResult.Content);
204
+ if (!result.IsSuccess)
205
+ return Core_1.OperateResult.CreateFailedResult(result);
206
+ const bools = [];
207
+ for (let i = 0; i < length; i++) {
208
+ const byteIndex = Math.floor(i / 8);
209
+ const bitIndex = i % 8;
210
+ bools.push((result.Content[byteIndex] & (1 << bitIndex)) !== 0);
211
+ }
212
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? bools[0] : bools);
213
+ }
214
+ /**
215
+ * 读取离散输入
216
+ */
217
+ async ReadDiscrete(address, length = 1) {
218
+ const cmdResult = this.buildReadCommand(address, length, 2);
219
+ if (!cmdResult.IsSuccess)
220
+ return Core_1.OperateResult.CreateFailedResult(cmdResult);
221
+ const result = await this.ReadFromCoreServer(cmdResult.Content);
222
+ if (!result.IsSuccess)
223
+ return Core_1.OperateResult.CreateFailedResult(result);
224
+ const bools = [];
225
+ for (let i = 0; i < length; i++) {
226
+ const byteIndex = Math.floor(i / 8);
227
+ const bitIndex = i % 8;
228
+ bools.push((result.Content[byteIndex] & (1 << bitIndex)) !== 0);
229
+ }
230
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? bools[0] : bools);
231
+ }
232
+ /**
233
+ * 写入单个线圈
234
+ */
235
+ async WriteCoil(address, value) {
236
+ const a = this.addr(address, 5);
237
+ if (!a.IsSuccess)
238
+ return Core_1.OperateResult.CreateFailedResult(a);
239
+ const cmd = Buffer.alloc(5);
240
+ cmd[0] = 5;
241
+ cmd.writeUInt16BE(a.Content.address, 1);
242
+ cmd.writeUInt16BE(value ? 0xFF00 : 0x0000, 3);
243
+ const result = await this.ReadFromCoreServer(cmd);
244
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
245
+ }
246
+ /**
247
+ * 写入多个线圈
248
+ */
249
+ async WriteCoils(address, values) {
250
+ const a = this.addr(address, 15);
251
+ if (!a.IsSuccess)
252
+ return Core_1.OperateResult.CreateFailedResult(a);
253
+ const byteCount = Math.ceil(values.length / 8);
254
+ const data = Buffer.alloc(byteCount);
255
+ for (let i = 0; i < values.length; i++) {
256
+ if (values[i]) {
257
+ const byteIndex = Math.floor(i / 8);
258
+ const bitIndex = i % 8;
259
+ data[byteIndex] |= (1 << bitIndex);
260
+ }
261
+ }
262
+ const cmd = Buffer.alloc(6 + byteCount);
263
+ cmd[0] = 15;
264
+ cmd.writeUInt16BE(a.Content.address, 1);
265
+ cmd.writeUInt16BE(values.length, 3);
266
+ cmd[5] = byteCount;
267
+ data.copy(cmd, 6);
268
+ const result = await this.ReadFromCoreServer(cmd);
269
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
270
+ }
271
+ /**
272
+ * 写入单个寄存器
273
+ */
274
+ async WriteRegister(address, value) {
275
+ if (this.DisableFunctionCode06) {
276
+ return this.WriteRegisters(address, [value]);
277
+ }
278
+ const a = this.addr(address, 6);
279
+ if (!a.IsSuccess)
280
+ return Core_1.OperateResult.CreateFailedResult(a);
281
+ const cmd = Buffer.alloc(5);
282
+ cmd[0] = 6;
283
+ cmd.writeUInt16BE(a.Content.address, 1);
284
+ cmd.writeUInt16BE(value & 0xFFFF, 3);
285
+ const result = await this.ReadFromCoreServer(cmd);
286
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
287
+ }
288
+ /**
289
+ * 写入多个寄存器
290
+ */
291
+ async WriteRegisters(address, values) {
292
+ const a = this.addr(address, 16);
293
+ if (!a.IsSuccess)
294
+ return Core_1.OperateResult.CreateFailedResult(a);
295
+ const data = Buffer.alloc(values.length * 2);
296
+ for (let i = 0; i < values.length; i++) {
297
+ data.writeUInt16BE(values[i] & 0xFFFF, i * 2);
298
+ }
299
+ const cmd = Buffer.alloc(6 + data.length);
300
+ cmd[0] = 16;
301
+ cmd.writeUInt16BE(a.Content.address, 1);
302
+ cmd.writeUInt16BE(values.length, 3);
303
+ cmd[5] = data.length;
304
+ data.copy(cmd, 6);
305
+ const result = await this.ReadFromCoreServer(cmd);
306
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
307
+ }
308
+ /**
309
+ * 读取 Int16
310
+ */
311
+ async ReadInt16(address, length = 1) {
312
+ const result = await this.Read(address, length);
313
+ if (!result.IsSuccess)
314
+ return Core_1.OperateResult.CreateFailedResult(result);
315
+ const values = [];
316
+ for (let i = 0; i < length; i++) {
317
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
318
+ }
319
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
320
+ }
321
+ /**
322
+ * 读取 UInt16
323
+ */
324
+ async ReadUInt16(address, length = 1) {
325
+ const result = await this.Read(address, length);
326
+ if (!result.IsSuccess)
327
+ return Core_1.OperateResult.CreateFailedResult(result);
328
+ const values = [];
329
+ for (let i = 0; i < length; i++) {
330
+ values.push(this.ByteTransform.TransUInt16(result.Content, i * 2));
331
+ }
332
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
333
+ }
334
+ /**
335
+ * 读取 Int32
336
+ */
337
+ async ReadInt32(address, length = 1) {
338
+ const result = await this.Read(address, length * 2);
339
+ if (!result.IsSuccess)
340
+ return Core_1.OperateResult.CreateFailedResult(result);
341
+ const values = [];
342
+ for (let i = 0; i < length; i++) {
343
+ values.push(this.ByteTransform.TransInt32(result.Content, i * 4));
344
+ }
345
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
346
+ }
347
+ /**
348
+ * 读取 Float
349
+ */
350
+ async ReadFloat(address, length = 1) {
351
+ const result = await this.Read(address, length * 2);
352
+ if (!result.IsSuccess)
353
+ return Core_1.OperateResult.CreateFailedResult(result);
354
+ const values = [];
355
+ for (let i = 0; i < length; i++) {
356
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
357
+ }
358
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
359
+ }
26
360
  }
27
361
  exports.ModbusRtu = ModbusRtu;
@@ -1,4 +1,24 @@
1
- import { ModbusTcpNet } from './ModbusTcpNet';
2
- /** Modbus RTU frame carried over TCP. */
3
- export declare class ModbusRtuOverTcp extends ModbusTcpNet {
1
+ import { DeviceClient, DataFormat } from '../core/Core';
2
+ import { OperateResult } from '../core/Core';
3
+ import { INetMessage } from '../core/INetMessage';
4
+ /**
5
+ * Modbus RTU over TCP 客户端
6
+ * TCP 传输 RTU 帧(无 MBAP 头)
7
+ */
8
+ export declare class ModbusRtuOverTcp extends DeviceClient {
9
+ Station: number;
10
+ AddressStartWithZero: boolean;
11
+ StationCheckMatch: boolean;
12
+ Crc16CheckEnable: boolean;
13
+ BroadcastStation: number;
14
+ get DataFormat(): DataFormat;
15
+ set DataFormat(value: DataFormat);
16
+ constructor(ipAddress?: string, port?: number, station?: number);
17
+ protected GetNewNetMessage(): INetMessage;
18
+ private packCommand;
19
+ private unpackResponse;
20
+ protected sendRequest(command: Buffer): Promise<OperateResult<Buffer>>;
21
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
22
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
23
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
4
24
  }