@ya-modbus/emulator 0.8.0 → 0.9.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/CHANGELOG.md +6 -0
- package/README.md +54 -1
- package/dist/cjs/src/emulator.d.ts.map +1 -1
- package/dist/cjs/src/emulator.js +14 -1
- package/dist/cjs/src/emulator.js.map +1 -1
- package/dist/cjs/src/transports/tcp.d.ts +38 -0
- package/dist/cjs/src/transports/tcp.d.ts.map +1 -0
- package/dist/cjs/src/transports/tcp.js +209 -0
- package/dist/cjs/src/transports/tcp.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/emulator.d.ts.map +1 -1
- package/dist/esm/src/emulator.js +14 -1
- package/dist/esm/src/emulator.js.map +1 -1
- package/dist/esm/src/transports/tcp.d.ts +38 -0
- package/dist/esm/src/transports/tcp.d.ts.map +1 -0
- package/dist/esm/src/transports/tcp.js +205 -0
- package/dist/esm/src/transports/tcp.js.map +1 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,12 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.9.0](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/emulator@0.8.0...@ya-modbus/emulator@0.9.0) (2026-02-07)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **emulator:** implement TCP transport ([#252](https://github.com/groupsky/ya-modbus/issues/252)) ([3df8fda](https://github.com/groupsky/ya-modbus/commit/3df8fdac2c279ca13fb314867daa2ffc32194481)), closes [#244](https://github.com/groupsky/ya-modbus/issues/244)
|
|
11
|
+
|
|
6
12
|
# [0.8.0](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/emulator@0.7.1...@ya-modbus/emulator@0.8.0) (2026-02-07)
|
|
7
13
|
|
|
8
14
|
### Features
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Software Modbus device emulator for testing device drivers without physical hard
|
|
|
7
7
|
- **Realistic device simulation**: Mimic actual device constraints and timing characteristics
|
|
8
8
|
- **Test acceleration**: Enable fast, deterministic testing without hardware
|
|
9
9
|
- **Edge case coverage**: Simulate error conditions and edge cases
|
|
10
|
-
- **Multiple transports**: RTU (virtual/real serial ports) and in-memory
|
|
10
|
+
- **Multiple transports**: TCP, RTU (virtual/real serial ports), and in-memory
|
|
11
11
|
- **Custom function codes**: Support vendor-specific Modbus extensions
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
@@ -49,6 +49,43 @@ await emulator.start()
|
|
|
49
49
|
await emulator.stop()
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
### TCP Transport (network)
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { ModbusEmulator } from '@ya-modbus/emulator'
|
|
56
|
+
|
|
57
|
+
// Create emulator with TCP transport
|
|
58
|
+
const emulator = new ModbusEmulator({
|
|
59
|
+
transport: 'tcp',
|
|
60
|
+
host: '0.0.0.0', // Listen on all interfaces
|
|
61
|
+
port: 502, // Standard Modbus TCP port
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// Add devices
|
|
65
|
+
emulator.addDevice({
|
|
66
|
+
slaveId: 1,
|
|
67
|
+
registers: {
|
|
68
|
+
holding: { 0: 230, 1: 52 },
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
emulator.addDevice({
|
|
73
|
+
slaveId: 2,
|
|
74
|
+
registers: {
|
|
75
|
+
holding: { 0: 500, 1: 100 },
|
|
76
|
+
},
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// Start emulator
|
|
80
|
+
await emulator.start()
|
|
81
|
+
|
|
82
|
+
// Use with your driver tests (clients connect to localhost:502)
|
|
83
|
+
// ...
|
|
84
|
+
|
|
85
|
+
// Stop emulator
|
|
86
|
+
await emulator.stop()
|
|
87
|
+
```
|
|
88
|
+
|
|
52
89
|
### RTU Transport (serial port)
|
|
53
90
|
|
|
54
91
|
```typescript
|
|
@@ -125,6 +162,22 @@ Options:
|
|
|
125
162
|
|
|
126
163
|
Create a YAML or JSON configuration file to define devices and behaviors:
|
|
127
164
|
|
|
165
|
+
**Basic TCP Example** (`basic-tcp.yaml`):
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
transport:
|
|
169
|
+
type: tcp
|
|
170
|
+
host: 0.0.0.0
|
|
171
|
+
port: 502
|
|
172
|
+
|
|
173
|
+
devices:
|
|
174
|
+
- slaveId: 1
|
|
175
|
+
registers:
|
|
176
|
+
holding:
|
|
177
|
+
0: 230 # Voltage * 10 = 23.0V
|
|
178
|
+
1: 52 # Current * 10 = 5.2A
|
|
179
|
+
```
|
|
180
|
+
|
|
128
181
|
**Basic RTU Example** (`basic-rtu.yaml`):
|
|
129
182
|
|
|
130
183
|
```yaml
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"emulator.d.ts","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAIzD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAErE,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,OAAO,CAAQ;gBAEX,MAAM,EAAE,cAAc;IA0C5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAQb,aAAa;IA2B3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B,YAAY,IAAI,aAAa;IAI7B,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc;IAU/C,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAOnC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;CAGvD"}
|
package/dist/cjs/src/emulator.js
CHANGED
|
@@ -40,6 +40,7 @@ exports.ModbusEmulator = void 0;
|
|
|
40
40
|
const device_js_1 = require("./device.js");
|
|
41
41
|
const memory_js_1 = require("./transports/memory.js");
|
|
42
42
|
const rtu_js_1 = require("./transports/rtu.js");
|
|
43
|
+
const tcp_js_1 = require("./transports/tcp.js");
|
|
43
44
|
class ModbusEmulator {
|
|
44
45
|
constructor(config) {
|
|
45
46
|
this.devices = new Map();
|
|
@@ -62,8 +63,20 @@ class ModbusEmulator {
|
|
|
62
63
|
};
|
|
63
64
|
this.transport = new rtu_js_1.RtuTransport(rtuConfig);
|
|
64
65
|
}
|
|
66
|
+
else if (config.transport === 'tcp') {
|
|
67
|
+
if (!config.host) {
|
|
68
|
+
throw new Error('TCP transport requires host');
|
|
69
|
+
}
|
|
70
|
+
if (!config.port || typeof config.port !== 'number') {
|
|
71
|
+
throw new Error('TCP transport requires port');
|
|
72
|
+
}
|
|
73
|
+
this.transport = new tcp_js_1.TcpTransport({
|
|
74
|
+
host: config.host,
|
|
75
|
+
port: config.port,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
65
78
|
else {
|
|
66
|
-
throw new Error(`Unsupported transport: ${config.transport}`);
|
|
79
|
+
throw new Error(`Unsupported transport: ${String(config.transport)}`);
|
|
67
80
|
}
|
|
68
81
|
// Set up request handler
|
|
69
82
|
this.transport.onRequest(this.handleRequest.bind(this));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA4C;AAE5C,sDAAwD;AACxD,gDAAkD;AAGlD,MAAa,cAAc;IAKzB,YAAY,MAAsB;QAJ1B,YAAO,GAAgC,IAAI,GAAG,EAAE,CAAA;QAEhD,YAAO,GAAG,KAAK,CAAA;QAGrB,mCAAmC;QACnC,IAAI,MAAM,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,GAAG,IAAI,2BAAe,EAAE,CAAA;QACxC,CAAC;aAAM,IAAI,MAAM,CAAC,SAAS,KAAK,KAAK,EAAE,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAA;YACnE,CAAC;YACD,6EAA6E;YAC7E,MAAM,SAAS,GAMX;gBACF,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACnE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC7D,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACnE,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC;aACpE,CAAA;YACD,IAAI,CAAC,SAAS,GAAG,IAAI,qBAAY,CAAC,SAAS,CAAC,CAAA;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,CAAC,SAAS,EAAE,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TCP transport for Modbus emulator
|
|
3
|
+
*
|
|
4
|
+
* This implementation uses modbus-serial ServerTCP for protocol handling.
|
|
5
|
+
*/
|
|
6
|
+
import { BaseTransport } from './base.js';
|
|
7
|
+
export interface TcpTransportConfig {
|
|
8
|
+
host: string;
|
|
9
|
+
port: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class TcpTransport extends BaseTransport {
|
|
12
|
+
private config;
|
|
13
|
+
private requestHandler?;
|
|
14
|
+
private server?;
|
|
15
|
+
private started;
|
|
16
|
+
constructor(config: TcpTransportConfig);
|
|
17
|
+
start(): Promise<void>;
|
|
18
|
+
stop(): Promise<void>;
|
|
19
|
+
send(_slaveId: number, _response: Buffer): Promise<void>;
|
|
20
|
+
onRequest(handler: (slaveId: number, request: Buffer) => Promise<Buffer>): void;
|
|
21
|
+
/**
|
|
22
|
+
* Handle register read operations
|
|
23
|
+
*/
|
|
24
|
+
private handleRegisterRead;
|
|
25
|
+
/**
|
|
26
|
+
* Handle register write operations
|
|
27
|
+
*/
|
|
28
|
+
private handleRegisterWrite;
|
|
29
|
+
/**
|
|
30
|
+
* Handle coil read operations
|
|
31
|
+
*/
|
|
32
|
+
private handleCoilRead;
|
|
33
|
+
/**
|
|
34
|
+
* Handle coil write operations
|
|
35
|
+
*/
|
|
36
|
+
private handleCoilWrite;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=tcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.d.ts","sourceRoot":"","sources":["../../../../src/transports/tcp.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AAEzC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,cAAc,CAAC,CAAuD;IAC9E,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,OAAO,CAAQ;gBAEX,MAAM,EAAE,kBAAkB;IAKhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB3B,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI;IAI/E;;OAEG;YACW,kBAAkB;IAmChC;;OAEG;YACW,mBAAmB;IAqCjC;;OAEG;YACW,cAAc;IAiC5B;;OAEG;YACW,eAAe;CAoB9B"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TCP transport for Modbus emulator
|
|
4
|
+
*
|
|
5
|
+
* This implementation uses modbus-serial ServerTCP for protocol handling.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.TcpTransport = void 0;
|
|
9
|
+
const modbus_serial_1 = require("modbus-serial");
|
|
10
|
+
const base_js_1 = require("./base.js");
|
|
11
|
+
class TcpTransport extends base_js_1.BaseTransport {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
super();
|
|
14
|
+
this.started = false;
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async start() {
|
|
18
|
+
if (this.started) {
|
|
19
|
+
throw new Error('Transport already started');
|
|
20
|
+
}
|
|
21
|
+
// Create service vector that bridges modbus-serial callbacks to our request handler
|
|
22
|
+
const serviceVector = {
|
|
23
|
+
getHoldingRegister: async (addr, unitID) => {
|
|
24
|
+
return this.handleRegisterRead(unitID, 0x03, addr, 1);
|
|
25
|
+
},
|
|
26
|
+
getInputRegister: async (addr, unitID) => {
|
|
27
|
+
return this.handleRegisterRead(unitID, 0x04, addr, 1);
|
|
28
|
+
},
|
|
29
|
+
getMultipleHoldingRegisters: async (addr, length, unitID) => {
|
|
30
|
+
return this.handleRegisterRead(unitID, 0x03, addr, length);
|
|
31
|
+
},
|
|
32
|
+
getMultipleInputRegisters: async (addr, length, unitID) => {
|
|
33
|
+
return this.handleRegisterRead(unitID, 0x04, addr, length);
|
|
34
|
+
},
|
|
35
|
+
setRegister: async (addr, value, unitID) => {
|
|
36
|
+
return this.handleRegisterWrite(unitID, 0x06, addr, [value]);
|
|
37
|
+
},
|
|
38
|
+
setRegisterArray: async (addr, values, unitID) => {
|
|
39
|
+
return this.handleRegisterWrite(unitID, 0x10, addr, values);
|
|
40
|
+
},
|
|
41
|
+
getCoil: async (addr, unitID) => {
|
|
42
|
+
return this.handleCoilRead(unitID, 0x01, addr, 1);
|
|
43
|
+
},
|
|
44
|
+
getDiscreteInput: async (addr, unitID) => {
|
|
45
|
+
return this.handleCoilRead(unitID, 0x02, addr, 1);
|
|
46
|
+
},
|
|
47
|
+
setCoil: async (addr, value, unitID) => {
|
|
48
|
+
return this.handleCoilWrite(unitID, 0x05, addr, value);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// Build options - all values are required for TCP
|
|
52
|
+
const options = {
|
|
53
|
+
host: this.config.host,
|
|
54
|
+
port: this.config.port,
|
|
55
|
+
unitID: 255, // Listen to all unit IDs
|
|
56
|
+
};
|
|
57
|
+
// Create server
|
|
58
|
+
const server = new modbus_serial_1.ServerTCP(serviceVector, options);
|
|
59
|
+
this.server = server;
|
|
60
|
+
// Wait for initialized event
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
server.on('initialized', () => {
|
|
63
|
+
this.started = true;
|
|
64
|
+
resolve();
|
|
65
|
+
});
|
|
66
|
+
// Handle errors
|
|
67
|
+
server.on('error', (err) => {
|
|
68
|
+
// Log error but don't stop server
|
|
69
|
+
console.error('TCP transport error:', err);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async stop() {
|
|
74
|
+
if (!this.started || !this.server) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
return new Promise((resolve, reject) => {
|
|
78
|
+
if (!this.server) {
|
|
79
|
+
resolve();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.server.close((err) => {
|
|
83
|
+
if (err) {
|
|
84
|
+
reject(err);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.started = false;
|
|
88
|
+
delete this.server;
|
|
89
|
+
resolve();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
send(_slaveId, _response) {
|
|
95
|
+
if (!this.started) {
|
|
96
|
+
return Promise.reject(new Error('Transport not started'));
|
|
97
|
+
}
|
|
98
|
+
// Responses are sent automatically by modbus-serial server
|
|
99
|
+
// This method is kept for interface compatibility
|
|
100
|
+
return Promise.resolve();
|
|
101
|
+
}
|
|
102
|
+
onRequest(handler) {
|
|
103
|
+
this.requestHandler = handler;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Handle register read operations
|
|
107
|
+
*/
|
|
108
|
+
async handleRegisterRead(unitID, functionCode, addr, length) {
|
|
109
|
+
if (!this.requestHandler) {
|
|
110
|
+
throw new Error('No request handler set');
|
|
111
|
+
}
|
|
112
|
+
// Build Modbus request buffer
|
|
113
|
+
const request = Buffer.alloc(6);
|
|
114
|
+
request[0] = unitID;
|
|
115
|
+
request[1] = functionCode;
|
|
116
|
+
request.writeUInt16BE(addr, 2);
|
|
117
|
+
request.writeUInt16BE(length, 4);
|
|
118
|
+
// Call handler
|
|
119
|
+
const response = await this.requestHandler(unitID, request);
|
|
120
|
+
// Parse response
|
|
121
|
+
const byteCount = response[2];
|
|
122
|
+
if (byteCount === undefined || response.length < 3 + byteCount) {
|
|
123
|
+
throw new Error('Invalid response');
|
|
124
|
+
}
|
|
125
|
+
// Extract register values
|
|
126
|
+
const values = [];
|
|
127
|
+
for (let i = 0; i < byteCount / 2; i++) {
|
|
128
|
+
values.push(response.readUInt16BE(3 + i * 2));
|
|
129
|
+
}
|
|
130
|
+
return values;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Handle register write operations
|
|
134
|
+
*/
|
|
135
|
+
async handleRegisterWrite(unitID, functionCode, addr, values) {
|
|
136
|
+
if (!this.requestHandler) {
|
|
137
|
+
throw new Error('No request handler set');
|
|
138
|
+
}
|
|
139
|
+
// Build Modbus request buffer
|
|
140
|
+
let request;
|
|
141
|
+
if (functionCode === 0x06) {
|
|
142
|
+
// Write single register
|
|
143
|
+
request = Buffer.alloc(6);
|
|
144
|
+
request[0] = unitID;
|
|
145
|
+
request[1] = functionCode;
|
|
146
|
+
request.writeUInt16BE(addr, 2);
|
|
147
|
+
request.writeUInt16BE(values[0] ?? 0, 4);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
// Write multiple registers
|
|
151
|
+
const byteCount = values.length * 2;
|
|
152
|
+
request = Buffer.alloc(7 + byteCount);
|
|
153
|
+
request[0] = unitID;
|
|
154
|
+
request[1] = functionCode;
|
|
155
|
+
request.writeUInt16BE(addr, 2);
|
|
156
|
+
request.writeUInt16BE(values.length, 4);
|
|
157
|
+
request[6] = byteCount;
|
|
158
|
+
for (let i = 0; i < values.length; i++) {
|
|
159
|
+
request.writeUInt16BE(values[i] ?? 0, 7 + i * 2);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Call handler and ignore response
|
|
163
|
+
await this.requestHandler(unitID, request);
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Handle coil read operations
|
|
167
|
+
*/
|
|
168
|
+
async handleCoilRead(unitID, functionCode, addr, length) {
|
|
169
|
+
if (!this.requestHandler) {
|
|
170
|
+
throw new Error('No request handler set');
|
|
171
|
+
}
|
|
172
|
+
// Build Modbus request buffer
|
|
173
|
+
const request = Buffer.alloc(6);
|
|
174
|
+
request[0] = unitID;
|
|
175
|
+
request[1] = functionCode;
|
|
176
|
+
request.writeUInt16BE(addr, 2);
|
|
177
|
+
request.writeUInt16BE(length, 4);
|
|
178
|
+
// Call handler
|
|
179
|
+
const response = await this.requestHandler(unitID, request);
|
|
180
|
+
// Parse response - get first bit from first byte of coil data
|
|
181
|
+
const byteCount = response[2];
|
|
182
|
+
if (byteCount === undefined || response.length < 4) {
|
|
183
|
+
throw new Error('Invalid response');
|
|
184
|
+
}
|
|
185
|
+
const coilByte = response[3];
|
|
186
|
+
if (coilByte === undefined) {
|
|
187
|
+
throw new Error('Invalid response');
|
|
188
|
+
}
|
|
189
|
+
return (coilByte & 0x01) === 1;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Handle coil write operations
|
|
193
|
+
*/
|
|
194
|
+
async handleCoilWrite(unitID, functionCode, addr, value) {
|
|
195
|
+
if (!this.requestHandler) {
|
|
196
|
+
throw new Error('No request handler set');
|
|
197
|
+
}
|
|
198
|
+
// Build Modbus request buffer
|
|
199
|
+
const request = Buffer.alloc(6);
|
|
200
|
+
request[0] = unitID;
|
|
201
|
+
request[1] = functionCode;
|
|
202
|
+
request.writeUInt16BE(addr, 2);
|
|
203
|
+
request.writeUInt16BE(value ? 0xff00 : 0x0000, 4);
|
|
204
|
+
// Call handler and ignore response
|
|
205
|
+
await this.requestHandler(unitID, request);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
exports.TcpTransport = TcpTransport;
|
|
209
|
+
//# sourceMappingURL=tcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tcp.js","sourceRoot":"","sources":["../../../../src/transports/tcp.ts"],"names":[],"mappings":"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"}
|