@ya-modbus/emulator 0.10.8 → 0.11.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 +46 -1
- package/dist/cjs/src/behaviors/function-codes.d.ts +2 -1
- package/dist/cjs/src/behaviors/function-codes.d.ts.map +1 -1
- package/dist/cjs/src/behaviors/function-codes.js +30 -12
- package/dist/cjs/src/behaviors/function-codes.js.map +1 -1
- package/dist/cjs/src/cli.d.ts.map +1 -1
- package/dist/cjs/src/cli.js +3 -2
- package/dist/cjs/src/cli.js.map +1 -1
- package/dist/cjs/src/emulator.d.ts +3 -0
- package/dist/cjs/src/emulator.d.ts.map +1 -1
- package/dist/cjs/src/emulator.js +9 -1
- package/dist/cjs/src/emulator.js.map +1 -1
- package/dist/cjs/src/types/config.d.ts +2 -0
- package/dist/cjs/src/types/config.d.ts.map +1 -1
- package/dist/cjs/src/verbose-logger.d.ts +14 -0
- package/dist/cjs/src/verbose-logger.d.ts.map +1 -0
- package/dist/cjs/src/verbose-logger.js +63 -0
- package/dist/cjs/src/verbose-logger.js.map +1 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/behaviors/function-codes.d.ts +2 -1
- package/dist/esm/src/behaviors/function-codes.d.ts.map +1 -1
- package/dist/esm/src/behaviors/function-codes.js +30 -12
- package/dist/esm/src/behaviors/function-codes.js.map +1 -1
- package/dist/esm/src/cli.d.ts.map +1 -1
- package/dist/esm/src/cli.js +3 -2
- package/dist/esm/src/cli.js.map +1 -1
- package/dist/esm/src/emulator.d.ts +3 -0
- package/dist/esm/src/emulator.d.ts.map +1 -1
- package/dist/esm/src/emulator.js +9 -1
- package/dist/esm/src/emulator.js.map +1 -1
- package/dist/esm/src/types/config.d.ts +2 -0
- package/dist/esm/src/types/config.d.ts.map +1 -1
- package/dist/esm/src/verbose-logger.d.ts +14 -0
- package/dist/esm/src/verbose-logger.d.ts.map +1 -0
- package/dist/esm/src/verbose-logger.js +59 -0
- package/dist/esm/src/verbose-logger.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.11.0](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/emulator@0.10.8...@ya-modbus/emulator@0.11.0) (2026-02-07)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **emulator:** add verbose logging for Modbus operations ([#316](https://github.com/groupsky/ya-modbus/issues/316)) ([2bd14aa](https://github.com/groupsky/ya-modbus/commit/2bd14aadf4c6cd8da5275824a371adb5835cc502)), closes [#309](https://github.com/groupsky/ya-modbus/issues/309) [#311](https://github.com/groupsky/ya-modbus/issues/311) [#312](https://github.com/groupsky/ya-modbus/issues/312) [#313](https://github.com/groupsky/ya-modbus/issues/313) [#310](https://github.com/groupsky/ya-modbus/issues/310) [#314](https://github.com/groupsky/ya-modbus/issues/314)
|
|
11
|
+
|
|
6
12
|
## [0.10.8](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/emulator@0.10.7...@ya-modbus/emulator@0.10.8) (2026-02-07)
|
|
7
13
|
|
|
8
14
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -155,11 +155,56 @@ Options:
|
|
|
155
155
|
-s, --slave-id <id> Slave ID (required if no config file)
|
|
156
156
|
-v, --verbose Enable verbose logging
|
|
157
157
|
-q, --quiet Suppress all output except errors
|
|
158
|
-
--log-requests Log all Modbus requests/responses
|
|
159
158
|
-V, --version output the version number
|
|
160
159
|
-h, --help display help for command
|
|
161
160
|
```
|
|
162
161
|
|
|
162
|
+
### Verbose Logging
|
|
163
|
+
|
|
164
|
+
Enable verbose logging to see detailed Modbus operations for debugging and testing:
|
|
165
|
+
|
|
166
|
+
**CLI:**
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# With config file
|
|
170
|
+
ya-modbus-emulator --config config.yaml --verbose
|
|
171
|
+
|
|
172
|
+
# Or directly
|
|
173
|
+
ya-modbus-emulator --transport rtu --port /dev/ttyUSB0 --slave-id 1 --verbose
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Programmatic:**
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
const emulator = new ModbusEmulator({
|
|
180
|
+
transport: 'memory',
|
|
181
|
+
verbose: true,
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**Output Format:**
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
[VERBOSE] READ slave=1 func=0x03 addr=0x0000 count=2 values=[0x1234, 0x5678]
|
|
189
|
+
[VERBOSE] WRITE slave=1 func=0x06 addr=0x0005 count=1 values=[0x9ABC]
|
|
190
|
+
[VERBOSE] WRITE slave=2 func=0x10 addr=0x0010 count=3 values=[0xAABB, 0xCCDD, 0xEEFF]
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Each log entry includes:
|
|
194
|
+
|
|
195
|
+
- **Operation type**: READ or WRITE
|
|
196
|
+
- **Slave ID**: Which device handled the request
|
|
197
|
+
- **Function code**: Modbus function (0x03=Read Holding, 0x04=Read Input, 0x06=Write Single, 0x10=Write Multiple)
|
|
198
|
+
- **Starting address**: Register address in hexadecimal
|
|
199
|
+
- **Register count**: Number of registers accessed
|
|
200
|
+
- **Values**: Register values in hexadecimal
|
|
201
|
+
|
|
202
|
+
Verbose logging is useful for:
|
|
203
|
+
|
|
204
|
+
- **E2E testing**: Verify exact data flow in integration tests
|
|
205
|
+
- **Driver development**: Debug communication with emulated devices
|
|
206
|
+
- **Protocol validation**: Ensure correct Modbus message formatting
|
|
207
|
+
|
|
163
208
|
### Configuration Files
|
|
164
209
|
|
|
165
210
|
Create a YAML or JSON configuration file to define devices and behaviors:
|
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
* Modbus function code handlers
|
|
3
3
|
*/
|
|
4
4
|
import type { EmulatedDevice } from '../device.js';
|
|
5
|
+
import type { VerboseLogger } from '../verbose-logger.js';
|
|
5
6
|
export declare const ILLEGAL_FUNCTION = 1;
|
|
6
7
|
export declare const ILLEGAL_DATA_ADDRESS = 2;
|
|
7
8
|
export declare const ILLEGAL_DATA_VALUE = 3;
|
|
8
9
|
/**
|
|
9
10
|
* Handle a Modbus request and return the response
|
|
10
11
|
*/
|
|
11
|
-
export declare function handleModbusRequest(device: EmulatedDevice, request: Buffer): Buffer;
|
|
12
|
+
export declare function handleModbusRequest(device: EmulatedDevice, request: Buffer, verboseLogger?: VerboseLogger): Buffer;
|
|
12
13
|
//# sourceMappingURL=function-codes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function-codes.d.ts","sourceRoot":"","sources":["../../../../src/behaviors/function-codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"function-codes.d.ts","sourceRoot":"","sources":["../../../../src/behaviors/function-codes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,eAAO,MAAM,gBAAgB,IAAO,CAAA;AACpC,eAAO,MAAM,oBAAoB,IAAO,CAAA;AACxC,eAAO,MAAM,kBAAkB,IAAO,CAAA;AAEtC;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,EACf,aAAa,CAAC,EAAE,aAAa,GAC5B,MAAM,CA4BR"}
|
|
@@ -12,7 +12,7 @@ exports.ILLEGAL_DATA_VALUE = 0x03;
|
|
|
12
12
|
/**
|
|
13
13
|
* Handle a Modbus request and return the response
|
|
14
14
|
*/
|
|
15
|
-
function handleModbusRequest(device, request) {
|
|
15
|
+
function handleModbusRequest(device, request, verboseLogger) {
|
|
16
16
|
if (request.length < 2) {
|
|
17
17
|
return createExceptionResponse(request[0] ?? 0, 0x00, exports.ILLEGAL_DATA_VALUE);
|
|
18
18
|
}
|
|
@@ -24,13 +24,13 @@ function handleModbusRequest(device, request) {
|
|
|
24
24
|
try {
|
|
25
25
|
switch (functionCode) {
|
|
26
26
|
case 0x03:
|
|
27
|
-
return handleReadHoldingRegisters(device, request);
|
|
27
|
+
return handleReadHoldingRegisters(device, request, verboseLogger);
|
|
28
28
|
case 0x04:
|
|
29
|
-
return handleReadInputRegisters(device, request);
|
|
29
|
+
return handleReadInputRegisters(device, request, verboseLogger);
|
|
30
30
|
case 0x06:
|
|
31
|
-
return handleWriteSingleRegister(device, request);
|
|
31
|
+
return handleWriteSingleRegister(device, request, verboseLogger);
|
|
32
32
|
case 0x10:
|
|
33
|
-
return handleWriteMultipleRegisters(device, request);
|
|
33
|
+
return handleWriteMultipleRegisters(device, request, verboseLogger);
|
|
34
34
|
default:
|
|
35
35
|
return createExceptionResponse(slaveId, functionCode, exports.ILLEGAL_FUNCTION);
|
|
36
36
|
}
|
|
@@ -43,7 +43,7 @@ function handleModbusRequest(device, request) {
|
|
|
43
43
|
/**
|
|
44
44
|
* 0x03 - Read Holding Registers
|
|
45
45
|
*/
|
|
46
|
-
function handleReadHoldingRegisters(device, request) {
|
|
46
|
+
function handleReadHoldingRegisters(device, request, verboseLogger) {
|
|
47
47
|
if (request.length < 6) {
|
|
48
48
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
49
49
|
return createExceptionResponse(request[0], 0x03, exports.ILLEGAL_DATA_VALUE);
|
|
@@ -61,12 +61,13 @@ function handleReadHoldingRegisters(device, request) {
|
|
|
61
61
|
const value = device.getHoldingRegister(startAddress + i);
|
|
62
62
|
response.writeUInt16BE(value, 3 + i * 2);
|
|
63
63
|
}
|
|
64
|
+
verboseLogger?.logRead(slaveId, 0x03, startAddress, quantity, response);
|
|
64
65
|
return response;
|
|
65
66
|
}
|
|
66
67
|
/**
|
|
67
68
|
* 0x04 - Read Input Registers
|
|
68
69
|
*/
|
|
69
|
-
function handleReadInputRegisters(device, request) {
|
|
70
|
+
function handleReadInputRegisters(device, request, verboseLogger) {
|
|
70
71
|
if (request.length < 6) {
|
|
71
72
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
72
73
|
return createExceptionResponse(request[0], 0x04, exports.ILLEGAL_DATA_VALUE);
|
|
@@ -84,26 +85,32 @@ function handleReadInputRegisters(device, request) {
|
|
|
84
85
|
const value = device.getInputRegister(startAddress + i);
|
|
85
86
|
response.writeUInt16BE(value, 3 + i * 2);
|
|
86
87
|
}
|
|
88
|
+
verboseLogger?.logRead(slaveId, 0x04, startAddress, quantity, response);
|
|
87
89
|
return response;
|
|
88
90
|
}
|
|
89
91
|
/**
|
|
90
92
|
* 0x06 - Write Single Register
|
|
91
93
|
*/
|
|
92
|
-
function handleWriteSingleRegister(device, request) {
|
|
94
|
+
function handleWriteSingleRegister(device, request, verboseLogger) {
|
|
93
95
|
if (request.length < 6) {
|
|
94
96
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
95
97
|
return createExceptionResponse(request[0], 0x06, exports.ILLEGAL_DATA_VALUE);
|
|
96
98
|
}
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
100
|
+
const slaveId = request[0];
|
|
97
101
|
const address = request.readUInt16BE(2);
|
|
98
102
|
const value = request.readUInt16BE(4);
|
|
99
103
|
device.setHoldingRegister(address, value);
|
|
104
|
+
if (verboseLogger) {
|
|
105
|
+
verboseLogger.logWrite(slaveId, 0x06, address, 1, [value]);
|
|
106
|
+
}
|
|
100
107
|
// Echo the request as response
|
|
101
108
|
return request;
|
|
102
109
|
}
|
|
103
110
|
/**
|
|
104
111
|
* 0x10 - Write Multiple Registers
|
|
105
112
|
*/
|
|
106
|
-
function handleWriteMultipleRegisters(device, request) {
|
|
113
|
+
function handleWriteMultipleRegisters(device, request, verboseLogger) {
|
|
107
114
|
if (request.length < 7) {
|
|
108
115
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
109
116
|
return createExceptionResponse(request[0], 0x10, exports.ILLEGAL_DATA_VALUE);
|
|
@@ -118,9 +125,20 @@ function handleWriteMultipleRegisters(device, request) {
|
|
|
118
125
|
return createExceptionResponse(slaveId, 0x10, exports.ILLEGAL_DATA_VALUE);
|
|
119
126
|
}
|
|
120
127
|
// Write registers
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
128
|
+
if (verboseLogger) {
|
|
129
|
+
const values = [];
|
|
130
|
+
for (let i = 0; i < quantity; i++) {
|
|
131
|
+
const value = request.readUInt16BE(7 + i * 2);
|
|
132
|
+
device.setHoldingRegister(startAddress + i, value);
|
|
133
|
+
values.push(value);
|
|
134
|
+
}
|
|
135
|
+
verboseLogger.logWrite(slaveId, 0x10, startAddress, quantity, values);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
for (let i = 0; i < quantity; i++) {
|
|
139
|
+
const value = request.readUInt16BE(7 + i * 2);
|
|
140
|
+
device.setHoldingRegister(startAddress + i, value);
|
|
141
|
+
}
|
|
124
142
|
}
|
|
125
143
|
// Response: slave_id + function_code + start_address + quantity
|
|
126
144
|
const response = Buffer.alloc(6);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function-codes.js","sourceRoot":"","sources":["../../../../src/behaviors/function-codes.ts"],"names":[],"mappings":";AAAA;;GAEG;;;
|
|
1
|
+
{"version":3,"file":"function-codes.js","sourceRoot":"","sources":["../../../../src/behaviors/function-codes.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAaH,kDAgCC;AAxCD,yBAAyB;AACZ,QAAA,gBAAgB,GAAG,IAAI,CAAA;AACvB,QAAA,oBAAoB,GAAG,IAAI,CAAA;AAC3B,QAAA,kBAAkB,GAAG,IAAI,CAAA;AAEtC;;GAEG;AACH,SAAgB,mBAAmB,CACjC,MAAsB,EACtB,OAAe,EACf,aAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IAC3E,CAAC;IAED,2CAA2C;IAC3C,oEAAoE;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAC3B,oEAAoE;IACpE,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAEhC,IAAI,CAAC;QACH,QAAQ,YAAY,EAAE,CAAC;YACrB,KAAK,IAAI;gBACP,OAAO,0BAA0B,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;YACnE,KAAK,IAAI;gBACP,OAAO,wBAAwB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;YACjE,KAAK,IAAI;gBACP,OAAO,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;YAClE,KAAK,IAAI;gBACP,OAAO,4BAA4B,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;YACrE;gBACE,OAAO,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,wBAAgB,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;QACvD,OAAO,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,0BAAkB,CAAC,CAAA;IAC3E,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CACjC,MAAsB,EACtB,OAAe,EACf,aAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,oEAAoE;QACpE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IACvE,CAAC;IAED,oEAAoE;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAExC,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IAE5C,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;IACrB,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAClB,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAkB,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;QACzD,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,aAAa,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAEvE,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,wBAAwB,CAC/B,MAAsB,EACtB,OAAe,EACf,aAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,oEAAoE;QACpE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IACvE,CAAC;IAED,oEAAoE;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAExC,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,SAAS,CAAC,CAAA;IAE5C,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;IACrB,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAClB,QAAQ,CAAC,CAAC,CAAC,GAAG,SAAS,CAAA;IAEvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,CAAC,gBAAgB,CAAC,YAAY,GAAG,CAAC,CAAC,CAAA;QACvD,QAAQ,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;IAC1C,CAAC;IAED,aAAa,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAEvE,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAChC,MAAsB,EACtB,OAAe,EACf,aAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,oEAAoE;QACpE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IACvE,CAAC;IAED,oEAAoE;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAErC,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAEzC,IAAI,aAAa,EAAE,CAAC;QAClB,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5D,CAAC;IAED,+BAA+B;IAC/B,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,4BAA4B,CACnC,MAAsB,EACtB,OAAe,EACf,aAA6B;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,oEAAoE;QACpE,OAAO,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAE,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IACvE,CAAC;IAED,oEAAoE;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACxC,oEAAoE;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAE,CAAA;IAE7B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,SAAS,EAAE,CAAC;QACnC,OAAO,uBAAuB,CAAC,OAAO,EAAE,IAAI,EAAE,0BAAkB,CAAC,CAAA;IACnE,CAAC;IAED,kBAAkB;IAClB,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7C,MAAM,CAAC,kBAAkB,CAAC,YAAY,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;YAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;QACD,aAAa,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IACvE,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;YAC7C,MAAM,CAAC,kBAAkB,CAAC,YAAY,GAAG,CAAC,EAAE,KAAK,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IAED,gEAAgE;IAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;IACrB,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAClB,QAAQ,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;IACvC,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;IAEnC,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC9B,OAAe,EACf,YAAoB,EACpB,aAAqB;IAErB,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAChC,QAAQ,CAAC,CAAC,CAAC,GAAG,OAAO,CAAA;IACrB,QAAQ,CAAC,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI,CAAA,CAAC,gBAAgB;IAClD,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;IAC3B,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":";AACA;;GAEG;AA8CH;;GAEG;AACH,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAuGnC;AAOD,OAAO,EAAE,IAAI,EAAE,CAAA"}
|
package/dist/cjs/src/cli.js
CHANGED
|
@@ -23,8 +23,7 @@ program
|
|
|
23
23
|
.option('--no-lock', 'Disable serial port locking (enabled by default)')
|
|
24
24
|
.option('-s, --slave-id <id>', 'Slave ID (required if no config file)', parseInt)
|
|
25
25
|
.option('-v, --verbose', 'Enable verbose logging')
|
|
26
|
-
.option('-q, --quiet', 'Suppress all output except errors')
|
|
27
|
-
.option('--log-requests', 'Log all Modbus requests/responses');
|
|
26
|
+
.option('-q, --quiet', 'Suppress all output except errors');
|
|
28
27
|
program.parse();
|
|
29
28
|
// Type assertion needed for TypeScript strict mode with noUncheckedIndexedAccess
|
|
30
29
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
@@ -56,6 +55,7 @@ async function main() {
|
|
|
56
55
|
stopBits: fileConfig.transport.stopBits,
|
|
57
56
|
}),
|
|
58
57
|
...(fileConfig.transport.lock !== undefined && { lock: fileConfig.transport.lock }),
|
|
58
|
+
...(options.verbose === true && { verbose: true }),
|
|
59
59
|
};
|
|
60
60
|
devices = fileConfig.devices;
|
|
61
61
|
}
|
|
@@ -78,6 +78,7 @@ async function main() {
|
|
|
78
78
|
parity: options.parity,
|
|
79
79
|
}),
|
|
80
80
|
...(typeof options.lock === 'boolean' && { lock: options.lock }),
|
|
81
|
+
...(options.verbose === true && { verbose: true }),
|
|
81
82
|
};
|
|
82
83
|
devices = [{ slaveId: options.slaveId }];
|
|
83
84
|
}
|
package/dist/cjs/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":";;AACA;;GAEG;;AA+JM,oBAAI;AA7Jb,yCAAmC;AAEnC,+CAA8C;AAE9C,+DAAqD;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
import { EmulatedDevice } from './device.js';
|
|
5
5
|
import type { BaseTransport } from './transports/base.js';
|
|
6
6
|
import type { EmulatorConfig, DeviceConfig } from './types/config.js';
|
|
7
|
+
import { VerboseLogger } from './verbose-logger.js';
|
|
7
8
|
export declare class ModbusEmulator {
|
|
8
9
|
private devices;
|
|
9
10
|
private transport;
|
|
10
11
|
private started;
|
|
12
|
+
private verboseLogger?;
|
|
11
13
|
constructor(config: EmulatorConfig);
|
|
12
14
|
start(): Promise<void>;
|
|
13
15
|
stop(): Promise<void>;
|
|
@@ -20,5 +22,6 @@ export declare class ModbusEmulator {
|
|
|
20
22
|
addDevice(config: DeviceConfig): EmulatedDevice;
|
|
21
23
|
removeDevice(slaveId: number): void;
|
|
22
24
|
getDevice(slaveId: number): EmulatedDevice | undefined;
|
|
25
|
+
getVerboseLogger(): VerboseLogger | undefined;
|
|
23
26
|
}
|
|
24
27
|
//# sourceMappingURL=emulator.d.ts.map
|
|
@@ -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;AAIzD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,mBAAmB,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;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAC,CAAe;gBAEzB,MAAM,EAAE,cAAc;IAiD5B,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;IAItD,gBAAgB,IAAI,aAAa,GAAG,SAAS;CAG9C"}
|
package/dist/cjs/src/emulator.js
CHANGED
|
@@ -41,10 +41,15 @@ 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
43
|
const tcp_js_1 = require("./transports/tcp.js");
|
|
44
|
+
const verbose_logger_js_1 = require("./verbose-logger.js");
|
|
44
45
|
class ModbusEmulator {
|
|
45
46
|
constructor(config) {
|
|
46
47
|
this.devices = new Map();
|
|
47
48
|
this.started = false;
|
|
49
|
+
// Create verbose logger if enabled
|
|
50
|
+
if (config.verbose === true) {
|
|
51
|
+
this.verboseLogger = new verbose_logger_js_1.VerboseLogger(true);
|
|
52
|
+
}
|
|
48
53
|
// Create transport based on config
|
|
49
54
|
if (config.transport === 'memory') {
|
|
50
55
|
this.transport = new memory_js_1.MemoryTransport();
|
|
@@ -117,7 +122,7 @@ class ModbusEmulator {
|
|
|
117
122
|
}
|
|
118
123
|
// Import dynamically to avoid circular dependency issues
|
|
119
124
|
const { handleModbusRequest } = await Promise.resolve().then(() => __importStar(require('./behaviors/function-codes.js')));
|
|
120
|
-
return handleModbusRequest(device, request);
|
|
125
|
+
return handleModbusRequest(device, request, this.verboseLogger);
|
|
121
126
|
}
|
|
122
127
|
/**
|
|
123
128
|
* Parse register count from Modbus request
|
|
@@ -161,6 +166,9 @@ class ModbusEmulator {
|
|
|
161
166
|
getDevice(slaveId) {
|
|
162
167
|
return this.devices.get(slaveId);
|
|
163
168
|
}
|
|
169
|
+
getVerboseLogger() {
|
|
170
|
+
return this.verboseLogger;
|
|
171
|
+
}
|
|
164
172
|
}
|
|
165
173
|
exports.ModbusEmulator = ModbusEmulator;
|
|
166
174
|
//# sourceMappingURL=emulator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,2CAA4C;AAE5C,sDAAwD;AACxD,gDAAkD;AAClD,gDAAkD;
|
|
1
|
+
{"version":3,"file":"emulator.js","sourceRoot":"","sources":["../../../src/emulator.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,8 @@ export interface EmulatorConfig {
|
|
|
20
20
|
dataBits?: 7 | 8;
|
|
21
21
|
/** Enable exclusive port locking (RTU) - default: true */
|
|
22
22
|
lock?: boolean;
|
|
23
|
+
/** Enable verbose logging of operations */
|
|
24
|
+
verbose?: boolean;
|
|
23
25
|
}
|
|
24
26
|
export interface RegisterStorage {
|
|
25
27
|
/** Holding registers (read/write) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;IACnC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IAChC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../src/types/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,cAAc;IAC7B,qBAAqB;IACrB,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;IACnC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;IAChC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAA;IAChB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,uCAAuC;IACvC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,qBAAqB,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IAC3D,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,eAAe,CAAC,EAAE,MAAM,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;IACrD,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,8BAA8B,CAAC,EAAE,OAAO,CAAA;CACzC;AAED,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,8BAA8B;IAC9B,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,oCAAoC;IACpC,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verbose logger for Modbus operations
|
|
3
|
+
*/
|
|
4
|
+
export declare class VerboseLogger {
|
|
5
|
+
private enabled;
|
|
6
|
+
constructor(enabled: boolean);
|
|
7
|
+
logRead(slaveId: number, functionCode: number, address: number, count: number, response: Buffer): void;
|
|
8
|
+
logWrite(slaveId: number, functionCode: number, address: number, count: number, values: number[]): void;
|
|
9
|
+
private formatHex;
|
|
10
|
+
private formatValues;
|
|
11
|
+
private formatMessage;
|
|
12
|
+
private parseReadResponse;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=verbose-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-logger.d.ts","sourceRoot":"","sources":["../../../src/verbose-logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,qBAAa,aAAa;IACZ,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,OAAO;IAEpC,OAAO,CACL,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,IAAI;IAUP,QAAQ,CACN,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EAAE,GACf,IAAI;IASP,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,iBAAiB;CA8B1B"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Verbose logger for Modbus operations
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.VerboseLogger = void 0;
|
|
7
|
+
class VerboseLogger {
|
|
8
|
+
constructor(enabled) {
|
|
9
|
+
this.enabled = enabled;
|
|
10
|
+
}
|
|
11
|
+
logRead(slaveId, functionCode, address, count, response) {
|
|
12
|
+
if (!this.enabled) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const values = this.parseReadResponse(response);
|
|
16
|
+
const formattedValues = this.formatValues(values);
|
|
17
|
+
console.log(this.formatMessage('READ', slaveId, functionCode, address, count, formattedValues));
|
|
18
|
+
}
|
|
19
|
+
logWrite(slaveId, functionCode, address, count, values) {
|
|
20
|
+
if (!this.enabled) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const formattedValues = this.formatValues(values);
|
|
24
|
+
console.log(this.formatMessage('WRITE', slaveId, functionCode, address, count, formattedValues));
|
|
25
|
+
}
|
|
26
|
+
formatHex(value, width) {
|
|
27
|
+
return `0x${value.toString(16).toUpperCase().padStart(width, '0')}`;
|
|
28
|
+
}
|
|
29
|
+
formatValues(values) {
|
|
30
|
+
return values.map((v) => this.formatHex(v, 4)).join(', ');
|
|
31
|
+
}
|
|
32
|
+
formatMessage(operation, slaveId, functionCode, address, count, formattedValues) {
|
|
33
|
+
return `[VERBOSE] ${operation} slave=${slaveId} func=${this.formatHex(functionCode, 2)} addr=${this.formatHex(address, 4)} count=${count} values=[${formattedValues}]`;
|
|
34
|
+
}
|
|
35
|
+
parseReadResponse(response) {
|
|
36
|
+
// Response format: [slaveId, functionCode, byteCount, ...data]
|
|
37
|
+
if (response.length < 3) {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
const byteCount = response[2];
|
|
41
|
+
if (byteCount === undefined || response.length < 3 + byteCount) {
|
|
42
|
+
// Attempt to parse what we have
|
|
43
|
+
const values = [];
|
|
44
|
+
for (let i = 3; i < response.length; i += 2) {
|
|
45
|
+
if (i + 1 < response.length) {
|
|
46
|
+
values.push(response.readUInt16BE(i));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return values;
|
|
50
|
+
}
|
|
51
|
+
const registerCount = byteCount / 2;
|
|
52
|
+
const values = [];
|
|
53
|
+
for (let i = 0; i < registerCount; i++) {
|
|
54
|
+
const offset = 3 + i * 2;
|
|
55
|
+
if (offset + 1 < response.length) {
|
|
56
|
+
values.push(response.readUInt16BE(offset));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return values;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.VerboseLogger = VerboseLogger;
|
|
63
|
+
//# sourceMappingURL=verbose-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verbose-logger.js","sourceRoot":"","sources":["../../../src/verbose-logger.ts"],"names":[],"mappings":"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"}
|