ts-communication
v1.1.0
Published
工业 PLC 通讯库,支持 Siemens S7、Melsec MC、Omron FINS、Inovance、Invt、Delta、GE SRTP、XinJE 和 Modbus。
Downloads
26
Maintainers
Readme
ts-communication
面向 Node.js 和 TypeScript 的工业 PLC 通讯库,提供统一的异步连接、读取、写入和在线监测 API。
所有协议客户端共享同一套方法命名(ConnectServer / ReadInt16 / WriteFloat / ConnectClose)和同一种返回值(OperateResult),切换设备品牌时业务代码基本不用改动,也不需要在业务层处理底层报文。
支持的设备与协议
| 品牌 / 协议 | 客户端类 | 默认端口 | 默认字节序 |
| --- | --- | --- | --- |
| Siemens S7(S7-200 / 200 Smart / 300 / 400 / 1200 / 1500) | SiemensS7Net | 102 | ABCD |
| Melsec MC 二进制 | MelsecMcNet、MelsecMcUdp | 6000 | DCBA |
| Melsec MC ASCII | MelsecMcAsciiNet、MelsecMcAsciiUdp | 6000 | DCBA |
| Omron FINS | OmronFinsNet、OmronFinsUdp | 9600 | CDAB |
| Inovance 汇川(AM / H3U / H5U / Easy / EVO) | InovanceTcpNet、InovanceSerial、InovanceSerialOverTcp | 502 | CDAB |
| Inovance EasyNet | InovanceEasyNet | 8000 | CDAB |
| Invt 英威腾 TS600 | InvtModbusTcp | 502 | CDAB |
| Delta 台达(DVP / AS300) | DeltaTcpNet | 502 | CDAB |
| GE SRTP(PACSystems / 90 系列) | GeSRTPNet | 18245 | DCBA |
| XinJE 信捷(XC / XD / XL) | XinJETcpNet | 502 | CDAB |
| Modbus | ModbusTcpNet、ModbusUdpNet、ModbusRtu、ModbusRtuOverTcp、ModbusAscii、ModbusAsciiOverTcp | 502 | CDAB |
| 调试工具 | PingTest、TcpClient、TcpServer | — | — |
汇川、英威腾、台达、信捷客户端都继承自 Modbus,地址会按各自的规则自动换算成 Modbus 地址,因此同时具备 Modbus 的全部能力。
安装
npm install ts-communication使用 ModbusRtu、ModbusAscii 或 InovanceSerial 等串口型客户端时,另外安装串口驱动:
npm install serialport要求 Node.js 18 及以上版本。
快速开始
Siemens S7
import { SiemensPLCS, SiemensS7Net } from 'ts-communication';
const plc = new SiemensS7Net(SiemensPLCS.S1200, '192.168.1.10');
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) {
throw new Error(connected.Message);
}
const temperature = await plc.ReadFloat('DB1.0');
if (temperature.IsSuccess) {
console.log(temperature.Content);
}
const written = await plc.WriteFloat('DB1.0', 25.5);
console.log(written.IsSuccess, written.Message);
await plc.ConnectClose();常用 Siemens 地址:M100、M10.2、I0.0、Q0.0、DB1.0、DB1.DBD100、V100。
SiemensPLCS 可选 S1200、S1500、S300、S400、S200、S200Smart。
Melsec MC
import { MelsecMcNet } from 'ts-communication';
const plc = new MelsecMcNet('192.168.1.20', 6000);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) console.log(result.Content);
await plc.WriteInt16('D100', 1234);
await plc.ConnectClose();常用三菱地址:M100、X10、Y10、D100、W100、R100、SM100、B100、ZR100(X、Y、B、W 等按十六进制解析)。
MC 协议支持随机读取,一次报文读取多个不连续地址:
const random = await plc.ReadRandomInt16(['D100', 'D200', 'W50']);
if (random.IsSuccess) console.log(random.Content); // [v1, v2, v3]Omron FINS
import { OmronFinsNet } from 'ts-communication';
const plc = new OmronFinsNet('192.168.1.30', 9600);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadUInt16('D100');
if (result.IsSuccess) console.log(result.Content);
await plc.ConnectClose();常用欧姆龙地址:D100、CIO100、W100、H100、A100、E100(E/EM 区按十六进制解析)、TIM10、CNT10,位地址形如 CIO100.05。
Inovance 汇川
import { InovanceSeries, InovanceTcpNet } from 'ts-communication';
const plc = new InovanceTcpNet('192.168.1.40', 502, 1);
plc.Series = InovanceSeries.AM;
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt32('MD0');
if (result.IsSuccess) console.log(result.Content);
await plc.WriteInt32('MD0', 100);
await plc.ConnectClose();常用汇川地址:M0、MX0.0、MW0、MD0、MB0、QX0.0、IX0.0。地址格式会根据 Series(AM、H3U、H5U、Easy、EVO)自动转换为对应的 Modbus 地址。
Invt 英威腾 TS600
import { InvtModbusTcp } from 'ts-communication';
const plc = new InvtModbusTcp('192.168.1.60', 502, 1);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) console.log(result.Content);
await plc.WriteInt16('D100', 1234);
await plc.ConnectClose();常用英威腾地址:M0、S0、X0(八进制)、Y0(八进制)、D0、R0、T0、C0。
Delta 台达
import { DeltaSeries, DeltaTcpNet } from 'ts-communication';
const plc = new DeltaTcpNet('192.168.1.70', 502, 1);
plc.Series = DeltaSeries.Dvp; // 或 DeltaSeries.AS
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) console.log(result.Content);
await plc.WriteInt16('D100', 1234);
await plc.ConnectClose();常用台达地址:M0、S0、X0(八进制)、Y0(八进制)、D0、T0、C0。Dvp 适用于 DVP-ES/EX/EC/SS 与 DVP-SA/SC/SX/EH,AS 适用于 AS300。
GE SRTP
import { GeSRTPNet } from 'ts-communication';
const plc = new GeSRTPNet('192.168.1.80', 18245);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt16('R100');
if (result.IsSuccess) console.log(result.Content);
const bit = await plc.ReadBool('M100');
if (bit.IsSuccess) console.log(bit.Content);
await plc.WriteInt16('R100', 1234);
await plc.ConnectClose();常用 GE 地址:R1、AI1、AQ1(仅字访问)、I1、Q1、M1、T1、S1、G1、SA1、SB1、SC1。GE 地址从 1 开始计数,有效范围 1–65536。
XinJE 信捷
import { XinJESeries, XinJETcpNet } from 'ts-communication';
const plc = new XinJETcpNet('192.168.1.90', 502, XinJESeries.XD);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) console.log(result.Content);
await plc.WriteInt16('D100', 1234);
await plc.ConnectClose();XinJESeries 可选 XC、XD、XL;位地址(X、Y)按八进制解析。
Modbus TCP
import { ModbusTcpNet } from 'ts-communication';
const plc = new ModbusTcpNet('192.168.1.50', 502, 1);
const connected = await plc.ConnectServer();
if (!connected.IsSuccess) throw new Error(connected.Message);
const value = await plc.ReadUInt16('100');
if (value.IsSuccess) console.log(value.Content);
await plc.WriteUInt16('100', 88);
await plc.ConnectClose();Modbus 地址前缀
地址可以携带以下前缀,多个前缀可以组合使用:
| 前缀 | 含义 | 示例 |
| --- | --- | --- |
| s= | 站号(覆盖客户端的 Station) | s=2;100 |
| x= | 读取功能码 | x=4;100(读输入寄存器) |
| w= | 写入功能码 | w=6;100 |
| format= | 该次访问使用的字节序 | format=ABCD;100 |
支持的功能码:1、2、3、4、5、6、15、16、22。位地址可以写成 100.3 的形式(位序号 0–15)。
常用可调选项
plc.Station = 1; // 默认站号
plc.AddressStartWithZero = true; // 地址是否从 0 开始,false 时内部减 1
plc.StationCheckMatch = true; // 是否校验响应站号
plc.DisableFunctionCode06 = false;// 单字写入是否禁用功能码 06(改用 16)
plc.BroadcastStation = -1; // 广播站号,命中时不等待响应ReadCoil、ReadDiscrete、WriteMask 也可直接使用。
Modbus RTU / 串口客户端
串口客户端不使用 ConnectServer,而是配置串口参数后调用 Open() / Close():
import { ModbusRtu } from 'ts-communication';
const plc = new ModbusRtu(1);
plc.PortName = 'COM3'; // Linux 下形如 '/dev/ttyUSB0'
plc.BaudRate = 9600;
plc.DataBits = 8;
plc.StopBits = 1;
plc.Parity = 'none';
const opened = await plc.Open();
if (!opened.IsSuccess) throw new Error(opened.Message);
const result = await plc.ReadInt16('100');
if (result.IsSuccess) console.log(result.Content);
await plc.Close();汇川串口客户端用法相同,额外设置 Series:
import { InovanceSerial, InovanceSeries } from 'ts-communication';
const plc = new InovanceSerial(1);
plc.Series = InovanceSeries.H5U;
plc.PortName = 'COM3';
await plc.Open();若串口设备通过串口服务器接入网络,改用 ModbusRtuOverTcp 或 InovanceSerialOverTcp,它们走 TCP,使用 ConnectServer() / ConnectClose()。
C# 数值类型
JavaScript 的 number 不区分整数宽度。库提供与 PLC 常用类型对应的显式类型类,写入时可以保留 byte、short、ushort、int、uint、float、double、long 和 ulong 的范围与字节宽度。
import { Byte, Float, Int16, UInt16, Int64 } from 'ts-communication';
const byteValue = new Byte(255);
const shortValue = new Int16(-12);
const unsignedValue = new UInt16(60000);
const floatValue = new Float(12.5);
const longValue = new Int64(9007199254740993n);客户端也提供直接的强类型读写方法:
await plc.ReadInt16('D100');
await plc.ReadUInt32('D102');
await plc.ReadFloat('D104');
await plc.ReadDouble('D106');
await plc.ReadInt64('D110');
await plc.WriteFloat('D104', 12.5);完整方法集:ReadBool、ReadByte、ReadInt16、ReadUInt16、ReadInt32、ReadUInt32、ReadFloat、ReadDouble、ReadInt64、ReadUInt64、ReadString、Read(原始字节),以及对应的 Write* 方法。ReadInt64 / ReadUInt64 返回 bigint,写入时可传 bigint 或 number。
当传入 length 时,读取方法返回数组;不传入时返回单个值。
统一结果处理
所有连接、读取和写入操作都返回 OperateResult。访问 Content 前应先检查 IsSuccess:
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) {
console.log(result.Content);
} else {
console.error(result.Message, result.ErrorCode);
}OperateResult 字段:IsSuccess、Content、Message、ErrorCode。
连接与超时
plc.ConnectTimeOut = 5000; // 连接超时(毫秒)
plc.ReceiveTimeOut = 5000; // 接收超时(毫秒)
plc.AutoReConnect = true; // 请求时若连接已断开,自动重连读写方法会在需要时自动建立连接,因此 ConnectServer() 主要用于提前确认设备可达。
并发与通信锁
客户端内置通信锁和请求队列,同一个实例上的并发读写会自动串行化,不会互相插入报文:
const [a, b, c] = await Promise.all([
plc.ReadInt16('D100'),
plc.ReadInt16('D200'),
plc.ReadFloat('D300'),
]);如果外部已经保证了串行访问,可以关闭锁以减少开销:
plc.EnableCommunicationLock = false;长任务与轮询
库客户端可以在 Node.js Worker、Electron Worker 或其他后台线程中长期复用。建议保持一个客户端实例由一个工作线程独占,并在循环中复用连接:
while (running) {
const result = await plc.ReadInt16('D100');
if (result.IsSuccess) {
console.log(new Date().toISOString(), result.Content);
}
await new Promise(resolve => setTimeout(resolve, 1000));
}字节序
客户端公开 ByteTransform 和 DataFormat,可根据 PLC 配置选择 ABCD、BADC、CDAB 或 DCBA:
import { DataFormat } from 'ts-communication';
plc.ByteTransform.DataFormat = DataFormat.ABCD;
plc.ByteTransform.IsStringReverseByteWord = false; // 字符串是否按字内交换字节各协议的默认字节序见上面的协议表。数值读出来明显不对(例如浮点数变成极大值、32 位整数高低字反了)时,应先确认 PLC 侧的字节排列方式,再调整 DataFormat。Modbus 系客户端还可以只针对单次访问指定:format=DCBA;100。
调试工具
import { PingTest, TcpClient, TcpServer } from 'ts-communication';
// 连通性检查
const ping = await PingTest.ping('192.168.1.10');
console.log(ping.success, ping.time, ping.message);
console.log(await PingTest.isHostOnline('192.168.1.10', 2000));
// 手动收发报文
const client = new TcpClient('192.168.1.10', 502);
await client.connect();
const response = await client.sendAndReceive(Buffer.from([0x00, 0x01]), 5000);
// 本地模拟服务端
const server = new TcpServer(5000, '0.0.0.0');
await server.start();
await server.stop();TypeScript
库内置 TypeScript 类型声明,可直接用于 TypeScript 项目:
import { SiemensS7Net } from 'ts-communication';从源码构建:
npm run build注意事项
- 使用真实设备前,请确认 PLC IP、端口、站号、机架/槽号以及访问权限。
- Siemens S7-1200/S7-1500 通常使用 TCP
102端口,并需要在 PLC 组态中允许 PUT/GET 访问。 - 串口协议需要操作系统具有对应串口权限,并正确配置波特率、数据位、停止位和校验位。
- 一个客户端实例对应一条物理连接,不要在多个线程/进程之间共享同一个实例。
- 所有示例都应检查
IsSuccess后再读取Content。
License
ISC
