ts-communication 1.0.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/README.md +198 -0
- package/dist/XCommunication.d.ts +11 -0
- package/dist/XCommunication.js +27 -0
- package/dist/core/Core.d.ts +95 -0
- package/dist/core/Core.js +267 -0
- package/dist/inovance/InovanceTcpNet.d.ts +23 -0
- package/dist/inovance/InovanceTcpNet.js +93 -0
- package/dist/melsec/MelsecMcNet.d.ts +55 -0
- package/dist/melsec/MelsecMcNet.js +271 -0
- package/dist/modbus/ModbusAscii.d.ts +4 -0
- package/dist/modbus/ModbusAscii.js +8 -0
- package/dist/modbus/ModbusAsciiOverTcp.d.ts +4 -0
- package/dist/modbus/ModbusAsciiOverTcp.js +8 -0
- package/dist/modbus/ModbusRtu.d.ts +15 -0
- package/dist/modbus/ModbusRtu.js +27 -0
- package/dist/modbus/ModbusRtuOverTcp.d.ts +4 -0
- package/dist/modbus/ModbusRtuOverTcp.js +8 -0
- package/dist/modbus/ModbusTcpNet.d.ts +55 -0
- package/dist/modbus/ModbusTcpNet.js +192 -0
- package/dist/modbus/ModbusUdpNet.d.ts +4 -0
- package/dist/modbus/ModbusUdpNet.js +8 -0
- package/dist/omron/OmronFinsNet.d.ts +57 -0
- package/dist/omron/OmronFinsNet.js +95 -0
- package/dist/siemens/SiemensS7Net.d.ts +69 -0
- package/dist/siemens/SiemensS7Net.js +276 -0
- package/package.json +39 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InovanceSerialOverTcp = exports.InovanceSerial = exports.InovanceTcpNet = exports.InovanceSeries = void 0;
|
|
4
|
+
exports.parseInovanceAddress = parseInovanceAddress;
|
|
5
|
+
const ModbusTcpNet_1 = require("../modbus/ModbusTcpNet");
|
|
6
|
+
const Core_1 = require("../core/Core");
|
|
7
|
+
var InovanceSeries;
|
|
8
|
+
(function (InovanceSeries) {
|
|
9
|
+
InovanceSeries["AM"] = "AM";
|
|
10
|
+
InovanceSeries["H3U"] = "H3U";
|
|
11
|
+
InovanceSeries["H5U"] = "H5U";
|
|
12
|
+
InovanceSeries["Easy"] = "Easy";
|
|
13
|
+
InovanceSeries["EVO"] = "EVO";
|
|
14
|
+
})(InovanceSeries || (exports.InovanceSeries = InovanceSeries = {}));
|
|
15
|
+
function parseInovanceAddress(series, address, modbusCode) {
|
|
16
|
+
try {
|
|
17
|
+
let station = '';
|
|
18
|
+
const sm = address.match(/^s=(\d+);(.*)$/i);
|
|
19
|
+
if (sm) {
|
|
20
|
+
station = `s=${sm[1]};`;
|
|
21
|
+
address = sm[2];
|
|
22
|
+
}
|
|
23
|
+
const upper = address.toUpperCase();
|
|
24
|
+
const bit = (text) => text.includes('.') ? `${parseInt(text.split('.')[0], 10) * 8 + parseInt(text.split('.')[1], 10)}` : text;
|
|
25
|
+
const isBitCode = modbusCode === 1 || modbusCode === 5 || modbusCode === 15;
|
|
26
|
+
if (series === InovanceSeries.AM || series === InovanceSeries.EVO) {
|
|
27
|
+
if (/^(QX|Q)/i.test(address))
|
|
28
|
+
return Core_1.OperateResult.CreateSuccessResult(station + bit(address.replace(/^QX?/i, '')));
|
|
29
|
+
if (/^(IX|I)/i.test(address))
|
|
30
|
+
return Core_1.OperateResult.CreateSuccessResult(station + 'x=2;' + bit(address.replace(/^IX?/i, '')));
|
|
31
|
+
if (/^MW/i.test(address))
|
|
32
|
+
return Core_1.OperateResult.CreateSuccessResult(station + address.slice(2));
|
|
33
|
+
if (/^MD/i.test(address)) {
|
|
34
|
+
const suffix = address.slice(2);
|
|
35
|
+
if (isBitCode && suffix.includes('.'))
|
|
36
|
+
return Core_1.OperateResult.CreateSuccessResult(station + `${Number(suffix.split('.')[0]) * 2}.${Number(suffix.split('.')[1])}`);
|
|
37
|
+
return Core_1.OperateResult.CreateSuccessResult(station + String(Number(suffix) * 2));
|
|
38
|
+
}
|
|
39
|
+
if (/^MB/i.test(address)) {
|
|
40
|
+
const n = Number(address.slice(2));
|
|
41
|
+
if (!Number.isInteger(n) || n % 2 !== 0)
|
|
42
|
+
return new Core_1.OperateResult(`Address[${address}] must use an even byte offset`);
|
|
43
|
+
return Core_1.OperateResult.CreateSuccessResult(station + String(n / 2));
|
|
44
|
+
}
|
|
45
|
+
if (/^MX/i.test(address)) {
|
|
46
|
+
const suffix = address.slice(2).split('.');
|
|
47
|
+
const n = Number(suffix[0]);
|
|
48
|
+
if (isBitCode)
|
|
49
|
+
return Core_1.OperateResult.CreateSuccessResult(station + `${Math.floor(n / 2)}.${(n % 2) * 8 + Number(suffix[1] ?? 0)}`);
|
|
50
|
+
return Core_1.OperateResult.CreateSuccessResult(station + String(Math.floor(n / 2)));
|
|
51
|
+
}
|
|
52
|
+
if (/^M/i.test(address))
|
|
53
|
+
return Core_1.OperateResult.CreateSuccessResult(station + address.slice(1));
|
|
54
|
+
if (isBitCode && /^SMX?/i.test(address))
|
|
55
|
+
return Core_1.OperateResult.CreateSuccessResult(station + `x=${modbusCode + 48};` + bit(address.replace(/^SMX?/i, '')));
|
|
56
|
+
if (!isBitCode && /^SDW?/i.test(address))
|
|
57
|
+
return Core_1.OperateResult.CreateSuccessResult(station + `x=${modbusCode + 48};` + address.replace(/^SDW?/i, ''));
|
|
58
|
+
}
|
|
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 };
|
|
61
|
+
const m = upper.match(/^(SM|SD|[A-Z]+)(.+)$/);
|
|
62
|
+
if (m && map[m[1]] !== undefined)
|
|
63
|
+
return Core_1.OperateResult.CreateSuccessResult(station + String(map[m[1]] + (m[1] === 'X' || m[1] === 'Y' ? parseInt(m[2], 8) : parseInt(m[2], 10))));
|
|
64
|
+
}
|
|
65
|
+
if (series === InovanceSeries.H5U || series === InovanceSeries.Easy) {
|
|
66
|
+
const map = { M: 0, B: 12288, S: 57344, X: 63488, Y: 64512, D: 0, R: 12288 };
|
|
67
|
+
const m = upper.match(/^([A-Z]+)(.+)$/);
|
|
68
|
+
if (m && map[m[1]] !== undefined)
|
|
69
|
+
return Core_1.OperateResult.CreateSuccessResult(station + String(map[m[1]] + parseInt(m[2], 10)));
|
|
70
|
+
}
|
|
71
|
+
throw new Error(`Unsupported Inovance address: ${address}`);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
return new Core_1.OperateResult(e.message);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
class InovanceTcpNet extends ModbusTcpNet_1.ModbusTcpNet {
|
|
78
|
+
Series = InovanceSeries.AM;
|
|
79
|
+
constructor(ipAddress, port = 502, station = 1) { super(ipAddress, port, station); }
|
|
80
|
+
TranslateToModbusAddress(address, modbusCode) { return parseInovanceAddress(this.Series, address, modbusCode); }
|
|
81
|
+
// 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); }
|
|
86
|
+
}
|
|
87
|
+
exports.InovanceTcpNet = InovanceTcpNet;
|
|
88
|
+
class InovanceSerial extends InovanceTcpNet {
|
|
89
|
+
}
|
|
90
|
+
exports.InovanceSerial = InovanceSerial;
|
|
91
|
+
class InovanceSerialOverTcp extends InovanceTcpNet {
|
|
92
|
+
}
|
|
93
|
+
exports.InovanceSerialOverTcp = InovanceSerialOverTcp;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { DataFormat, DeviceClient, OperateResult } from '../core/Core';
|
|
2
|
+
export interface McAddressData {
|
|
3
|
+
AddressStart: number;
|
|
4
|
+
Length: number;
|
|
5
|
+
DataCode: number;
|
|
6
|
+
DataType: number;
|
|
7
|
+
FromBase: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseMelsecAddress(input: string, length: number, isBit?: boolean): OperateResult<McAddressData>;
|
|
10
|
+
export declare class MelsecMcNet extends DeviceClient {
|
|
11
|
+
NetworkNumber: number;
|
|
12
|
+
PLCNumber: number;
|
|
13
|
+
NetworkStationNumber: number;
|
|
14
|
+
TargetIOStation: number;
|
|
15
|
+
EnableWriteBitToWordRegister: boolean;
|
|
16
|
+
DataFormat: DataFormat;
|
|
17
|
+
constructor(ipAddress?: string, port?: number);
|
|
18
|
+
protected pack(core: Buffer): Buffer<ArrayBuffer>;
|
|
19
|
+
private transact;
|
|
20
|
+
Read(address: string, length: number): Promise<OperateResult<Buffer>>;
|
|
21
|
+
ReadBool(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
|
|
22
|
+
private typedRead;
|
|
23
|
+
ReadInt16(a: string, l?: number): Promise<OperateResult<any>>;
|
|
24
|
+
ReadUInt16(a: string, l?: number): Promise<OperateResult<any>>;
|
|
25
|
+
ReadInt32(a: string, l?: number): Promise<OperateResult<any>>;
|
|
26
|
+
ReadUInt32(a: string, l?: number): Promise<OperateResult<any>>;
|
|
27
|
+
ReadFloat(a: string, l?: number): Promise<OperateResult<any>>;
|
|
28
|
+
ReadDouble(a: string, l?: number): Promise<OperateResult<any>>;
|
|
29
|
+
ReadInt64(a: string, l?: number): Promise<OperateResult<any>>;
|
|
30
|
+
ReadUInt64(a: string, l?: number): Promise<OperateResult<any>>;
|
|
31
|
+
ReadString(address: string, length: number, encoding?: BufferEncoding): Promise<OperateResult<string>>;
|
|
32
|
+
Write(address: string, value: number | boolean | string | Buffer | number[] | boolean[]): Promise<OperateResult<any>>;
|
|
33
|
+
WriteByte(a: string, v: number): Promise<OperateResult<any>>;
|
|
34
|
+
WriteInt16(a: string, v: number): Promise<OperateResult<any>>;
|
|
35
|
+
WriteUInt16(a: string, v: number): Promise<OperateResult<any>>;
|
|
36
|
+
WriteInt32(a: string, v: number): Promise<OperateResult<any>>;
|
|
37
|
+
WriteUInt32(a: string, v: number): Promise<OperateResult<any>>;
|
|
38
|
+
WriteFloat(a: string, v: number): Promise<OperateResult<any>>;
|
|
39
|
+
WriteDouble(a: string, v: number): Promise<OperateResult<any>>;
|
|
40
|
+
WriteInt64(a: string, v: bigint | number): Promise<OperateResult<any>>;
|
|
41
|
+
WriteUInt64(a: string, v: bigint | number): Promise<OperateResult<any>>;
|
|
42
|
+
ReadRandom(address: string[], length?: number[]): Promise<OperateResult<Buffer>>;
|
|
43
|
+
ReadRandomInt16(address: string[]): Promise<OperateResult<number[]>>;
|
|
44
|
+
ReadRandomUInt16(address: string[]): Promise<OperateResult<number[]>>;
|
|
45
|
+
ConnectServerAsync(): Promise<OperateResult<any>>;
|
|
46
|
+
ConnectCloseAsync(): Promise<OperateResult<any>>;
|
|
47
|
+
RemoteRun(): Promise<OperateResult<string>>;
|
|
48
|
+
RemoteStop(): Promise<OperateResult<string>>;
|
|
49
|
+
}
|
|
50
|
+
export declare class MelsecMcAsciiNet extends MelsecMcNet {
|
|
51
|
+
}
|
|
52
|
+
export declare class MelsecMcUdp extends MelsecMcNet {
|
|
53
|
+
}
|
|
54
|
+
export declare class MelsecMcAsciiUdp extends MelsecMcNet {
|
|
55
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MelsecMcAsciiUdp = exports.MelsecMcUdp = exports.MelsecMcAsciiNet = exports.MelsecMcNet = void 0;
|
|
4
|
+
exports.parseMelsecAddress = parseMelsecAddress;
|
|
5
|
+
const Core_1 = require("../core/Core");
|
|
6
|
+
const MC = {
|
|
7
|
+
M: [0x90, 1, 10],
|
|
8
|
+
X: [0x9c, 1, 16],
|
|
9
|
+
Y: [0x9d, 1, 16],
|
|
10
|
+
SM: [0x91, 1, 10],
|
|
11
|
+
S: [0x98, 1, 10],
|
|
12
|
+
L: [0x92, 1, 10],
|
|
13
|
+
F: [0x93, 1, 10],
|
|
14
|
+
V: [0x94, 1, 10],
|
|
15
|
+
B: [0xa0, 1, 16],
|
|
16
|
+
SB: [0xa1, 1, 16],
|
|
17
|
+
DX: [0xa2, 1, 16],
|
|
18
|
+
DY: [0xa3, 1, 16],
|
|
19
|
+
D: [0xa8, 0, 10],
|
|
20
|
+
SD: [0xa9, 0, 10],
|
|
21
|
+
W: [0xb4, 0, 16],
|
|
22
|
+
SW: [0xb5, 0, 16],
|
|
23
|
+
R: [0xaf, 0, 10],
|
|
24
|
+
Z: [0xcc, 0, 10],
|
|
25
|
+
ZR: [0xb0, 0, 10],
|
|
26
|
+
TN: [0xc2, 0, 10],
|
|
27
|
+
TS: [0xc1, 1, 10],
|
|
28
|
+
TC: [0xc0, 1, 10],
|
|
29
|
+
SS: [0xc7, 1, 10],
|
|
30
|
+
SC: [0xc6, 1, 10],
|
|
31
|
+
SN: [0xc8, 0, 10],
|
|
32
|
+
CN: [0xc5, 0, 10],
|
|
33
|
+
CS: [0xc4, 1, 10],
|
|
34
|
+
CC: [0xc3, 1, 10]
|
|
35
|
+
};
|
|
36
|
+
function parseMelsecAddress(input, length, isBit = false) {
|
|
37
|
+
try {
|
|
38
|
+
const m = input.match(/^([A-Za-z]+)([0-9A-Fa-f]+)$/);
|
|
39
|
+
if (!m)
|
|
40
|
+
throw new Error(`Invalid Mitsubishi address: ${input}`);
|
|
41
|
+
const key = m[1].toUpperCase();
|
|
42
|
+
const type = MC[key];
|
|
43
|
+
if (!type)
|
|
44
|
+
throw new Error(`Unsupported Mitsubishi address: ${input}`);
|
|
45
|
+
const value = parseInt(m[2], type[2]);
|
|
46
|
+
return Core_1.OperateResult.CreateSuccessResult({
|
|
47
|
+
AddressStart: value,
|
|
48
|
+
Length: length,
|
|
49
|
+
DataCode: type[0],
|
|
50
|
+
DataType: type[1],
|
|
51
|
+
FromBase: type[2]
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
return new Core_1.OperateResult(e.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
class MelsecMcNet extends Core_1.DeviceClient {
|
|
59
|
+
NetworkNumber = 0;
|
|
60
|
+
PLCNumber = 0xff;
|
|
61
|
+
NetworkStationNumber = 0;
|
|
62
|
+
TargetIOStation = 1023;
|
|
63
|
+
EnableWriteBitToWordRegister = true;
|
|
64
|
+
DataFormat = Core_1.DataFormat.DCBA;
|
|
65
|
+
constructor(ipAddress, port = 6000) {
|
|
66
|
+
super(ipAddress, ipAddress === undefined ? undefined : port);
|
|
67
|
+
this.Port = ipAddress === undefined ? 5000 : port;
|
|
68
|
+
this.ByteTransform = new Core_1.ByteTransform(this.DataFormat);
|
|
69
|
+
}
|
|
70
|
+
pack(core) {
|
|
71
|
+
const h = Buffer.alloc(11 + core.length);
|
|
72
|
+
h[0] = 0x50;
|
|
73
|
+
h[1] = 0;
|
|
74
|
+
h[2] = this.NetworkNumber;
|
|
75
|
+
h[3] = this.PLCNumber;
|
|
76
|
+
h.writeUInt16LE(this.TargetIOStation, 4);
|
|
77
|
+
h[6] = this.NetworkStationNumber;
|
|
78
|
+
h.writeUInt16LE(core.length + 2, 7);
|
|
79
|
+
h.writeUInt16LE(10, 9);
|
|
80
|
+
core.copy(h, 11);
|
|
81
|
+
return h;
|
|
82
|
+
}
|
|
83
|
+
async transact(core) {
|
|
84
|
+
const frame = this.pack(core);
|
|
85
|
+
const r = await this.request(frame, data => {
|
|
86
|
+
if (data.length < 11)
|
|
87
|
+
throw new Error('incomplete Mitsubishi response');
|
|
88
|
+
const n = data.readUInt16LE(7);
|
|
89
|
+
if (data.length < 9 + n)
|
|
90
|
+
throw new Error('incomplete Mitsubishi response');
|
|
91
|
+
return data.subarray(0, 9 + n);
|
|
92
|
+
});
|
|
93
|
+
if (!r.IsSuccess)
|
|
94
|
+
return r;
|
|
95
|
+
const body = r.Content;
|
|
96
|
+
const status = body.readUInt16LE(9);
|
|
97
|
+
if (status !== 0)
|
|
98
|
+
return new Core_1.OperateResult(`Mitsubishi error 0x${status.toString(16)}`, status);
|
|
99
|
+
return Core_1.OperateResult.CreateSuccessResult(body.subarray(11));
|
|
100
|
+
}
|
|
101
|
+
async Read(address, length) {
|
|
102
|
+
const a = 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] = 1;
|
|
108
|
+
core[1] = 4;
|
|
109
|
+
core[2] = 0;
|
|
110
|
+
core.writeUIntLE(d.AddressStart, 4, 3);
|
|
111
|
+
core[7] = d.DataCode;
|
|
112
|
+
core.writeUInt16LE(length, 8);
|
|
113
|
+
return this.transact(core);
|
|
114
|
+
}
|
|
115
|
+
async ReadBool(address, length) {
|
|
116
|
+
const a = parseMelsecAddress(address, length ?? 1, true);
|
|
117
|
+
if (!a.IsSuccess)
|
|
118
|
+
return Core_1.OperateResult.CreateFailedResult(a);
|
|
119
|
+
const d = a.Content;
|
|
120
|
+
const core = Buffer.alloc(10);
|
|
121
|
+
core[0] = 1;
|
|
122
|
+
core[1] = 4;
|
|
123
|
+
core[2] = 1;
|
|
124
|
+
core.writeUIntLE(d.AddressStart, 4, 3);
|
|
125
|
+
core[7] = d.DataCode;
|
|
126
|
+
core.writeUInt16LE(length ?? 1, 8);
|
|
127
|
+
const r = await this.transact(core);
|
|
128
|
+
if (!r.IsSuccess)
|
|
129
|
+
return Core_1.OperateResult.CreateFailedResult(r);
|
|
130
|
+
const values = [];
|
|
131
|
+
for (let i = 0; i < (length ?? 1); i++)
|
|
132
|
+
values.push(r.Content[i] !== 0);
|
|
133
|
+
return Core_1.OperateResult.CreateSuccessResult(length === undefined ? values[0] : values);
|
|
134
|
+
}
|
|
135
|
+
async typedRead(address, length, width, fn) {
|
|
136
|
+
const r = await this.Read(address, length * width / 2);
|
|
137
|
+
if (!r.IsSuccess)
|
|
138
|
+
return Core_1.OperateResult.CreateFailedResult(r);
|
|
139
|
+
const values = Array.from({ length }, (_, i) => fn(r.Content, i * width));
|
|
140
|
+
return Core_1.OperateResult.CreateSuccessResult(length === 1 ? values[0] : values);
|
|
141
|
+
}
|
|
142
|
+
async ReadInt16(a, l) {
|
|
143
|
+
return this.typedRead(a, l ?? 1, 2, (b, o) => this.ByteTransform.TransInt16(b, o));
|
|
144
|
+
}
|
|
145
|
+
async ReadUInt16(a, l) {
|
|
146
|
+
return this.typedRead(a, l ?? 1, 2, (b, o) => this.ByteTransform.TransUInt16(b, o));
|
|
147
|
+
}
|
|
148
|
+
async ReadInt32(a, l) {
|
|
149
|
+
return this.typedRead(a, l ?? 1, 4, (b, o) => this.ByteTransform.TransInt32(b, o));
|
|
150
|
+
}
|
|
151
|
+
async ReadUInt32(a, l) {
|
|
152
|
+
return this.typedRead(a, l ?? 1, 4, (b, o) => this.ByteTransform.TransUInt32(b, o));
|
|
153
|
+
}
|
|
154
|
+
async ReadFloat(a, l) {
|
|
155
|
+
return this.typedRead(a, l ?? 1, 4, (b, o) => this.ByteTransform.TransSingle(b, o));
|
|
156
|
+
}
|
|
157
|
+
async ReadDouble(a, l) {
|
|
158
|
+
return this.typedRead(a, l ?? 1, 8, (b, o) => this.ByteTransform.TransDouble(b, o));
|
|
159
|
+
}
|
|
160
|
+
async ReadInt64(a, l) {
|
|
161
|
+
return this.typedRead(a, l ?? 1, 8, (b, o) => this.ByteTransform.TransInt64(b, o));
|
|
162
|
+
}
|
|
163
|
+
async ReadUInt64(a, l) {
|
|
164
|
+
return this.typedRead(a, l ?? 1, 8, (b, o) => this.ByteTransform.TransUInt64(b, o));
|
|
165
|
+
}
|
|
166
|
+
async ReadString(address, length, encoding = 'utf8') {
|
|
167
|
+
const r = await this.Read(address, length);
|
|
168
|
+
return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(this.ByteTransform.TransString(r.Content, encoding)) : Core_1.OperateResult.CreateFailedResult(r);
|
|
169
|
+
}
|
|
170
|
+
async Write(address, value) {
|
|
171
|
+
const isBit = typeof value === 'boolean' || (Array.isArray(value) && typeof value[0] === 'boolean');
|
|
172
|
+
const a = parseMelsecAddress(address, Array.isArray(value) ? value.length : 1, isBit);
|
|
173
|
+
if (!a.IsSuccess)
|
|
174
|
+
return a;
|
|
175
|
+
const d = a.Content;
|
|
176
|
+
let data;
|
|
177
|
+
if (typeof value === 'boolean')
|
|
178
|
+
data = Buffer.from([value ? 1 : 0]);
|
|
179
|
+
else if (typeof value === 'string')
|
|
180
|
+
data = Buffer.from(value);
|
|
181
|
+
else if (Buffer.isBuffer(value))
|
|
182
|
+
data = value;
|
|
183
|
+
else if (Array.isArray(value) && typeof value[0] === 'boolean')
|
|
184
|
+
data = Buffer.from(value.map(v => v ? 1 : 0));
|
|
185
|
+
else
|
|
186
|
+
data = this.ByteTransform.TransByte(value, 2);
|
|
187
|
+
const core = Buffer.alloc(10 + data.length);
|
|
188
|
+
core[0] = 1;
|
|
189
|
+
core[1] = 0x14;
|
|
190
|
+
core[2] = isBit ? 1 : 0;
|
|
191
|
+
core.writeUIntLE(d.AddressStart, 4, 3);
|
|
192
|
+
core[7] = d.DataCode;
|
|
193
|
+
core.writeUInt16LE(isBit ? data.length : data.length / 2, 8);
|
|
194
|
+
data.copy(core, 10);
|
|
195
|
+
const r = await this.transact(core);
|
|
196
|
+
return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult() : r;
|
|
197
|
+
}
|
|
198
|
+
WriteByte(a, v) {
|
|
199
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Byte(v)));
|
|
200
|
+
}
|
|
201
|
+
WriteInt16(a, v) {
|
|
202
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Int16(v)));
|
|
203
|
+
}
|
|
204
|
+
WriteUInt16(a, v) {
|
|
205
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.UInt16(v)));
|
|
206
|
+
}
|
|
207
|
+
WriteInt32(a, v) {
|
|
208
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Int32(v)));
|
|
209
|
+
}
|
|
210
|
+
WriteUInt32(a, v) {
|
|
211
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.UInt32(v)));
|
|
212
|
+
}
|
|
213
|
+
WriteFloat(a, v) {
|
|
214
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Float(v)));
|
|
215
|
+
}
|
|
216
|
+
WriteDouble(a, v) {
|
|
217
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Double(v)));
|
|
218
|
+
}
|
|
219
|
+
WriteInt64(a, v) {
|
|
220
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.Int64(v)));
|
|
221
|
+
}
|
|
222
|
+
WriteUInt64(a, v) {
|
|
223
|
+
return this.Write(a, this.ByteTransform.TransByte(new Core_1.UInt64(v)));
|
|
224
|
+
}
|
|
225
|
+
async ReadRandom(address, length) {
|
|
226
|
+
const ds = address.map((x, i) => parseMelsecAddress(x, length?.[i] ?? 1, false));
|
|
227
|
+
const bad = ds.find(x => !x.IsSuccess);
|
|
228
|
+
if (bad)
|
|
229
|
+
return Core_1.OperateResult.CreateFailedResult(bad);
|
|
230
|
+
const list = ds.map(x => x.Content);
|
|
231
|
+
const core = Buffer.alloc(6 + list.length * 4);
|
|
232
|
+
core[0] = 3;
|
|
233
|
+
core[1] = 4;
|
|
234
|
+
core[4] = list.length;
|
|
235
|
+
list.forEach((d, i) => {
|
|
236
|
+
core.writeUIntLE(d.AddressStart, 6 + i * 4, 3);
|
|
237
|
+
core[9 + i * 4] = d.DataCode;
|
|
238
|
+
});
|
|
239
|
+
return this.transact(core);
|
|
240
|
+
}
|
|
241
|
+
async ReadRandomInt16(address) {
|
|
242
|
+
const r = await this.ReadRandom(address);
|
|
243
|
+
return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(Array.from({ length: address.length }, (_, i) => this.ByteTransform.TransInt16(r.Content, i * 2))) : Core_1.OperateResult.CreateFailedResult(r);
|
|
244
|
+
}
|
|
245
|
+
async ReadRandomUInt16(address) {
|
|
246
|
+
const r = await this.ReadRandom(address);
|
|
247
|
+
return r.IsSuccess ? Core_1.OperateResult.CreateSuccessResult(Array.from({ length: address.length }, (_, i) => this.ByteTransform.TransUInt16(r.Content, i * 2))) : Core_1.OperateResult.CreateFailedResult(r);
|
|
248
|
+
}
|
|
249
|
+
async ConnectServerAsync() {
|
|
250
|
+
return this.ConnectServer();
|
|
251
|
+
}
|
|
252
|
+
async ConnectCloseAsync() {
|
|
253
|
+
return this.ConnectClose();
|
|
254
|
+
}
|
|
255
|
+
async RemoteRun() {
|
|
256
|
+
return new Core_1.OperateResult('RemoteRun is not implemented for this transport');
|
|
257
|
+
}
|
|
258
|
+
async RemoteStop() {
|
|
259
|
+
return new Core_1.OperateResult('RemoteStop is not implemented for this transport');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
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,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModbusAscii = void 0;
|
|
4
|
+
const ModbusRtu_1 = require("./ModbusRtu");
|
|
5
|
+
/** Modbus ASCII serial client. */
|
|
6
|
+
class ModbusAscii extends ModbusRtu_1.ModbusRtu {
|
|
7
|
+
}
|
|
8
|
+
exports.ModbusAscii = ModbusAscii;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
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 {
|
|
7
|
+
}
|
|
8
|
+
exports.ModbusAsciiOverTcp = ModbusAsciiOverTcp;
|
|
@@ -0,0 +1,15 @@
|
|
|
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;
|
|
11
|
+
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>>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModbusRtu = void 0;
|
|
4
|
+
const ModbusTcpNet_1 = require("./ModbusTcpNet");
|
|
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(); }
|
|
26
|
+
}
|
|
27
|
+
exports.ModbusRtu = ModbusRtu;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ModbusRtuOverTcp = void 0;
|
|
4
|
+
const ModbusTcpNet_1 = require("./ModbusTcpNet");
|
|
5
|
+
/** Modbus RTU frame carried over TCP. */
|
|
6
|
+
class ModbusRtuOverTcp extends ModbusTcpNet_1.ModbusTcpNet {
|
|
7
|
+
}
|
|
8
|
+
exports.ModbusRtuOverTcp = ModbusRtuOverTcp;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { DataFormat, DeviceClient, OperateResult } from '../core/Core';
|
|
2
|
+
export interface ModbusAddress {
|
|
3
|
+
station: number;
|
|
4
|
+
code: number;
|
|
5
|
+
address: number;
|
|
6
|
+
bit?: number;
|
|
7
|
+
writeCode?: number;
|
|
8
|
+
format?: DataFormat;
|
|
9
|
+
}
|
|
10
|
+
export declare function parseModbusAddress(input: string, defaultStation?: number, defaultCode?: number): OperateResult<ModbusAddress>;
|
|
11
|
+
export declare class ModbusTcpNet extends DeviceClient {
|
|
12
|
+
Station: number;
|
|
13
|
+
AddressStartWithZero: boolean;
|
|
14
|
+
IsStringReverse: boolean;
|
|
15
|
+
StationCheckMatch: boolean;
|
|
16
|
+
BroadcastStation: number;
|
|
17
|
+
WordReadBatchLength: number;
|
|
18
|
+
DisableFunctionCode06: boolean;
|
|
19
|
+
EnableWriteMaskCode: boolean;
|
|
20
|
+
DataFormat: DataFormat;
|
|
21
|
+
MessageId: number;
|
|
22
|
+
constructor(ipAddress?: string, port?: number, station?: number);
|
|
23
|
+
private nextId;
|
|
24
|
+
private frame;
|
|
25
|
+
private transact;
|
|
26
|
+
private addr;
|
|
27
|
+
Read(address: string, length: number): Promise<OperateResult<Buffer>>;
|
|
28
|
+
ReadBool(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
|
|
29
|
+
ReadCoil(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
|
|
30
|
+
ReadDiscrete(address: string, length?: number): Promise<OperateResult<boolean | boolean[]>>;
|
|
31
|
+
private readTyped;
|
|
32
|
+
ReadInt16(address: string, length?: number): Promise<OperateResult<any>>;
|
|
33
|
+
ReadUInt16(address: string, length?: number): Promise<OperateResult<any>>;
|
|
34
|
+
ReadInt32(address: string, length?: number): Promise<OperateResult<any>>;
|
|
35
|
+
ReadUInt32(address: string, length?: number): Promise<OperateResult<any>>;
|
|
36
|
+
ReadFloat(address: string, length?: number): Promise<OperateResult<any>>;
|
|
37
|
+
ReadDouble(address: string, length?: number): Promise<OperateResult<any>>;
|
|
38
|
+
ReadInt64(address: string, length?: number): Promise<OperateResult<any>>;
|
|
39
|
+
ReadUInt64(address: string, length?: number): Promise<OperateResult<any>>;
|
|
40
|
+
ReadByte(address: string): Promise<OperateResult<number>>;
|
|
41
|
+
ReadString(address: string, length: number, encoding?: BufferEncoding): Promise<OperateResult<string>>;
|
|
42
|
+
Write(address: string, value: number | boolean | string | Buffer | number[] | boolean[]): Promise<OperateResult<any>>;
|
|
43
|
+
WriteMask(address: string, andMask: number, orMask: number): Promise<OperateResult<any>>;
|
|
44
|
+
WriteByte(a: string, v: number): Promise<OperateResult<any>>;
|
|
45
|
+
WriteInt16(a: string, v: number): Promise<OperateResult<any>>;
|
|
46
|
+
WriteUInt16(a: string, v: number): Promise<OperateResult<any>>;
|
|
47
|
+
WriteInt32(a: string, v: number): Promise<OperateResult<any>>;
|
|
48
|
+
WriteUInt32(a: string, v: number): Promise<OperateResult<any>>;
|
|
49
|
+
WriteFloat(a: string, v: number): Promise<OperateResult<any>>;
|
|
50
|
+
WriteDouble(a: string, v: number): Promise<OperateResult<any>>;
|
|
51
|
+
WriteInt64(a: string, v: bigint | number): Promise<OperateResult<any>>;
|
|
52
|
+
WriteUInt64(a: string, v: bigint | number): Promise<OperateResult<any>>;
|
|
53
|
+
ConnectServerAsync(): Promise<OperateResult<any>>;
|
|
54
|
+
ConnectCloseAsync(): Promise<OperateResult<any>>;
|
|
55
|
+
}
|