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.
- package/LICENSE +15 -0
- package/README.md +246 -14
- package/dist/Invt/InvtModbusTcp.d.ts +88 -0
- package/dist/Invt/InvtModbusTcp.js +255 -0
- package/dist/XCommunication.d.ts +18 -0
- package/dist/XCommunication.js +29 -0
- package/dist/ab/AbEtherNetIp.d.ts +1 -0
- package/dist/ab/AbEtherNetIp.js +2 -0
- package/dist/core/CommunicationLock.d.ts +88 -0
- package/dist/core/CommunicationLock.js +156 -0
- package/dist/core/Core.d.ts +27 -1
- package/dist/core/Core.js +375 -71
- package/dist/core/DeviceSerialPort.d.ts +64 -0
- package/dist/core/DeviceSerialPort.js +283 -0
- package/dist/core/DeviceUdpNet.d.ts +56 -0
- package/dist/core/DeviceUdpNet.js +307 -0
- package/dist/core/INetMessage.d.ts +145 -0
- package/dist/core/INetMessage.js +240 -0
- package/dist/debug/PingTest.d.ts +11 -0
- package/dist/debug/PingTest.js +59 -0
- package/dist/debug/tcpClient.d.ts +11 -0
- package/dist/debug/tcpClient.js +116 -0
- package/dist/debug/tcpServer.d.ts +12 -0
- package/dist/debug/tcpServer.js +102 -0
- package/dist/delta/DeltaTcpNet.d.ts +65 -0
- package/dist/delta/DeltaTcpNet.js +346 -0
- package/dist/ge/GeSRTPNet.d.ts +49 -0
- package/dist/ge/GeSRTPNet.js +337 -0
- package/dist/inovance/InovanceEasyNet.d.ts +8 -0
- package/dist/inovance/InovanceEasyNet.js +103 -0
- package/dist/inovance/InovanceSerial.d.ts +55 -0
- package/dist/inovance/InovanceSerial.js +145 -0
- package/dist/inovance/InovanceSerialOverTcp.d.ts +39 -0
- package/dist/inovance/InovanceSerialOverTcp.js +172 -0
- package/dist/inovance/InovanceTcpNet.d.ts +2 -4
- package/dist/inovance/InovanceTcpNet.js +40 -13
- package/dist/melsec/MelsecMcAsciiNet.d.ts +49 -0
- package/dist/melsec/MelsecMcAsciiNet.js +196 -0
- package/dist/melsec/MelsecMcAsciiUdp.d.ts +54 -0
- package/dist/melsec/MelsecMcAsciiUdp.js +204 -0
- package/dist/melsec/MelsecMcNet.d.ts +1 -8
- package/dist/melsec/MelsecMcNet.js +4 -14
- package/dist/melsec/MelsecMcUdp.d.ts +52 -0
- package/dist/melsec/MelsecMcUdp.js +191 -0
- package/dist/modbus/ModbusAscii.d.ts +24 -3
- package/dist/modbus/ModbusAscii.js +109 -3
- package/dist/modbus/ModbusAsciiOverTcp.d.ts +21 -3
- package/dist/modbus/ModbusAsciiOverTcp.js +67 -3
- package/dist/modbus/ModbusRtu.d.ts +101 -13
- package/dist/modbus/ModbusRtu.js +355 -21
- package/dist/modbus/ModbusRtuOverTcp.d.ts +23 -3
- package/dist/modbus/ModbusRtuOverTcp.js +68 -3
- package/dist/modbus/ModbusTcpNet.d.ts +16 -3
- package/dist/modbus/ModbusTcpNet.js +192 -60
- package/dist/modbus/ModbusUdpNet.d.ts +26 -3
- package/dist/modbus/ModbusUdpNet.js +125 -2
- package/dist/omron/OmronFinsNet.d.ts +1 -2
- package/dist/omron/OmronFinsNet.js +210 -69
- package/dist/omron/OmronFinsUdp.d.ts +41 -0
- package/dist/omron/OmronFinsUdp.js +146 -0
- package/dist/siemens/SiemensS7Net.d.ts +6 -0
- package/dist/siemens/SiemensS7Net.js +45 -6
- package/dist/xinjie/XinJETcpNet.d.ts +18 -0
- package/dist/xinjie/XinJETcpNet.js +106 -0
- package/package.json +16 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 X Communication
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
10
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
11
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
12
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
13
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
14
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
15
|
+
PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -2,15 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
面向 Node.js 和 TypeScript 的工业 PLC 通讯库,提供统一的异步连接、读取、写入和在线监测 API。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
所有协议客户端共享同一套方法命名(`ConnectServer` / `ReadInt16` / `WriteFloat` / `ConnectClose`)和同一种返回值(`OperateResult`),切换设备品牌时业务代码基本不用改动,也不需要在业务层处理底层报文。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- Melsec MC:MC 二进制 TCP/UDP 与 ASCII 兼容客户端
|
|
9
|
-
- Omron FINS:FINS TCP/UDP 客户端
|
|
10
|
-
- Inovance:AM、H3U、H5U、Easy、EVO 系列
|
|
11
|
-
- Modbus:Modbus TCP、RTU、RTU over TCP、ASCII、UDP
|
|
7
|
+
## 支持的设备与协议
|
|
12
8
|
|
|
13
|
-
|
|
9
|
+
| 品牌 / 协议 | 客户端类 | 默认端口 | 默认字节序 |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| Siemens S7(S7-200 / 200 Smart / 300 / 400 / 1200 / 1500) | `SiemensS7Net` | 102 | ABCD |
|
|
12
|
+
| Melsec MC 二进制 | `MelsecMcNet`、`MelsecMcUdp` | 6000 | DCBA |
|
|
13
|
+
| Melsec MC ASCII | `MelsecMcAsciiNet`、`MelsecMcAsciiUdp` | 6000 | DCBA |
|
|
14
|
+
| Omron FINS | `OmronFinsNet`、`OmronFinsUdp` | 9600 | CDAB |
|
|
15
|
+
| Inovance 汇川(AM / H3U / H5U / Easy / EVO) | `InovanceTcpNet`、`InovanceSerial`、`InovanceSerialOverTcp` | 502 | CDAB |
|
|
16
|
+
| Inovance EasyNet | `InovanceEasyNet` | 8000 | CDAB |
|
|
17
|
+
| Invt 英威腾 TS600 | `InvtModbusTcp` | 502 | CDAB |
|
|
18
|
+
| Delta 台达(DVP / AS300) | `DeltaTcpNet` | 502 | CDAB |
|
|
19
|
+
| GE SRTP(PACSystems / 90 系列) | `GeSRTPNet` | 18245 | DCBA |
|
|
20
|
+
| XinJE 信捷(XC / XD / XL) | `XinJETcpNet` | 502 | CDAB |
|
|
21
|
+
| Modbus | `ModbusTcpNet`、`ModbusUdpNet`、`ModbusRtu`、`ModbusRtuOverTcp`、`ModbusAscii`、`ModbusAsciiOverTcp` | 502 | CDAB |
|
|
22
|
+
| 调试工具 | `PingTest`、`TcpClient`、`TcpServer` | — | — |
|
|
23
|
+
|
|
24
|
+
汇川、英威腾、台达、信捷客户端都继承自 Modbus,地址会按各自的规则自动换算成 Modbus 地址,因此同时具备 Modbus 的全部能力。
|
|
14
25
|
|
|
15
26
|
## 安装
|
|
16
27
|
|
|
@@ -18,12 +29,14 @@
|
|
|
18
29
|
npm install ts-communication
|
|
19
30
|
```
|
|
20
31
|
|
|
21
|
-
使用
|
|
32
|
+
使用 `ModbusRtu`、`ModbusAscii` 或 `InovanceSerial` 等串口型客户端时,另外安装串口驱动:
|
|
22
33
|
|
|
23
34
|
```bash
|
|
24
35
|
npm install serialport
|
|
25
36
|
```
|
|
26
37
|
|
|
38
|
+
要求 Node.js 18 及以上版本。
|
|
39
|
+
|
|
27
40
|
## 快速开始
|
|
28
41
|
|
|
29
42
|
### Siemens S7
|
|
@@ -51,6 +64,8 @@ await plc.ConnectClose();
|
|
|
51
64
|
|
|
52
65
|
常用 Siemens 地址:`M100`、`M10.2`、`I0.0`、`Q0.0`、`DB1.0`、`DB1.DBD100`、`V100`。
|
|
53
66
|
|
|
67
|
+
`SiemensPLCS` 可选 `S1200`、`S1500`、`S300`、`S400`、`S200`、`S200Smart`。
|
|
68
|
+
|
|
54
69
|
### Melsec MC
|
|
55
70
|
|
|
56
71
|
```ts
|
|
@@ -67,6 +82,15 @@ await plc.WriteInt16('D100', 1234);
|
|
|
67
82
|
await plc.ConnectClose();
|
|
68
83
|
```
|
|
69
84
|
|
|
85
|
+
常用三菱地址:`M100`、`X10`、`Y10`、`D100`、`W100`、`R100`、`SM100`、`B100`、`ZR100`(`X`、`Y`、`B`、`W` 等按十六进制解析)。
|
|
86
|
+
|
|
87
|
+
MC 协议支持随机读取,一次报文读取多个不连续地址:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
const random = await plc.ReadRandomInt16(['D100', 'D200', 'W50']);
|
|
91
|
+
if (random.IsSuccess) console.log(random.Content); // [v1, v2, v3]
|
|
92
|
+
```
|
|
93
|
+
|
|
70
94
|
### Omron FINS
|
|
71
95
|
|
|
72
96
|
```ts
|
|
@@ -82,7 +106,9 @@ if (result.IsSuccess) console.log(result.Content);
|
|
|
82
106
|
await plc.ConnectClose();
|
|
83
107
|
```
|
|
84
108
|
|
|
85
|
-
|
|
109
|
+
常用欧姆龙地址:`D100`、`CIO100`、`W100`、`H100`、`A100`、`E100`(`E`/`EM` 区按十六进制解析)、`TIM10`、`CNT10`,位地址形如 `CIO100.05`。
|
|
110
|
+
|
|
111
|
+
### Inovance 汇川
|
|
86
112
|
|
|
87
113
|
```ts
|
|
88
114
|
import { InovanceSeries, InovanceTcpNet } from 'ts-communication';
|
|
@@ -100,7 +126,85 @@ await plc.WriteInt32('MD0', 100);
|
|
|
100
126
|
await plc.ConnectClose();
|
|
101
127
|
```
|
|
102
128
|
|
|
103
|
-
常用汇川地址:`M0`、`MX0.0`、`MW0`、`MD0`、`MB0`、`QX0.0`、`IX0.0`。地址格式会根据 `Series
|
|
129
|
+
常用汇川地址:`M0`、`MX0.0`、`MW0`、`MD0`、`MB0`、`QX0.0`、`IX0.0`。地址格式会根据 `Series`(`AM`、`H3U`、`H5U`、`Easy`、`EVO`)自动转换为对应的 Modbus 地址。
|
|
130
|
+
|
|
131
|
+
### Invt 英威腾 TS600
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { InvtModbusTcp } from 'ts-communication';
|
|
135
|
+
|
|
136
|
+
const plc = new InvtModbusTcp('192.168.1.60', 502, 1);
|
|
137
|
+
const connected = await plc.ConnectServer();
|
|
138
|
+
if (!connected.IsSuccess) throw new Error(connected.Message);
|
|
139
|
+
|
|
140
|
+
const result = await plc.ReadInt16('D100');
|
|
141
|
+
if (result.IsSuccess) console.log(result.Content);
|
|
142
|
+
|
|
143
|
+
await plc.WriteInt16('D100', 1234);
|
|
144
|
+
await plc.ConnectClose();
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
常用英威腾地址:`M0`、`S0`、`X0`(八进制)、`Y0`(八进制)、`D0`、`R0`、`T0`、`C0`。
|
|
148
|
+
|
|
149
|
+
### Delta 台达
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { DeltaSeries, DeltaTcpNet } from 'ts-communication';
|
|
153
|
+
|
|
154
|
+
const plc = new DeltaTcpNet('192.168.1.70', 502, 1);
|
|
155
|
+
plc.Series = DeltaSeries.Dvp; // 或 DeltaSeries.AS
|
|
156
|
+
|
|
157
|
+
const connected = await plc.ConnectServer();
|
|
158
|
+
if (!connected.IsSuccess) throw new Error(connected.Message);
|
|
159
|
+
|
|
160
|
+
const result = await plc.ReadInt16('D100');
|
|
161
|
+
if (result.IsSuccess) console.log(result.Content);
|
|
162
|
+
|
|
163
|
+
await plc.WriteInt16('D100', 1234);
|
|
164
|
+
await plc.ConnectClose();
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
常用台达地址:`M0`、`S0`、`X0`(八进制)、`Y0`(八进制)、`D0`、`T0`、`C0`。`Dvp` 适用于 DVP-ES/EX/EC/SS 与 DVP-SA/SC/SX/EH,`AS` 适用于 AS300。
|
|
168
|
+
|
|
169
|
+
### GE SRTP
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
import { GeSRTPNet } from 'ts-communication';
|
|
173
|
+
|
|
174
|
+
const plc = new GeSRTPNet('192.168.1.80', 18245);
|
|
175
|
+
const connected = await plc.ConnectServer();
|
|
176
|
+
if (!connected.IsSuccess) throw new Error(connected.Message);
|
|
177
|
+
|
|
178
|
+
const result = await plc.ReadInt16('R100');
|
|
179
|
+
if (result.IsSuccess) console.log(result.Content);
|
|
180
|
+
|
|
181
|
+
const bit = await plc.ReadBool('M100');
|
|
182
|
+
if (bit.IsSuccess) console.log(bit.Content);
|
|
183
|
+
|
|
184
|
+
await plc.WriteInt16('R100', 1234);
|
|
185
|
+
await plc.ConnectClose();
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
常用 GE 地址:`R1`、`AI1`、`AQ1`(仅字访问)、`I1`、`Q1`、`M1`、`T1`、`S1`、`G1`、`SA1`、`SB1`、`SC1`。GE 地址从 1 开始计数,有效范围 1–65536。
|
|
189
|
+
|
|
190
|
+
### XinJE 信捷
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
import { XinJESeries, XinJETcpNet } from 'ts-communication';
|
|
194
|
+
|
|
195
|
+
const plc = new XinJETcpNet('192.168.1.90', 502, XinJESeries.XD);
|
|
196
|
+
|
|
197
|
+
const connected = await plc.ConnectServer();
|
|
198
|
+
if (!connected.IsSuccess) throw new Error(connected.Message);
|
|
199
|
+
|
|
200
|
+
const result = await plc.ReadInt16('D100');
|
|
201
|
+
if (result.IsSuccess) console.log(result.Content);
|
|
202
|
+
|
|
203
|
+
await plc.WriteInt16('D100', 1234);
|
|
204
|
+
await plc.ConnectClose();
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`XinJESeries` 可选 `XC`、`XD`、`XL`;位地址(`X`、`Y`)按八进制解析。
|
|
104
208
|
|
|
105
209
|
### Modbus TCP
|
|
106
210
|
|
|
@@ -118,7 +222,66 @@ await plc.WriteUInt16('100', 88);
|
|
|
118
222
|
await plc.ConnectClose();
|
|
119
223
|
```
|
|
120
224
|
|
|
121
|
-
Modbus
|
|
225
|
+
#### Modbus 地址前缀
|
|
226
|
+
|
|
227
|
+
地址可以携带以下前缀,多个前缀可以组合使用:
|
|
228
|
+
|
|
229
|
+
| 前缀 | 含义 | 示例 |
|
|
230
|
+
| --- | --- | --- |
|
|
231
|
+
| `s=` | 站号(覆盖客户端的 `Station`) | `s=2;100` |
|
|
232
|
+
| `x=` | 读取功能码 | `x=4;100`(读输入寄存器) |
|
|
233
|
+
| `w=` | 写入功能码 | `w=6;100` |
|
|
234
|
+
| `format=` | 该次访问使用的字节序 | `format=ABCD;100` |
|
|
235
|
+
|
|
236
|
+
支持的功能码:`1`、`2`、`3`、`4`、`5`、`6`、`15`、`16`、`22`。位地址可以写成 `100.3` 的形式(位序号 0–15)。
|
|
237
|
+
|
|
238
|
+
#### 常用可调选项
|
|
239
|
+
|
|
240
|
+
```ts
|
|
241
|
+
plc.Station = 1; // 默认站号
|
|
242
|
+
plc.AddressStartWithZero = true; // 地址是否从 0 开始,false 时内部减 1
|
|
243
|
+
plc.StationCheckMatch = true; // 是否校验响应站号
|
|
244
|
+
plc.DisableFunctionCode06 = false;// 单字写入是否禁用功能码 06(改用 16)
|
|
245
|
+
plc.BroadcastStation = -1; // 广播站号,命中时不等待响应
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
`ReadCoil`、`ReadDiscrete`、`WriteMask` 也可直接使用。
|
|
249
|
+
|
|
250
|
+
### Modbus RTU / 串口客户端
|
|
251
|
+
|
|
252
|
+
串口客户端不使用 `ConnectServer`,而是配置串口参数后调用 `Open()` / `Close()`:
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
import { ModbusRtu } from 'ts-communication';
|
|
256
|
+
|
|
257
|
+
const plc = new ModbusRtu(1);
|
|
258
|
+
plc.PortName = 'COM3'; // Linux 下形如 '/dev/ttyUSB0'
|
|
259
|
+
plc.BaudRate = 9600;
|
|
260
|
+
plc.DataBits = 8;
|
|
261
|
+
plc.StopBits = 1;
|
|
262
|
+
plc.Parity = 'none';
|
|
263
|
+
|
|
264
|
+
const opened = await plc.Open();
|
|
265
|
+
if (!opened.IsSuccess) throw new Error(opened.Message);
|
|
266
|
+
|
|
267
|
+
const result = await plc.ReadInt16('100');
|
|
268
|
+
if (result.IsSuccess) console.log(result.Content);
|
|
269
|
+
|
|
270
|
+
await plc.Close();
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
汇川串口客户端用法相同,额外设置 `Series`:
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { InovanceSerial, InovanceSeries } from 'ts-communication';
|
|
277
|
+
|
|
278
|
+
const plc = new InovanceSerial(1);
|
|
279
|
+
plc.Series = InovanceSeries.H5U;
|
|
280
|
+
plc.PortName = 'COM3';
|
|
281
|
+
await plc.Open();
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
若串口设备通过串口服务器接入网络,改用 `ModbusRtuOverTcp` 或 `InovanceSerialOverTcp`,它们走 TCP,使用 `ConnectServer()` / `ConnectClose()`。
|
|
122
285
|
|
|
123
286
|
## C# 数值类型
|
|
124
287
|
|
|
@@ -145,6 +308,8 @@ await plc.ReadInt64('D110');
|
|
|
145
308
|
await plc.WriteFloat('D104', 12.5);
|
|
146
309
|
```
|
|
147
310
|
|
|
311
|
+
完整方法集:`ReadBool`、`ReadByte`、`ReadInt16`、`ReadUInt16`、`ReadInt32`、`ReadUInt32`、`ReadFloat`、`ReadDouble`、`ReadInt64`、`ReadUInt64`、`ReadString`、`Read`(原始字节),以及对应的 `Write*` 方法。`ReadInt64` / `ReadUInt64` 返回 `bigint`,写入时可传 `bigint` 或 `number`。
|
|
312
|
+
|
|
148
313
|
当传入 `length` 时,读取方法返回数组;不传入时返回单个值。
|
|
149
314
|
|
|
150
315
|
## 统一结果处理
|
|
@@ -156,10 +321,40 @@ const result = await plc.ReadInt16('D100');
|
|
|
156
321
|
if (result.IsSuccess) {
|
|
157
322
|
console.log(result.Content);
|
|
158
323
|
} else {
|
|
159
|
-
console.error(result.Message);
|
|
324
|
+
console.error(result.Message, result.ErrorCode);
|
|
160
325
|
}
|
|
161
326
|
```
|
|
162
327
|
|
|
328
|
+
`OperateResult` 字段:`IsSuccess`、`Content`、`Message`、`ErrorCode`。
|
|
329
|
+
|
|
330
|
+
## 连接与超时
|
|
331
|
+
|
|
332
|
+
```ts
|
|
333
|
+
plc.ConnectTimeOut = 5000; // 连接超时(毫秒)
|
|
334
|
+
plc.ReceiveTimeOut = 5000; // 接收超时(毫秒)
|
|
335
|
+
plc.AutoReConnect = true; // 请求时若连接已断开,自动重连
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
读写方法会在需要时自动建立连接,因此 `ConnectServer()` 主要用于提前确认设备可达。
|
|
339
|
+
|
|
340
|
+
## 并发与通信锁
|
|
341
|
+
|
|
342
|
+
客户端内置通信锁和请求队列,同一个实例上的并发读写会自动串行化,不会互相插入报文:
|
|
343
|
+
|
|
344
|
+
```ts
|
|
345
|
+
const [a, b, c] = await Promise.all([
|
|
346
|
+
plc.ReadInt16('D100'),
|
|
347
|
+
plc.ReadInt16('D200'),
|
|
348
|
+
plc.ReadFloat('D300'),
|
|
349
|
+
]);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
如果外部已经保证了串行访问,可以关闭锁以减少开销:
|
|
353
|
+
|
|
354
|
+
```ts
|
|
355
|
+
plc.EnableCommunicationLock = false;
|
|
356
|
+
```
|
|
357
|
+
|
|
163
358
|
## 长任务与轮询
|
|
164
359
|
|
|
165
360
|
库客户端可以在 Node.js Worker、Electron Worker 或其他后台线程中长期复用。建议保持一个客户端实例由一个工作线程独占,并在循环中复用连接:
|
|
@@ -176,7 +371,37 @@ while (running) {
|
|
|
176
371
|
|
|
177
372
|
## 字节序
|
|
178
373
|
|
|
179
|
-
客户端公开 `ByteTransform` 和 `DataFormat`,可根据 PLC 配置选择 `ABCD`、`BADC`、`CDAB` 或 `DCBA
|
|
374
|
+
客户端公开 `ByteTransform` 和 `DataFormat`,可根据 PLC 配置选择 `ABCD`、`BADC`、`CDAB` 或 `DCBA`:
|
|
375
|
+
|
|
376
|
+
```ts
|
|
377
|
+
import { DataFormat } from 'ts-communication';
|
|
378
|
+
|
|
379
|
+
plc.ByteTransform.DataFormat = DataFormat.ABCD;
|
|
380
|
+
plc.ByteTransform.IsStringReverseByteWord = false; // 字符串是否按字内交换字节
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
各协议的默认字节序见上面的协议表。数值读出来明显不对(例如浮点数变成极大值、32 位整数高低字反了)时,应先确认 PLC 侧的字节排列方式,再调整 `DataFormat`。Modbus 系客户端还可以只针对单次访问指定:`format=DCBA;100`。
|
|
384
|
+
|
|
385
|
+
## 调试工具
|
|
386
|
+
|
|
387
|
+
```ts
|
|
388
|
+
import { PingTest, TcpClient, TcpServer } from 'ts-communication';
|
|
389
|
+
|
|
390
|
+
// 连通性检查
|
|
391
|
+
const ping = await PingTest.ping('192.168.1.10');
|
|
392
|
+
console.log(ping.success, ping.time, ping.message);
|
|
393
|
+
console.log(await PingTest.isHostOnline('192.168.1.10', 2000));
|
|
394
|
+
|
|
395
|
+
// 手动收发报文
|
|
396
|
+
const client = new TcpClient('192.168.1.10', 502);
|
|
397
|
+
await client.connect();
|
|
398
|
+
const response = await client.sendAndReceive(Buffer.from([0x00, 0x01]), 5000);
|
|
399
|
+
|
|
400
|
+
// 本地模拟服务端
|
|
401
|
+
const server = new TcpServer(5000, '0.0.0.0');
|
|
402
|
+
await server.start();
|
|
403
|
+
await server.stop();
|
|
404
|
+
```
|
|
180
405
|
|
|
181
406
|
## TypeScript
|
|
182
407
|
|
|
@@ -186,11 +411,18 @@ while (running) {
|
|
|
186
411
|
import { SiemensS7Net } from 'ts-communication';
|
|
187
412
|
```
|
|
188
413
|
|
|
414
|
+
从源码构建:
|
|
415
|
+
|
|
416
|
+
```bash
|
|
417
|
+
npm run build
|
|
418
|
+
```
|
|
419
|
+
|
|
189
420
|
## 注意事项
|
|
190
421
|
|
|
191
422
|
- 使用真实设备前,请确认 PLC IP、端口、站号、机架/槽号以及访问权限。
|
|
192
|
-
- Siemens S7-1200/S7-1500 通常使用 TCP `102`
|
|
423
|
+
- Siemens S7-1200/S7-1500 通常使用 TCP `102` 端口,并需要在 PLC 组态中允许 PUT/GET 访问。
|
|
193
424
|
- 串口协议需要操作系统具有对应串口权限,并正确配置波特率、数据位、停止位和校验位。
|
|
425
|
+
- 一个客户端实例对应一条物理连接,不要在多个线程/进程之间共享同一个实例。
|
|
194
426
|
- 所有示例都应检查 `IsSuccess` 后再读取 `Content`。
|
|
195
427
|
|
|
196
428
|
## License
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ModbusTcpNet } from '../modbus/ModbusTcpNet';
|
|
2
|
+
import { OperateResult } from '../core/Core';
|
|
3
|
+
/**
|
|
4
|
+
* 英威腾 TS600 系列 PLC 的 Modbus TCP 通讯类
|
|
5
|
+
* 支持通过 PLC 原生地址格式进行读写操作
|
|
6
|
+
*/
|
|
7
|
+
export declare class InvtModbusTcp extends ModbusTcpNet {
|
|
8
|
+
constructor(ipAddress?: string, port?: number, station?: number);
|
|
9
|
+
/**
|
|
10
|
+
* 将英威腾 PLC 地址转换为 Modbus 地址
|
|
11
|
+
* @param address 英威腾 PLC 地址,例如:M100、S100、X0、Y0、T100、C100、D100、R100
|
|
12
|
+
* @param modbusCode Modbus功能码
|
|
13
|
+
* @returns 转换后的Modbus地址
|
|
14
|
+
*/
|
|
15
|
+
TranslateToModbusAddress(address: string, modbusCode: number): OperateResult<string>;
|
|
16
|
+
/**
|
|
17
|
+
* 读取寄存器数据
|
|
18
|
+
*/
|
|
19
|
+
Read(address: string, length: number): Promise<any>;
|
|
20
|
+
/**
|
|
21
|
+
* 读取布尔类型数据
|
|
22
|
+
*/
|
|
23
|
+
ReadBool(address: string, length?: number): Promise<any>;
|
|
24
|
+
/**
|
|
25
|
+
* 读取线圈
|
|
26
|
+
*/
|
|
27
|
+
ReadCoil(address: string, length?: number): Promise<any>;
|
|
28
|
+
/**
|
|
29
|
+
* 写入数据
|
|
30
|
+
*/
|
|
31
|
+
Write(address: string, value: any): Promise<any>;
|
|
32
|
+
/**
|
|
33
|
+
* 读取Int16类型数据
|
|
34
|
+
*/
|
|
35
|
+
ReadInt16(address: string, length?: number): Promise<any>;
|
|
36
|
+
/**
|
|
37
|
+
* 读取UInt16类型数据
|
|
38
|
+
*/
|
|
39
|
+
ReadUInt16(address: string, length?: number): Promise<any>;
|
|
40
|
+
/**
|
|
41
|
+
* 读取Int32类型数据
|
|
42
|
+
*/
|
|
43
|
+
ReadInt32(address: string, length?: number): Promise<any>;
|
|
44
|
+
/**
|
|
45
|
+
* 读取UInt32类型数据
|
|
46
|
+
*/
|
|
47
|
+
ReadUInt32(address: string, length?: number): Promise<any>;
|
|
48
|
+
/**
|
|
49
|
+
* 读取Float类型数据
|
|
50
|
+
*/
|
|
51
|
+
ReadFloat(address: string, length?: number): Promise<any>;
|
|
52
|
+
/**
|
|
53
|
+
* 读取Double类型数据
|
|
54
|
+
*/
|
|
55
|
+
ReadDouble(address: string, length?: number): Promise<any>;
|
|
56
|
+
/**
|
|
57
|
+
* 读取 64 位整数。父类的类型读取路径使用原始读取,避免已转换地址再次映射。
|
|
58
|
+
*/
|
|
59
|
+
ReadInt64(address: string, length?: number): Promise<any>;
|
|
60
|
+
ReadUInt64(address: string, length?: number): Promise<any>;
|
|
61
|
+
ReadString(address: string, length: number, encoding?: BufferEncoding): Promise<any>;
|
|
62
|
+
/**
|
|
63
|
+
* 写入Int16类型数据
|
|
64
|
+
*/
|
|
65
|
+
WriteInt16(address: string, value: number): Promise<any>;
|
|
66
|
+
/**
|
|
67
|
+
* 写入UInt16类型数据
|
|
68
|
+
*/
|
|
69
|
+
WriteUInt16(address: string, value: number): Promise<any>;
|
|
70
|
+
/**
|
|
71
|
+
* 写入Int32类型数据
|
|
72
|
+
*/
|
|
73
|
+
WriteInt32(address: string, value: number): Promise<any>;
|
|
74
|
+
/**
|
|
75
|
+
* 写入UInt32类型数据
|
|
76
|
+
*/
|
|
77
|
+
WriteUInt32(address: string, value: number): Promise<any>;
|
|
78
|
+
/**
|
|
79
|
+
* 写入Float类型数据
|
|
80
|
+
*/
|
|
81
|
+
WriteFloat(address: string, value: number): Promise<any>;
|
|
82
|
+
/**
|
|
83
|
+
* 写入Double类型数据
|
|
84
|
+
*/
|
|
85
|
+
WriteDouble(address: string, value: number): Promise<any>;
|
|
86
|
+
WriteInt64(address: string, value: bigint | number): Promise<any>;
|
|
87
|
+
WriteUInt64(address: string, value: bigint | number): Promise<any>;
|
|
88
|
+
}
|