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
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MelsecMcAsciiUdp = void 0;
4
+ const DeviceUdpNet_1 = require("../core/DeviceUdpNet");
5
+ const Core_1 = require("../core/Core");
6
+ const MelsecMcNet_1 = require("./MelsecMcNet");
7
+ /**
8
+ * 三菱 MC 协议 ASCII 格式 UDP 客户端
9
+ * Mitsubishi MC protocol ASCII format over UDP
10
+ */
11
+ class MelsecMcAsciiUdp extends DeviceUdpNet_1.DeviceUdpNet {
12
+ NetworkNumber = 0;
13
+ PLCNumber = 0xff;
14
+ NetworkStationNumber = 0;
15
+ TargetIOStation = 1023;
16
+ EnableWriteBitToWordRegister = true;
17
+ constructor(ipAddress, port = 6001) {
18
+ super(ipAddress, port);
19
+ this.ByteTransform.DataFormat = Core_1.DataFormat.DCBA;
20
+ }
21
+ /**
22
+ * 将二进制转换为 ASCII
23
+ */
24
+ toAscii(data) {
25
+ return Buffer.from(data.toString('hex').toUpperCase(), 'ascii');
26
+ }
27
+ /**
28
+ * 将 ASCII 转换为二进制
29
+ */
30
+ fromAscii(ascii) {
31
+ return Buffer.from(ascii.toString('ascii'), 'hex');
32
+ }
33
+ /**
34
+ * 打包 ASCII 格式命令
35
+ */
36
+ packAscii(core) {
37
+ const header = Buffer.alloc(9);
38
+ header.writeUInt16BE(0x3530, 0); // "50"
39
+ header.writeUInt16BE(0x3030, 2); // "00"
40
+ // 网络号
41
+ const netHex = this.NetworkNumber.toString(16).padStart(2, '0').toUpperCase();
42
+ header[4] = netHex.charCodeAt(0);
43
+ header[5] = netHex.charCodeAt(1);
44
+ // PLC 号
45
+ const plcHex = this.PLCNumber.toString(16).padStart(2, '0').toUpperCase();
46
+ header[6] = plcHex.charCodeAt(0);
47
+ header[7] = plcHex.charCodeAt(1);
48
+ // 目标 IO 站号
49
+ const ioHex = this.TargetIOStation.toString(16).padStart(4, '0').toUpperCase();
50
+ const ioBuffer = Buffer.from(ioHex, 'ascii');
51
+ // 网络站号
52
+ const stationHex = this.NetworkStationNumber.toString(16).padStart(2, '0').toUpperCase();
53
+ const stationBuffer = Buffer.from(stationHex, 'ascii');
54
+ // 数据长度(ASCII 字符数)
55
+ const dataLength = (core.length * 2).toString(16).padStart(4, '0').toUpperCase();
56
+ const lengthBuffer = Buffer.from(dataLength, 'ascii');
57
+ // 监视定时器
58
+ const timer = Buffer.from('0010', 'ascii');
59
+ // 转换核心数据为 ASCII
60
+ const coreAscii = this.toAscii(core);
61
+ return Buffer.concat([
62
+ header,
63
+ ioBuffer,
64
+ stationBuffer,
65
+ lengthBuffer,
66
+ timer,
67
+ coreAscii
68
+ ]);
69
+ }
70
+ /**
71
+ * 发送请求
72
+ */
73
+ async transact(core) {
74
+ const frame = this.packAscii(core);
75
+ const result = await this.request(frame);
76
+ if (!result.IsSuccess)
77
+ return result;
78
+ const response = result.Content;
79
+ // ASCII 格式:响应至少包含 22 个字符的头部
80
+ if (response.length < 22) {
81
+ return new Core_1.OperateResult('Invalid response length', -1);
82
+ }
83
+ // 提取结束码
84
+ const endCodeHex = response.toString('ascii', 18, 22);
85
+ const endCode = parseInt(endCodeHex, 16);
86
+ if (endCode !== 0) {
87
+ return new Core_1.OperateResult(`Melsec error: 0x${endCode.toString(16)}`, endCode);
88
+ }
89
+ // 提取数据部分并转换为二进制
90
+ const dataAscii = response.subarray(22);
91
+ return Core_1.OperateResult.CreateSuccessResult(this.fromAscii(dataAscii));
92
+ }
93
+ /**
94
+ * 读取字数据
95
+ */
96
+ async Read(address, length) {
97
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
98
+ if (!a.IsSuccess)
99
+ return Core_1.OperateResult.CreateFailedResult(a);
100
+ const d = a.Content;
101
+ const core = Buffer.alloc(10);
102
+ core[0] = 0x01; // 批量读取
103
+ core[1] = 0x04; // 子命令
104
+ core[2] = 0x00; // 字单位
105
+ // 起始地址(3字节小端)
106
+ core.writeUIntLE(d.AddressStart, 3, 3);
107
+ // 设备代码
108
+ core[6] = d.DataCode;
109
+ // 读取长度
110
+ core.writeUInt16LE(length, 7);
111
+ return this.transact(core);
112
+ }
113
+ /**
114
+ * 读取位数据
115
+ */
116
+ async ReadBool(address, length = 1) {
117
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, true);
118
+ if (!a.IsSuccess)
119
+ return Core_1.OperateResult.CreateFailedResult(a);
120
+ const d = a.Content;
121
+ const core = Buffer.alloc(10);
122
+ core[0] = 0x01; // 批量读取
123
+ core[1] = 0x04; // 子命令
124
+ core[2] = 0x01; // 位单位
125
+ // 起始地址(3字节小端)
126
+ core.writeUIntLE(d.AddressStart, 3, 3);
127
+ // 设备代码
128
+ core[6] = d.DataCode;
129
+ // 读取长度
130
+ core.writeUInt16LE(length, 7);
131
+ const result = await this.transact(core);
132
+ if (!result.IsSuccess)
133
+ return Core_1.OperateResult.CreateFailedResult(result);
134
+ const values = [];
135
+ for (let i = 0; i < length; i++) {
136
+ values.push(result.Content[i] !== 0);
137
+ }
138
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
139
+ }
140
+ /**
141
+ * 写入字数据
142
+ */
143
+ async Write(address, data) {
144
+ const length = Math.ceil(data.length / 2);
145
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
146
+ if (!a.IsSuccess)
147
+ return Core_1.OperateResult.CreateFailedResult(a);
148
+ const d = a.Content;
149
+ const core = Buffer.alloc(10 + data.length);
150
+ core[0] = 0x01; // 批量写入
151
+ core[1] = 0x14; // 子命令
152
+ core[2] = 0x00; // 字单位
153
+ // 起始地址(3字节小端)
154
+ core.writeUIntLE(d.AddressStart, 3, 3);
155
+ // 设备代码
156
+ core[6] = d.DataCode;
157
+ // 写入长度
158
+ core.writeUInt16LE(length, 7);
159
+ // 数据
160
+ data.copy(core, 10);
161
+ const result = await this.transact(core);
162
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
163
+ }
164
+ /**
165
+ * 读取 Int16
166
+ */
167
+ async ReadInt16(address, length = 1) {
168
+ const result = await this.Read(address, length);
169
+ if (!result.IsSuccess)
170
+ return Core_1.OperateResult.CreateFailedResult(result);
171
+ const values = [];
172
+ for (let i = 0; i < length; i++) {
173
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
174
+ }
175
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
176
+ }
177
+ /**
178
+ * 读取 UInt16
179
+ */
180
+ async ReadUInt16(address, length = 1) {
181
+ const result = await this.Read(address, length);
182
+ if (!result.IsSuccess)
183
+ return Core_1.OperateResult.CreateFailedResult(result);
184
+ const values = [];
185
+ for (let i = 0; i < length; i++) {
186
+ values.push(this.ByteTransform.TransUInt16(result.Content, i * 2));
187
+ }
188
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
189
+ }
190
+ /**
191
+ * 读取 Float
192
+ */
193
+ async ReadFloat(address, length = 1) {
194
+ const result = await this.Read(address, length * 2);
195
+ if (!result.IsSuccess)
196
+ return Core_1.OperateResult.CreateFailedResult(result);
197
+ const values = [];
198
+ for (let i = 0; i < length; i++) {
199
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
200
+ }
201
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
202
+ }
203
+ }
204
+ exports.MelsecMcAsciiUdp = MelsecMcAsciiUdp;
@@ -1,4 +1,4 @@
1
- import { DataFormat, DeviceClient, OperateResult } from '../core/Core';
1
+ import { DeviceClient, OperateResult } from '../core/Core';
2
2
  export interface McAddressData {
3
3
  AddressStart: number;
4
4
  Length: number;
@@ -13,7 +13,6 @@ export declare class MelsecMcNet extends DeviceClient {
13
13
  NetworkStationNumber: number;
14
14
  TargetIOStation: number;
15
15
  EnableWriteBitToWordRegister: boolean;
16
- DataFormat: DataFormat;
17
16
  constructor(ipAddress?: string, port?: number);
18
17
  protected pack(core: Buffer): Buffer<ArrayBuffer>;
19
18
  private transact;
@@ -47,9 +46,3 @@ export declare class MelsecMcNet extends DeviceClient {
47
46
  RemoteRun(): Promise<OperateResult<string>>;
48
47
  RemoteStop(): Promise<OperateResult<string>>;
49
48
  }
50
- export declare class MelsecMcAsciiNet extends MelsecMcNet {
51
- }
52
- export declare class MelsecMcUdp extends MelsecMcNet {
53
- }
54
- export declare class MelsecMcAsciiUdp extends MelsecMcNet {
55
- }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MelsecMcAsciiUdp = exports.MelsecMcUdp = exports.MelsecMcAsciiNet = exports.MelsecMcNet = void 0;
3
+ exports.MelsecMcNet = void 0;
4
4
  exports.parseMelsecAddress = parseMelsecAddress;
5
5
  const Core_1 = require("../core/Core");
6
6
  const MC = {
@@ -61,11 +61,10 @@ class MelsecMcNet extends Core_1.DeviceClient {
61
61
  NetworkStationNumber = 0;
62
62
  TargetIOStation = 1023;
63
63
  EnableWriteBitToWordRegister = true;
64
- DataFormat = Core_1.DataFormat.DCBA;
65
64
  constructor(ipAddress, port = 6000) {
66
65
  super(ipAddress, ipAddress === undefined ? undefined : port);
67
66
  this.Port = ipAddress === undefined ? 5000 : port;
68
- this.ByteTransform = new Core_1.ByteTransform(this.DataFormat);
67
+ this.ByteTransform = new Core_1.ByteTransform(Core_1.DataFormat.DCBA);
69
68
  }
70
69
  pack(core) {
71
70
  const h = Buffer.alloc(11 + core.length);
@@ -163,7 +162,7 @@ class MelsecMcNet extends Core_1.DeviceClient {
163
162
  async ReadUInt64(a, l) {
164
163
  return this.typedRead(a, l ?? 1, 8, (b, o) => this.ByteTransform.TransUInt64(b, o));
165
164
  }
166
- async ReadString(address, length, encoding = 'utf8') {
165
+ async ReadString(address, length, encoding = 'ascii') {
167
166
  const r = await this.Read(address, length);
168
167
  return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(this.ByteTransform.TransString(r.Content, encoding)) : Core_1.OperateResult.CreateFailedResult(r);
169
168
  }
@@ -177,7 +176,7 @@ class MelsecMcNet extends Core_1.DeviceClient {
177
176
  if (typeof value === 'boolean')
178
177
  data = Buffer.from([value ? 1 : 0]);
179
178
  else if (typeof value === 'string')
180
- data = Buffer.from(value);
179
+ data = Buffer.from(value, 'ascii');
181
180
  else if (Buffer.isBuffer(value))
182
181
  data = value;
183
182
  else if (Array.isArray(value) && typeof value[0] === 'boolean')
@@ -260,12 +259,3 @@ class MelsecMcNet extends Core_1.DeviceClient {
260
259
  }
261
260
  }
262
261
  exports.MelsecMcNet = MelsecMcNet;
263
- class MelsecMcAsciiNet extends MelsecMcNet {
264
- }
265
- exports.MelsecMcAsciiNet = MelsecMcAsciiNet;
266
- class MelsecMcUdp extends MelsecMcNet {
267
- }
268
- exports.MelsecMcUdp = MelsecMcUdp;
269
- class MelsecMcAsciiUdp extends MelsecMcNet {
270
- }
271
- exports.MelsecMcAsciiUdp = MelsecMcAsciiUdp;
@@ -0,0 +1,52 @@
1
+ import { DeviceUdpNet } from '../core/DeviceUdpNet';
2
+ import { OperateResult } from '../core/Core';
3
+ import { INetMessage } from '../core/INetMessage';
4
+ /**
5
+ * 三菱 MC 协议二进制格式 UDP 客户端
6
+ * Mitsubishi MC protocol binary format over UDP
7
+ */
8
+ export declare class MelsecMcUdp extends DeviceUdpNet {
9
+ NetworkNumber: number;
10
+ PLCNumber: number;
11
+ NetworkStationNumber: number;
12
+ TargetIOStation: number;
13
+ EnableWriteBitToWordRegister: boolean;
14
+ constructor(ipAddress?: string, port?: number);
15
+ protected GetNewNetMessage(): INetMessage;
16
+ /**
17
+ * 打包二进制格式命令
18
+ */
19
+ protected pack(core: Buffer): Buffer;
20
+ /**
21
+ * 发送请求
22
+ */
23
+ private transact;
24
+ /**
25
+ * 读取字数据
26
+ */
27
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
28
+ /**
29
+ * 读取位数据
30
+ */
31
+ ReadBool(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
32
+ /**
33
+ * 写入字数据
34
+ */
35
+ Write(address: string, data: Buffer): Promise<OperateResult<void>>;
36
+ /**
37
+ * 读取 Int16
38
+ */
39
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
40
+ /**
41
+ * 读取 UInt16
42
+ */
43
+ ReadUInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
44
+ /**
45
+ * 读取 Int32
46
+ */
47
+ ReadInt32(address: string, length?: number): Promise<OperateResult<number | number[]>>;
48
+ /**
49
+ * 读取 Float
50
+ */
51
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
52
+ }
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MelsecMcUdp = void 0;
4
+ const DeviceUdpNet_1 = require("../core/DeviceUdpNet");
5
+ const Core_1 = require("../core/Core");
6
+ const INetMessage_1 = require("../core/INetMessage");
7
+ const MelsecMcNet_1 = require("./MelsecMcNet");
8
+ /**
9
+ * 三菱 MC 协议二进制格式 UDP 客户端
10
+ * Mitsubishi MC protocol binary format over UDP
11
+ */
12
+ class MelsecMcUdp extends DeviceUdpNet_1.DeviceUdpNet {
13
+ NetworkNumber = 0;
14
+ PLCNumber = 0xff;
15
+ NetworkStationNumber = 0;
16
+ TargetIOStation = 1023;
17
+ EnableWriteBitToWordRegister = true;
18
+ constructor(ipAddress, port = 6001) {
19
+ super(ipAddress, port);
20
+ this.ByteTransform.DataFormat = Core_1.DataFormat.DCBA;
21
+ }
22
+ GetNewNetMessage() {
23
+ return new INetMessage_1.MelsecMcMessage();
24
+ }
25
+ /**
26
+ * 打包二进制格式命令
27
+ */
28
+ pack(core) {
29
+ const header = Buffer.alloc(11);
30
+ // 副头部(二进制:0x5000)
31
+ header.writeUInt16LE(0x5000, 0);
32
+ // 网络号
33
+ header[2] = this.NetworkNumber;
34
+ // PLC 号
35
+ header[3] = this.PLCNumber;
36
+ // 目标 IO 站号(2 字节)
37
+ header.writeUInt16LE(this.TargetIOStation, 4);
38
+ // 网络站号
39
+ header[6] = this.NetworkStationNumber;
40
+ // 请求数据长度(2 字节) = core.length + 监视定时器(2)
41
+ header.writeUInt16LE(core.length + 2, 7);
42
+ // 监视定时器(2 字节)
43
+ header.writeUInt16LE(0x0010, 9);
44
+ return Buffer.concat([header, core]);
45
+ }
46
+ /**
47
+ * 发送请求
48
+ */
49
+ async transact(core) {
50
+ const frame = this.pack(core);
51
+ const result = await this.request(frame);
52
+ if (!result.IsSuccess)
53
+ return result;
54
+ const response = result.Content;
55
+ // 检查响应长度
56
+ if (response.length < 11) {
57
+ return new Core_1.OperateResult('Invalid response length', -1);
58
+ }
59
+ // 提取结束码(偏移 9,2 字节)
60
+ const endCode = response.readUInt16LE(9);
61
+ if (endCode !== 0) {
62
+ return new Core_1.OperateResult(`Melsec error: 0x${endCode.toString(16)}`, endCode);
63
+ }
64
+ // 提取数据部分(从偏移 11 开始)
65
+ return Core_1.OperateResult.CreateSuccessResult(response.subarray(11));
66
+ }
67
+ /**
68
+ * 读取字数据
69
+ */
70
+ async Read(address, length) {
71
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
72
+ if (!a.IsSuccess)
73
+ return Core_1.OperateResult.CreateFailedResult(a);
74
+ const d = a.Content;
75
+ const core = Buffer.alloc(10);
76
+ core[0] = 0x01; // 批量读取
77
+ core[1] = 0x04; // 子命令
78
+ core[2] = 0x00; // 字单位
79
+ // 起始地址(3字节小端)
80
+ core.writeUIntLE(d.AddressStart, 3, 3);
81
+ // 设备代码
82
+ core[6] = d.DataCode;
83
+ // 读取长度
84
+ core.writeUInt16LE(length, 7);
85
+ return this.transact(core);
86
+ }
87
+ /**
88
+ * 读取位数据
89
+ */
90
+ async ReadBool(address, length = 1) {
91
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, true);
92
+ if (!a.IsSuccess)
93
+ return Core_1.OperateResult.CreateFailedResult(a);
94
+ const d = a.Content;
95
+ const core = Buffer.alloc(10);
96
+ core[0] = 0x01; // 批量读取
97
+ core[1] = 0x04; // 子命令
98
+ core[2] = 0x01; // 位单位
99
+ // 起始地址(3字节小端)
100
+ core.writeUIntLE(d.AddressStart, 3, 3);
101
+ // 设备代码
102
+ core[6] = d.DataCode;
103
+ // 读取长度
104
+ core.writeUInt16LE(length, 7);
105
+ const result = await this.transact(core);
106
+ if (!result.IsSuccess)
107
+ return Core_1.OperateResult.CreateFailedResult(result);
108
+ const values = [];
109
+ for (let i = 0; i < length; i++) {
110
+ values.push(result.Content[i] !== 0);
111
+ }
112
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
113
+ }
114
+ /**
115
+ * 写入字数据
116
+ */
117
+ async Write(address, data) {
118
+ const length = Math.ceil(data.length / 2);
119
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
120
+ if (!a.IsSuccess)
121
+ return Core_1.OperateResult.CreateFailedResult(a);
122
+ const d = a.Content;
123
+ const core = Buffer.alloc(10 + data.length);
124
+ core[0] = 0x01; // 批量写入
125
+ core[1] = 0x14; // 子命令
126
+ core[2] = 0x00; // 字单位
127
+ // 起始地址(3字节小端)
128
+ core.writeUIntLE(d.AddressStart, 3, 3);
129
+ // 设备代码
130
+ core[6] = d.DataCode;
131
+ // 写入长度
132
+ core.writeUInt16LE(length, 7);
133
+ // 数据
134
+ data.copy(core, 10);
135
+ const result = await this.transact(core);
136
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
137
+ }
138
+ /**
139
+ * 读取 Int16
140
+ */
141
+ async ReadInt16(address, length = 1) {
142
+ const result = await this.Read(address, length);
143
+ if (!result.IsSuccess)
144
+ return Core_1.OperateResult.CreateFailedResult(result);
145
+ const values = [];
146
+ for (let i = 0; i < length; i++) {
147
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
148
+ }
149
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
150
+ }
151
+ /**
152
+ * 读取 UInt16
153
+ */
154
+ async ReadUInt16(address, length = 1) {
155
+ const result = await this.Read(address, length);
156
+ if (!result.IsSuccess)
157
+ return Core_1.OperateResult.CreateFailedResult(result);
158
+ const values = [];
159
+ for (let i = 0; i < length; i++) {
160
+ values.push(this.ByteTransform.TransUInt16(result.Content, i * 2));
161
+ }
162
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
163
+ }
164
+ /**
165
+ * 读取 Int32
166
+ */
167
+ async ReadInt32(address, length = 1) {
168
+ const result = await this.Read(address, length * 2);
169
+ if (!result.IsSuccess)
170
+ return Core_1.OperateResult.CreateFailedResult(result);
171
+ const values = [];
172
+ for (let i = 0; i < length; i++) {
173
+ values.push(this.ByteTransform.TransInt32(result.Content, i * 4));
174
+ }
175
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
176
+ }
177
+ /**
178
+ * 读取 Float
179
+ */
180
+ async ReadFloat(address, length = 1) {
181
+ const result = await this.Read(address, length * 2);
182
+ if (!result.IsSuccess)
183
+ return Core_1.OperateResult.CreateFailedResult(result);
184
+ const values = [];
185
+ for (let i = 0; i < length; i++) {
186
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
187
+ }
188
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
189
+ }
190
+ }
191
+ exports.MelsecMcUdp = MelsecMcUdp;
@@ -1,4 +1,25 @@
1
- import { ModbusRtu } from './ModbusRtu';
2
- /** Modbus ASCII serial client. */
3
- export declare class ModbusAscii extends ModbusRtu {
1
+ import { DeviceSerialPort } from '../core/DeviceSerialPort';
2
+ import { OperateResult, DataFormat } from '../core/Core';
3
+ import { INetMessage } from '../core/INetMessage';
4
+ /**
5
+ * Modbus ASCII 串口客户端
6
+ * Modbus-ASCII serial client with LRC check
7
+ */
8
+ export declare class ModbusAscii extends DeviceSerialPort {
9
+ Station: number;
10
+ AddressStartWithZero: boolean;
11
+ BroadcastStation: number;
12
+ get DataFormat(): DataFormat;
13
+ set DataFormat(value: DataFormat);
14
+ constructor(station?: number);
15
+ protected GetNewNetMessage(): INetMessage;
16
+ protected PackCommandWithHeader(command: Buffer): Buffer;
17
+ protected UnpackResponseContent(send: Buffer, response: Buffer): OperateResult<Buffer>;
18
+ static calculateLrc(data: Buffer): number;
19
+ static asciiToBinary(ascii: Buffer): OperateResult<Buffer>;
20
+ static ExtraAsciiResponseContent(send: Buffer, response: Buffer, broadcastStation?: number): OperateResult<Buffer>;
21
+ private addr;
22
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
23
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
24
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
4
25
  }
@@ -1,8 +1,114 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ModbusAscii = void 0;
4
- const ModbusRtu_1 = require("./ModbusRtu");
5
- /** Modbus ASCII serial client. */
6
- class ModbusAscii extends ModbusRtu_1.ModbusRtu {
4
+ const DeviceSerialPort_1 = require("../core/DeviceSerialPort");
5
+ const Core_1 = require("../core/Core");
6
+ const INetMessage_1 = require("../core/INetMessage");
7
+ const ModbusTcpNet_1 = require("./ModbusTcpNet");
8
+ /**
9
+ * Modbus ASCII 串口客户端
10
+ * Modbus-ASCII serial client with LRC check
11
+ */
12
+ class ModbusAscii extends DeviceSerialPort_1.DeviceSerialPort {
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(station = 1) {
23
+ super();
24
+ this.Station = station;
25
+ this.ByteTransform.DataFormat = Core_1.DataFormat.CDAB;
26
+ }
27
+ GetNewNetMessage() {
28
+ return new INetMessage_1.ModbusAsciiMessage();
29
+ }
30
+ PackCommandWithHeader(command) {
31
+ const core = Buffer.concat([Buffer.from([this.Station]), command]);
32
+ const lrc = 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
+ UnpackResponseContent(send, response) {
37
+ return ModbusAscii.ExtraAsciiResponseContent(send, response, this.BroadcastStation);
38
+ }
39
+ static calculateLrc(data) {
40
+ let sum = 0;
41
+ for (const byte of data)
42
+ sum += byte;
43
+ return ((~sum) + 1) & 0xFF;
44
+ }
45
+ static asciiToBinary(ascii) {
46
+ try {
47
+ let str = ascii.toString('ascii').trim();
48
+ if (!str.startsWith(':'))
49
+ return new Core_1.OperateResult('ASCII frame must start with ":"', -1);
50
+ str = str.substring(1);
51
+ if (str.endsWith('\r\n'))
52
+ str = str.substring(0, str.length - 2);
53
+ else if (str.endsWith('\n') || str.endsWith('\r'))
54
+ str = str.substring(0, str.length - 1);
55
+ if (str.length % 2 !== 0)
56
+ return new Core_1.OperateResult('Invalid ASCII length', -2);
57
+ return Core_1.OperateResult.CreateSuccessResult(Buffer.from(str, 'hex'));
58
+ }
59
+ catch (e) {
60
+ return new Core_1.OperateResult(`ASCII decode error: ${e.message}`, -3);
61
+ }
62
+ }
63
+ static ExtraAsciiResponseContent(send, response, broadcastStation = -1) {
64
+ const binaryResult = ModbusAscii.asciiToBinary(response);
65
+ if (!binaryResult.IsSuccess)
66
+ return binaryResult;
67
+ const binary = binaryResult.Content;
68
+ const calculated = ModbusAscii.calculateLrc(binary.subarray(0, binary.length - 1));
69
+ if (calculated !== binary[binary.length - 1])
70
+ return new Core_1.OperateResult(`LRC check failed`, -4);
71
+ const data = binary.subarray(0, binary.length - 1);
72
+ const functionCode = data[1];
73
+ if (functionCode === 0x01 || functionCode === 0x02 || functionCode === 0x03 || functionCode === 0x04) {
74
+ const length = data[2];
75
+ return Core_1.OperateResult.CreateSuccessResult(data.subarray(3, 3 + length));
76
+ }
77
+ return Core_1.OperateResult.CreateSuccessResult(data.subarray(2));
78
+ }
79
+ addr(input, code) {
80
+ const p = (0, ModbusTcpNet_1.parseModbusAddress)(input, this.Station, code);
81
+ if (p.IsSuccess && !this.AddressStartWithZero)
82
+ p.Content.address--;
83
+ return p;
84
+ }
85
+ async Read(address, length) {
86
+ const a = this.addr(address, 3);
87
+ if (!a.IsSuccess)
88
+ return Core_1.OperateResult.CreateFailedResult(a);
89
+ const cmd = Buffer.alloc(5);
90
+ cmd[0] = a.Content.code;
91
+ cmd.writeUInt16BE(a.Content.address, 1);
92
+ cmd.writeUInt16BE(length, 3);
93
+ return this.ReadFromCoreServer(cmd);
94
+ }
95
+ async ReadInt16(address, length = 1) {
96
+ const result = await this.Read(address, length);
97
+ if (!result.IsSuccess)
98
+ return Core_1.OperateResult.CreateFailedResult(result);
99
+ const values = [];
100
+ for (let i = 0; i < length; i++)
101
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
102
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
103
+ }
104
+ async ReadFloat(address, length = 1) {
105
+ const result = await this.Read(address, length * 2);
106
+ if (!result.IsSuccess)
107
+ return Core_1.OperateResult.CreateFailedResult(result);
108
+ const values = [];
109
+ for (let i = 0; i < length; i++)
110
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
111
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
112
+ }
7
113
  }
8
114
  exports.ModbusAscii = ModbusAscii;