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,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InovanceSerialOverTcp = void 0;
4
+ const ModbusRtuOverTcp_1 = require("../modbus/ModbusRtuOverTcp");
5
+ const Core_1 = require("../core/Core");
6
+ const InovanceTcpNet_1 = require("./InovanceTcpNet");
7
+ /**
8
+ * 汇川 PLC 串口协议 over TCP 客户端(基于 Modbus RTU over TCP)
9
+ * Inovance PLC serial protocol over TCP client (based on Modbus RTU over TCP)
10
+ */
11
+ class InovanceSerialOverTcp extends ModbusRtuOverTcp_1.ModbusRtuOverTcp {
12
+ Series = InovanceTcpNet_1.InovanceSeries.AM;
13
+ constructor(ipAddress, port = 502, station = 1) {
14
+ super(ipAddress, port, station);
15
+ }
16
+ /**
17
+ * 地址转换:将汇川地址转换为 Modbus 地址
18
+ */
19
+ TranslateToModbusAddress(address, modbusCode) {
20
+ return (0, InovanceTcpNet_1.parseInovanceAddress)(this.Series, address, modbusCode);
21
+ }
22
+ /**
23
+ * 读取数据
24
+ */
25
+ async Read(address, length) {
26
+ const a = this.TranslateToModbusAddress(address, 3);
27
+ return a.IsSuccess ? super.Read(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a);
28
+ }
29
+ /**
30
+ * 读取布尔值
31
+ */
32
+ async ReadBool(address, length = 1) {
33
+ const a = this.TranslateToModbusAddress(address, 1);
34
+ if (!a.IsSuccess)
35
+ return Core_1.OperateResult.CreateFailedResult(a);
36
+ // 构建读取线圈命令
37
+ const cmd = Buffer.alloc(5);
38
+ cmd[0] = 1; // 功能码 01
39
+ cmd.writeUInt16BE(parseInt(a.Content), 1);
40
+ cmd.writeUInt16BE(length, 3);
41
+ const result = await this.sendRequest(cmd);
42
+ if (!result.IsSuccess)
43
+ return Core_1.OperateResult.CreateFailedResult(result);
44
+ const values = [];
45
+ for (let i = 0; i < length; i++) {
46
+ const byteIndex = Math.floor(i / 8);
47
+ const bitIndex = i % 8;
48
+ values.push((result.Content[byteIndex] & (1 << bitIndex)) !== 0);
49
+ }
50
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
51
+ }
52
+ /**
53
+ * 写入数据
54
+ */
55
+ async Write(address, value) {
56
+ // 判断是位写入还是字写入
57
+ const isBitWrite = typeof value === 'boolean' || (Array.isArray(value) && typeof value[0] === 'boolean');
58
+ const code = isBitWrite ? 5 : 6;
59
+ const a = this.TranslateToModbusAddress(address, code);
60
+ if (!a.IsSuccess)
61
+ return Core_1.OperateResult.CreateFailedResult(a);
62
+ const addr = parseInt(a.Content);
63
+ // 布尔值写入
64
+ if (typeof value === 'boolean') {
65
+ const cmd = Buffer.alloc(5);
66
+ cmd[0] = 5;
67
+ cmd.writeUInt16BE(addr, 1);
68
+ cmd.writeUInt16BE(value ? 0xFF00 : 0x0000, 3);
69
+ const result = await this.sendRequest(cmd);
70
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
71
+ }
72
+ // 布尔数组写入
73
+ if (Array.isArray(value) && typeof value[0] === 'boolean') {
74
+ const bools = value;
75
+ const byteCount = Math.ceil(bools.length / 8);
76
+ const data = Buffer.alloc(byteCount);
77
+ for (let i = 0; i < bools.length; i++) {
78
+ if (bools[i]) {
79
+ const byteIndex = Math.floor(i / 8);
80
+ const bitIndex = i % 8;
81
+ data[byteIndex] |= (1 << bitIndex);
82
+ }
83
+ }
84
+ const cmd = Buffer.alloc(6 + byteCount);
85
+ cmd[0] = 15;
86
+ cmd.writeUInt16BE(addr, 1);
87
+ cmd.writeUInt16BE(bools.length, 3);
88
+ cmd[5] = byteCount;
89
+ data.copy(cmd, 6);
90
+ const result = await this.sendRequest(cmd);
91
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
92
+ }
93
+ // Buffer 写入
94
+ if (Buffer.isBuffer(value)) {
95
+ const length = Math.ceil(value.length / 2);
96
+ const a16 = this.TranslateToModbusAddress(address, 16);
97
+ if (!a16.IsSuccess)
98
+ return Core_1.OperateResult.CreateFailedResult(a16);
99
+ const addr16 = parseInt(a16.Content);
100
+ if (length === 1) {
101
+ const cmd = Buffer.alloc(5);
102
+ cmd[0] = 6;
103
+ cmd.writeUInt16BE(addr16, 1);
104
+ cmd.writeUInt16BE(value.readUInt16BE(0), 3);
105
+ const result = await this.sendRequest(cmd);
106
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
107
+ }
108
+ else {
109
+ const cmd = Buffer.alloc(6 + value.length);
110
+ cmd[0] = 16;
111
+ cmd.writeUInt16BE(addr16, 1);
112
+ cmd.writeUInt16BE(length, 3);
113
+ cmd[5] = value.length;
114
+ value.copy(cmd, 6);
115
+ const result = await this.sendRequest(cmd);
116
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
117
+ }
118
+ }
119
+ // 数字写入
120
+ if (typeof value === 'number') {
121
+ const cmd = Buffer.alloc(5);
122
+ cmd[0] = 6;
123
+ cmd.writeUInt16BE(addr, 1);
124
+ cmd.writeUInt16BE(value & 0xFFFF, 3);
125
+ const result = await this.sendRequest(cmd);
126
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
127
+ }
128
+ // 数字数组写入
129
+ if (Array.isArray(value) && typeof value[0] === 'number') {
130
+ const nums = value;
131
+ const data = Buffer.alloc(nums.length * 2);
132
+ for (let i = 0; i < nums.length; i++) {
133
+ data.writeUInt16BE(nums[i] & 0xFFFF, i * 2);
134
+ }
135
+ const cmd = Buffer.alloc(6 + data.length);
136
+ cmd[0] = 16;
137
+ cmd.writeUInt16BE(addr, 1);
138
+ cmd.writeUInt16BE(nums.length, 3);
139
+ cmd[5] = data.length;
140
+ data.copy(cmd, 6);
141
+ const result = await this.sendRequest(cmd);
142
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
143
+ }
144
+ return new Core_1.OperateResult('Unsupported value type', -1);
145
+ }
146
+ /**
147
+ * 读取 Int16
148
+ */
149
+ async ReadInt16(address, length = 1) {
150
+ const a = this.TranslateToModbusAddress(address, 3);
151
+ return a.IsSuccess ? super.ReadInt16(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a);
152
+ }
153
+ /**
154
+ * 读取 Float
155
+ */
156
+ async ReadFloat(address, length = 1) {
157
+ const a = this.TranslateToModbusAddress(address, 3);
158
+ return a.IsSuccess ? super.ReadFloat(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a);
159
+ }
160
+ /**
161
+ * 读取字节(MB 地址)
162
+ */
163
+ async ReadByte(address) {
164
+ const n = Number(address.replace(/^MB?/i, ''));
165
+ const r = await this.Read(`MW${Math.floor(n / 2)}`, 1);
166
+ if (!r.IsSuccess)
167
+ return Core_1.OperateResult.CreateFailedResult(r);
168
+ // 偶数字节在高位,奇数字节在低位
169
+ return Core_1.OperateResult.CreateSuccessResult(n % 2 === 0 ? r.Content[1] : r.Content[0]);
170
+ }
171
+ }
172
+ exports.InovanceSerialOverTcp = InovanceSerialOverTcp;
@@ -17,7 +17,5 @@ export declare class InovanceTcpNet extends ModbusTcpNet {
17
17
  Write(address: string, value: any): Promise<any>;
18
18
  ReadByte(address: string): Promise<OperateResult<any>>;
19
19
  }
20
- export declare class InovanceSerial extends InovanceTcpNet {
21
- }
22
- export declare class InovanceSerialOverTcp extends InovanceTcpNet {
23
- }
20
+ export { InovanceSerial } from './InovanceSerial';
21
+ export { InovanceSerialOverTcp } from './InovanceSerialOverTcp';
@@ -57,7 +57,17 @@ function parseInovanceAddress(series, address, modbusCode) {
57
57
  return Core_1.OperateResult.CreateSuccessResult(station + `x=${modbusCode + 48};` + address.replace(/^SDW?/i, ''));
58
58
  }
59
59
  if (series === InovanceSeries.H3U) {
60
- const map = { X: 63488, Y: 64512, SM: 9216, S: 57344, T: 61440, C: 62464, D: 0, SD: 9216, R: 12288 };
60
+ const map = {
61
+ X: 63488,
62
+ Y: 64512,
63
+ SM: 9216,
64
+ S: 57344,
65
+ T: 61440,
66
+ C: 62464,
67
+ D: 0,
68
+ SD: 9216,
69
+ R: 12288
70
+ };
61
71
  const m = upper.match(/^(SM|SD|[A-Z]+)(.+)$/);
62
72
  if (m && map[m[1]] !== undefined)
63
73
  return Core_1.OperateResult.CreateSuccessResult(station + String(map[m[1]] + (m[1] === 'X' || m[1] === 'Y' ? parseInt(m[2], 8) : parseInt(m[2], 10))));
@@ -76,18 +86,35 @@ function parseInovanceAddress(series, address, modbusCode) {
76
86
  }
77
87
  class InovanceTcpNet extends ModbusTcpNet_1.ModbusTcpNet {
78
88
  Series = InovanceSeries.AM;
79
- constructor(ipAddress, port = 502, station = 1) { super(ipAddress, port, station); }
80
- TranslateToModbusAddress(address, modbusCode) { return parseInovanceAddress(this.Series, address, modbusCode); }
89
+ constructor(ipAddress, port = 502, station = 1) {
90
+ super(ipAddress, port, station);
91
+ }
92
+ TranslateToModbusAddress(address, modbusCode) {
93
+ return parseInovanceAddress(this.Series, address, modbusCode);
94
+ }
81
95
  // Address translation changes only the wire address; data API remains Modbus-compatible.
82
- async Read(address, length) { const a = this.TranslateToModbusAddress(address, 3); return a.IsSuccess ? super.Read(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a); }
83
- async ReadBool(address, length) { const a = this.TranslateToModbusAddress(address, 1); return a.IsSuccess ? super.ReadBool(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a); }
84
- async Write(address, value) { const code = typeof value === 'boolean' || (Array.isArray(value) && typeof value[0] === 'boolean') ? 1 : 16; const a = this.TranslateToModbusAddress(address, code); return a.IsSuccess ? super.Write(a.Content, value) : Core_1.OperateResult.CreateFailedResult(a); }
85
- async ReadByte(address) { const n = Number(address.replace(/^MB?/i, '')); const r = await this.Read(`MW${Math.floor(n / 2)}`, 1); return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(n % 2 === 0 ? r.Content[1] : r.Content[0]) : Core_1.OperateResult.CreateFailedResult(r); }
96
+ async Read(address, length) {
97
+ const a = this.TranslateToModbusAddress(address, 3);
98
+ return a.IsSuccess ? super.Read(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a);
99
+ }
100
+ async ReadBool(address, length) {
101
+ const a = this.TranslateToModbusAddress(address, 1);
102
+ return a.IsSuccess ? super.ReadBool(a.Content, length) : Core_1.OperateResult.CreateFailedResult(a);
103
+ }
104
+ async Write(address, value) {
105
+ const code = typeof value === 'boolean' || (Array.isArray(value) && typeof value[0] === 'boolean') ? 1 : 16;
106
+ const a = this.TranslateToModbusAddress(address, code);
107
+ return a.IsSuccess ? super.Write(a.Content, value) : Core_1.OperateResult.CreateFailedResult(a);
108
+ }
109
+ async ReadByte(address) {
110
+ const n = Number(address.replace(/^MB?/i, ''));
111
+ const r = await this.Read(`MW${Math.floor(n / 2)}`, 1);
112
+ return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(n % 2 === 0 ? r.Content[1] : r.Content[0]) : Core_1.OperateResult.CreateFailedResult(r);
113
+ }
86
114
  }
87
115
  exports.InovanceTcpNet = InovanceTcpNet;
88
- class InovanceSerial extends InovanceTcpNet {
89
- }
90
- exports.InovanceSerial = InovanceSerial;
91
- class InovanceSerialOverTcp extends InovanceTcpNet {
92
- }
93
- exports.InovanceSerialOverTcp = InovanceSerialOverTcp;
116
+ // 导出串口和串口 over TCP 实现
117
+ var InovanceSerial_1 = require("./InovanceSerial");
118
+ Object.defineProperty(exports, "InovanceSerial", { enumerable: true, get: function () { return InovanceSerial_1.InovanceSerial; } });
119
+ var InovanceSerialOverTcp_1 = require("./InovanceSerialOverTcp");
120
+ Object.defineProperty(exports, "InovanceSerialOverTcp", { enumerable: true, get: function () { return InovanceSerialOverTcp_1.InovanceSerialOverTcp; } });
@@ -0,0 +1,49 @@
1
+ import { DeviceClient, OperateResult } from '../core/Core';
2
+ /**
3
+ * 三菱 MC 协议 ASCII 格式客户端
4
+ * Mitsubishi MC protocol ASCII format over TCP
5
+ */
6
+ export declare class MelsecMcAsciiNet extends DeviceClient {
7
+ NetworkNumber: number;
8
+ PLCNumber: number;
9
+ NetworkStationNumber: number;
10
+ TargetIOStation: number;
11
+ EnableWriteBitToWordRegister: boolean;
12
+ constructor(ipAddress?: string, port?: number);
13
+ /**
14
+ * 将二进制转换为 ASCII
15
+ */
16
+ private toAscii;
17
+ /**
18
+ * 将 ASCII 转换为二进制
19
+ */
20
+ private fromAscii;
21
+ /**
22
+ * 打包 ASCII 格式命令
23
+ */
24
+ protected packAscii(core: Buffer): Buffer;
25
+ /**
26
+ * 发送请求
27
+ */
28
+ private transact;
29
+ /**
30
+ * 读取字数据
31
+ */
32
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
33
+ /**
34
+ * 读取位数据
35
+ */
36
+ ReadBool(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
37
+ /**
38
+ * 写入字数据
39
+ */
40
+ Write(address: string, data: Buffer): Promise<OperateResult<void>>;
41
+ /**
42
+ * 读取 Int16
43
+ */
44
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
45
+ /**
46
+ * 读取 Float
47
+ */
48
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
49
+ }
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MelsecMcAsciiNet = void 0;
4
+ const Core_1 = require("../core/Core");
5
+ const MelsecMcNet_1 = require("./MelsecMcNet");
6
+ /**
7
+ * 三菱 MC 协议 ASCII 格式客户端
8
+ * Mitsubishi MC protocol ASCII format over TCP
9
+ */
10
+ class MelsecMcAsciiNet extends Core_1.DeviceClient {
11
+ NetworkNumber = 0;
12
+ PLCNumber = 0xff;
13
+ NetworkStationNumber = 0;
14
+ TargetIOStation = 1023;
15
+ EnableWriteBitToWordRegister = true;
16
+ constructor(ipAddress, port = 6001) {
17
+ super(ipAddress, port);
18
+ this.ByteTransform.DataFormat = Core_1.DataFormat.DCBA;
19
+ }
20
+ /**
21
+ * 将二进制转换为 ASCII
22
+ */
23
+ toAscii(data) {
24
+ return Buffer.from(data.toString('hex').toUpperCase(), 'ascii');
25
+ }
26
+ /**
27
+ * 将 ASCII 转换为二进制
28
+ */
29
+ fromAscii(ascii) {
30
+ return Buffer.from(ascii.toString('ascii'), 'hex');
31
+ }
32
+ /**
33
+ * 打包 ASCII 格式命令
34
+ */
35
+ packAscii(core) {
36
+ const header = Buffer.alloc(9);
37
+ header.writeUInt16BE(0x3530, 0); // "50"
38
+ header.writeUInt16BE(0x3030, 2); // "00"
39
+ // 网络号
40
+ header[4] = this.NetworkNumber.toString(16).toUpperCase().charCodeAt(0);
41
+ header[5] = this.NetworkNumber.toString(16).toUpperCase().charCodeAt(0);
42
+ // PLC 号
43
+ const plcHex = this.PLCNumber.toString(16).padStart(2, '0').toUpperCase();
44
+ header[6] = plcHex.charCodeAt(0);
45
+ header[7] = plcHex.charCodeAt(1);
46
+ // 目标 IO 站号
47
+ const ioHex = this.TargetIOStation.toString(16).padStart(4, '0').toUpperCase();
48
+ const ioBuffer = Buffer.from(ioHex, 'ascii');
49
+ // 网络站号
50
+ const stationHex = this.NetworkStationNumber.toString(16).padStart(2, '0').toUpperCase();
51
+ const stationBuffer = Buffer.from(stationHex, 'ascii');
52
+ // 数据长度(ASCII 字符数)
53
+ const dataLength = (core.length * 2).toString(16).padStart(4, '0').toUpperCase();
54
+ const lengthBuffer = Buffer.from(dataLength, 'ascii');
55
+ // 监视定时器
56
+ const timer = Buffer.from('0010', 'ascii');
57
+ // 转换核心数据为 ASCII
58
+ const coreAscii = this.toAscii(core);
59
+ return Buffer.concat([
60
+ header,
61
+ ioBuffer,
62
+ stationBuffer,
63
+ lengthBuffer,
64
+ timer,
65
+ coreAscii
66
+ ]);
67
+ }
68
+ /**
69
+ * 发送请求
70
+ */
71
+ async transact(core) {
72
+ const frame = this.packAscii(core);
73
+ const result = await this.request(frame, (data) => {
74
+ // ASCII 格式:响应至少包含 22 个字符的头部
75
+ if (data.length < 22)
76
+ throw new Error('incomplete');
77
+ // 提取数据长度
78
+ const lengthHex = data.toString('ascii', 14, 18);
79
+ const dataLength = parseInt(lengthHex, 16);
80
+ // 总长度 = 头部(22) + 数据长度
81
+ if (data.length < 22 + dataLength)
82
+ throw new Error('incomplete');
83
+ return data.subarray(0, 22 + dataLength);
84
+ });
85
+ if (!result.IsSuccess)
86
+ return result;
87
+ const response = result.Content;
88
+ // 提取结束码
89
+ const endCodeHex = response.toString('ascii', 18, 22);
90
+ const endCode = parseInt(endCodeHex, 16);
91
+ if (endCode !== 0) {
92
+ return new Core_1.OperateResult(`Melsec error: 0x${endCode.toString(16)}`, endCode);
93
+ }
94
+ // 提取数据部分并转换为二进制
95
+ const dataAscii = response.subarray(22);
96
+ return Core_1.OperateResult.CreateSuccessResult(this.fromAscii(dataAscii));
97
+ }
98
+ /**
99
+ * 读取字数据
100
+ */
101
+ async Read(address, length) {
102
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
103
+ if (!a.IsSuccess)
104
+ return Core_1.OperateResult.CreateFailedResult(a);
105
+ const d = a.Content;
106
+ const core = Buffer.alloc(10);
107
+ core[0] = 0x01; // 批量读取
108
+ core[1] = 0x04; // 子命令
109
+ core[2] = 0x00; // 字单位
110
+ // 起始地址(3字节小端)
111
+ core.writeUIntLE(d.AddressStart, 3, 3);
112
+ // 设备代码
113
+ core[6] = d.DataCode;
114
+ // 读取长度
115
+ core.writeUInt16LE(length, 7);
116
+ return this.transact(core);
117
+ }
118
+ /**
119
+ * 读取位数据
120
+ */
121
+ async ReadBool(address, length = 1) {
122
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, true);
123
+ if (!a.IsSuccess)
124
+ return Core_1.OperateResult.CreateFailedResult(a);
125
+ const d = a.Content;
126
+ const core = Buffer.alloc(10);
127
+ core[0] = 0x01; // 批量读取
128
+ core[1] = 0x04; // 子命令
129
+ core[2] = 0x01; // 位单位
130
+ // 起始地址(3字节小端)
131
+ core.writeUIntLE(d.AddressStart, 3, 3);
132
+ // 设备代码
133
+ core[6] = d.DataCode;
134
+ // 读取长度
135
+ core.writeUInt16LE(length, 7);
136
+ const result = await this.transact(core);
137
+ if (!result.IsSuccess)
138
+ return Core_1.OperateResult.CreateFailedResult(result);
139
+ const values = [];
140
+ for (let i = 0; i < length; i++) {
141
+ values.push(result.Content[i] !== 0);
142
+ }
143
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
144
+ }
145
+ /**
146
+ * 写入字数据
147
+ */
148
+ async Write(address, data) {
149
+ const length = Math.ceil(data.length / 2);
150
+ const a = (0, MelsecMcNet_1.parseMelsecAddress)(address, length, false);
151
+ if (!a.IsSuccess)
152
+ return Core_1.OperateResult.CreateFailedResult(a);
153
+ const d = a.Content;
154
+ const core = Buffer.alloc(10 + data.length);
155
+ core[0] = 0x01; // 批量写入
156
+ core[1] = 0x14; // 子命令
157
+ core[2] = 0x00; // 字单位
158
+ // 起始地址(3字节小端)
159
+ core.writeUIntLE(d.AddressStart, 3, 3);
160
+ // 设备代码
161
+ core[6] = d.DataCode;
162
+ // 写入长度
163
+ core.writeUInt16LE(length, 7);
164
+ // 数据
165
+ data.copy(core, 10);
166
+ const result = await this.transact(core);
167
+ return result.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : Core_1.OperateResult.CreateFailedResult(result);
168
+ }
169
+ /**
170
+ * 读取 Int16
171
+ */
172
+ async ReadInt16(address, length = 1) {
173
+ const result = await this.Read(address, length);
174
+ if (!result.IsSuccess)
175
+ return Core_1.OperateResult.CreateFailedResult(result);
176
+ const values = [];
177
+ for (let i = 0; i < length; i++) {
178
+ values.push(this.ByteTransform.TransInt16(result.Content, i * 2));
179
+ }
180
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
181
+ }
182
+ /**
183
+ * 读取 Float
184
+ */
185
+ async ReadFloat(address, length = 1) {
186
+ const result = await this.Read(address, length * 2);
187
+ if (!result.IsSuccess)
188
+ return Core_1.OperateResult.CreateFailedResult(result);
189
+ const values = [];
190
+ for (let i = 0; i < length; i++) {
191
+ values.push(this.ByteTransform.TransSingle(result.Content, i * 4));
192
+ }
193
+ return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
194
+ }
195
+ }
196
+ exports.MelsecMcAsciiNet = MelsecMcAsciiNet;
@@ -0,0 +1,54 @@
1
+ import { DeviceUdpNet } from '../core/DeviceUdpNet';
2
+ import { OperateResult } from '../core/Core';
3
+ /**
4
+ * 三菱 MC 协议 ASCII 格式 UDP 客户端
5
+ * Mitsubishi MC protocol ASCII format over UDP
6
+ */
7
+ export declare class MelsecMcAsciiUdp extends DeviceUdpNet {
8
+ NetworkNumber: number;
9
+ PLCNumber: number;
10
+ NetworkStationNumber: number;
11
+ TargetIOStation: number;
12
+ EnableWriteBitToWordRegister: boolean;
13
+ constructor(ipAddress?: string, port?: number);
14
+ /**
15
+ * 将二进制转换为 ASCII
16
+ */
17
+ private toAscii;
18
+ /**
19
+ * 将 ASCII 转换为二进制
20
+ */
21
+ private fromAscii;
22
+ /**
23
+ * 打包 ASCII 格式命令
24
+ */
25
+ protected packAscii(core: Buffer): Buffer;
26
+ /**
27
+ * 发送请求
28
+ */
29
+ private transact;
30
+ /**
31
+ * 读取字数据
32
+ */
33
+ Read(address: string, length: number): Promise<OperateResult<Buffer>>;
34
+ /**
35
+ * 读取位数据
36
+ */
37
+ ReadBool(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
38
+ /**
39
+ * 写入字数据
40
+ */
41
+ Write(address: string, data: Buffer): Promise<OperateResult<void>>;
42
+ /**
43
+ * 读取 Int16
44
+ */
45
+ ReadInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
46
+ /**
47
+ * 读取 UInt16
48
+ */
49
+ ReadUInt16(address: string, length?: number): Promise<OperateResult<number | number[]>>;
50
+ /**
51
+ * 读取 Float
52
+ */
53
+ ReadFloat(address: string, length?: number): Promise<OperateResult<number | number[]>>;
54
+ }