njs-modbus 2.1.0 → 3.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/README.md +324 -147
- package/README.zh-CN.md +380 -0
- package/dist/index.cjs +2552 -2288
- package/dist/index.d.ts +400 -233
- package/dist/index.mjs +2548 -2287
- package/dist/src/error-code.d.ts +2 -24
- package/dist/src/layers/application/abstract-application-layer.d.ts +13 -8
- package/dist/src/layers/application/ascii-application-layer.d.ts +9 -11
- package/dist/src/layers/application/rtu-application-layer.d.ts +20 -47
- package/dist/src/layers/application/tcp-application-layer.d.ts +9 -8
- package/dist/src/layers/physical/abstract-physical-layer.d.ts +43 -14
- package/dist/src/layers/physical/index.d.ts +9 -3
- package/dist/src/layers/physical/serial-physical-layer.d.ts +43 -15
- package/dist/src/layers/physical/tcp-client-physical-layer.d.ts +13 -12
- package/dist/src/layers/physical/tcp-physical-connection.d.ts +16 -0
- package/dist/src/layers/physical/tcp-server-physical-layer.d.ts +24 -14
- package/dist/src/layers/physical/udp-client-physical-layer.d.ts +33 -0
- package/dist/src/layers/physical/udp-server-physical-layer.d.ts +50 -0
- package/dist/src/layers/physical/utils.d.ts +39 -0
- package/dist/src/layers/physical/vars.d.ts +11 -0
- package/dist/src/master/master-session.d.ts +3 -3
- package/dist/src/master/master.d.ts +55 -19
- package/dist/src/slave/slave.d.ts +58 -33
- package/dist/src/types.d.ts +2 -2
- package/dist/src/utils/callback.d.ts +8 -0
- package/dist/src/utils/crc.d.ts +1 -1
- package/dist/src/utils/index.d.ts +7 -4
- package/dist/src/utils/predictRtuFrameLength.d.ts +13 -16
- package/dist/src/utils/promisify-cb.d.ts +4 -0
- package/dist/src/utils/rtu-timing.d.ts +63 -0
- package/dist/src/utils/whitelist.d.ts +11 -0
- package/dist/src/vars.d.ts +2 -0
- package/package.json +15 -8
- package/dist/src/layers/physical/udp-physical-layer.d.ts +0 -42
- package/dist/src/utils/genConnectionId.d.ts +0 -2
- package/dist/test/adu-buffer.test.d.ts +0 -1
- package/dist/test/ascii-hex-sentry.test.d.ts +0 -1
- package/dist/test/ascii-hex-validation.test.d.ts +0 -1
- package/dist/test/ascii-tcp-fragmentation.test.d.ts +0 -1
- package/dist/test/check-range.test.d.ts +0 -1
- package/dist/test/fallback-atomic.test.d.ts +0 -1
- package/dist/test/fallback-serial.test.d.ts +0 -1
- package/dist/test/fc17-serverid-validation.test.d.ts +0 -1
- package/dist/test/fc43-conformity.test.d.ts +0 -1
- package/dist/test/fc43-utf8-objects.test.d.ts +0 -1
- package/dist/test/gen-connection-id.test.d.ts +0 -1
- package/dist/test/helpers/raw-tcp.d.ts +0 -38
- package/dist/test/master-concurrent.test.d.ts +0 -1
- package/dist/test/modbus-error.test.d.ts +0 -1
- package/dist/test/physical-lifecycle.test.d.ts +0 -1
- package/dist/test/predict-rtu.test.d.ts +0 -1
- package/dist/test/rtu-custom-fc.test.d.ts +0 -1
- package/dist/test/rtu-pool-overflow.test.d.ts +0 -1
- package/dist/test/rtu-t15-timing.test.d.ts +0 -1
- package/dist/test/rtu-t35-default.test.d.ts +0 -1
- package/dist/test/rtu-t35-strict.test.d.ts +0 -1
- package/dist/test/rtu-tcp-fragmentation.test.d.ts +0 -1
- package/dist/test/serial-e2e.test.d.ts +0 -1
- package/dist/test/slave-multi-connection.test.d.ts +0 -1
- package/dist/test/slave.test.d.ts +0 -1
- package/dist/test/tcp-fragmentation.test.d.ts +0 -1
- package/dist/test/udp-multi-client.test.d.ts +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { SerialPort } from 'serialport';
|
|
2
|
+
import { Socket, SocketConstructorOpts, SocketConnectOpts, Server, ServerOpts, ListenOptions } from 'node:net';
|
|
3
|
+
import { Socket as Socket$1, SocketOptions, BindOptions } from 'node:dgram';
|
|
1
4
|
import EventEmitter from 'node:events';
|
|
2
|
-
import { SocketConstructorOpts, SocketConnectOpts, NetConnectOpts, ListenOptions } from 'node:net';
|
|
3
|
-
import { SocketOptions, BindOptions } from 'node:dgram';
|
|
4
5
|
|
|
5
6
|
type Callback$1<T> = (error: Error | null, value: T) => void;
|
|
6
|
-
type
|
|
7
|
+
type MaybeAsyncFunction<F extends (...args: any) => any> = F extends (...args: infer A) => infer R ? ((...args: A) => Promise<R>) | ((...args: A) => R) : never;
|
|
7
8
|
interface ApplicationDataUnit {
|
|
8
9
|
transaction?: number;
|
|
9
10
|
unit: number;
|
|
@@ -54,7 +55,7 @@ interface CustomFunctionCode {
|
|
|
54
55
|
* Throwing inside `handle` is turned into a Modbus exception response by the slave.
|
|
55
56
|
* If `handle` is omitted, the slave returns an ILLEGAL_FUNCTION exception for this FC.
|
|
56
57
|
*/
|
|
57
|
-
handle?:
|
|
58
|
+
handle?: MaybeAsyncFunction<(data: Buffer, unit: number) => Buffer>;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
declare enum ErrorCode {
|
|
@@ -68,31 +69,9 @@ declare enum ErrorCode {
|
|
|
68
69
|
GATEWAY_PATH_UNAVAILABLE = 10,
|
|
69
70
|
GATEWAY_TARGET_DEVICE_FAILED_TO_RESPOND = 11
|
|
70
71
|
}
|
|
71
|
-
/** Internal error codes for programmatic error handling. */
|
|
72
|
-
declare const ModbusErrorCode: {
|
|
73
|
-
readonly TIMEOUT: "ETIMEOUT";
|
|
74
|
-
readonly INVALID_RESPONSE: "EINVALID_RESPONSE";
|
|
75
|
-
readonly INSUFFICIENT_DATA: "EINSUFFICIENT_DATA";
|
|
76
|
-
readonly MASTER_CLOSED: "EMASTER_CLOSED";
|
|
77
|
-
readonly MASTER_DESTROYED: "EMASTER_DESTROYED";
|
|
78
|
-
readonly CONCURRENT_NOT_TCP: "ECONCURRENT_NOT_TCP";
|
|
79
|
-
readonly PORT_DESTROYED: "EPORT_DESTROYED";
|
|
80
|
-
readonly PORT_ALREADY_OPEN: "EPORT_ALREADY_OPEN";
|
|
81
|
-
readonly PORT_NOT_OPEN: "EPORT_NOT_OPEN";
|
|
82
|
-
readonly NOT_SUPPORTED: "ENOT_SUPPORTED";
|
|
83
|
-
readonly INVALID_DATA: "EINVALID_DATA";
|
|
84
|
-
readonly INVALID_HEX: "EINVALID_HEX";
|
|
85
|
-
readonly CRC_MISMATCH: "ECRC_MISMATCH";
|
|
86
|
-
readonly LRC_MISMATCH: "ELRC_MISMATCH";
|
|
87
|
-
readonly INCOMPLETE_FRAME: "EINCOMPLETE_FRAME";
|
|
88
|
-
readonly T1_5_EXCEEDED: "ET1_5_EXCEEDED";
|
|
89
|
-
readonly UNKNOWN_FC: "EUNKNOWN_FC";
|
|
90
|
-
readonly INVALID_ROLE: "EINVALID_ROLE";
|
|
91
|
-
readonly RANGE: "ERANGE";
|
|
92
|
-
};
|
|
93
72
|
declare class ModbusError extends Error {
|
|
94
|
-
readonly code:
|
|
95
|
-
constructor(code:
|
|
73
|
+
readonly code: ErrorCode;
|
|
74
|
+
constructor(code: ErrorCode, message?: string);
|
|
96
75
|
}
|
|
97
76
|
declare function getErrorByCode(code: ErrorCode): ModbusError;
|
|
98
77
|
declare function getCodeByError(err: Error): ErrorCode;
|
|
@@ -134,6 +113,8 @@ declare enum ConformityLevel {
|
|
|
134
113
|
REGULAR = 130,
|
|
135
114
|
EXTENDED = 131
|
|
136
115
|
}
|
|
116
|
+
/** Shared empty Buffer to avoid repeated allocations. */
|
|
117
|
+
declare const EMPTY_BUFFER: Buffer<ArrayBuffer>;
|
|
137
118
|
/** Modbus V1.1b3 PDU quantity limits. */
|
|
138
119
|
declare const LIMITS: {
|
|
139
120
|
readonly READ_COILS_MIN: 1;
|
|
@@ -145,24 +126,16 @@ declare const LIMITS: {
|
|
|
145
126
|
readonly RW_REGISTERS_WRITE_MAX: 121;
|
|
146
127
|
};
|
|
147
128
|
|
|
148
|
-
|
|
149
|
-
|
|
129
|
+
declare enum PhysicalState {
|
|
130
|
+
OPENING = "opening",
|
|
131
|
+
OPEN = "open",
|
|
132
|
+
CLOSING = "closing",
|
|
133
|
+
CLOSED = "closed"
|
|
150
134
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
'connection-close': [connection: PhysicalConnection];
|
|
156
|
-
close: [];
|
|
157
|
-
}
|
|
158
|
-
declare abstract class AbstractPhysicalLayer extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
159
|
-
abstract readonly TYPE: 'SERIAL' | 'NET';
|
|
160
|
-
abstract readonly isOpen: boolean;
|
|
161
|
-
abstract readonly destroyed: boolean;
|
|
162
|
-
abstract open(...args: any[]): Promise<void>;
|
|
163
|
-
abstract write(data: Buffer): Promise<void>;
|
|
164
|
-
abstract close(): Promise<void>;
|
|
165
|
-
abstract destroy(): Promise<void>;
|
|
135
|
+
declare enum PhysicalConnectionState {
|
|
136
|
+
CONNECTED = "connected",
|
|
137
|
+
DESTROYING = "destroying",
|
|
138
|
+
DESTROYED = "destroyed"
|
|
166
139
|
}
|
|
167
140
|
|
|
168
141
|
interface SerialPhysicalLayerOptions {
|
|
@@ -172,132 +145,244 @@ interface SerialPhysicalLayerOptions {
|
|
|
172
145
|
* The baud rate of the port to be opened. This should match one of the commonly available baud rates, such as 110, 300, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 57600, or 115200. Custom rates are supported best effort per platform. The device connected to the serial port is not guaranteed to support the requested baud rate, even if the port itself supports that baud rate.
|
|
173
146
|
*/
|
|
174
147
|
baudRate: number;
|
|
175
|
-
/** Must be one of these: 5, 6, 7, or 8
|
|
148
|
+
/** Must be one of these: 5, 6, 7, or 8. Defaults to 8 */
|
|
176
149
|
dataBits?: 5 | 6 | 7 | 8;
|
|
177
150
|
/** Prevent other processes from opening the port. Windows does not currently support `false`. Defaults to true */
|
|
178
151
|
lock?: boolean;
|
|
179
|
-
/** Must be 1, 1.5 or 2
|
|
152
|
+
/** Must be 1, 1.5 or 2. Defaults to 1 */
|
|
180
153
|
stopBits?: 1 | 1.5 | 2;
|
|
181
|
-
parity
|
|
154
|
+
/** Device parity. Defaults to none */
|
|
155
|
+
parity?: 'none' | 'even' | 'odd' | 'mark' | 'space';
|
|
182
156
|
/** Flow control Setting. Defaults to false */
|
|
183
157
|
rtscts?: boolean;
|
|
184
158
|
/** Flow control Setting. Defaults to false */
|
|
185
159
|
xon?: boolean;
|
|
186
160
|
/** Flow control Setting. Defaults to false */
|
|
187
161
|
xoff?: boolean;
|
|
188
|
-
/** Flow control Setting
|
|
162
|
+
/** Flow control Setting. Defaults to false */
|
|
189
163
|
xany?: boolean;
|
|
190
164
|
/** drop DTR on close. Defaults to true */
|
|
191
165
|
hupcl?: boolean;
|
|
166
|
+
/** The size of the read and write buffers. Defaults to 64k */
|
|
167
|
+
highWaterMark?: number;
|
|
168
|
+
/** Emit 'end' on port close. Defaults to false */
|
|
169
|
+
endOnClose?: boolean;
|
|
170
|
+
/** see `man termios`. Defaults to 1 (Darwin/Linux only) */
|
|
171
|
+
vmin?: number;
|
|
172
|
+
/** see `man termios`. Defaults to 0 (Darwin/Linux only) */
|
|
173
|
+
vtime?: number;
|
|
174
|
+
/** RTS mode. Defaults to handshake (Windows only) */
|
|
175
|
+
rtsMode?: 'handshake' | 'enable' | 'toggle';
|
|
192
176
|
}
|
|
193
177
|
declare class SerialPhysicalLayer extends AbstractPhysicalLayer {
|
|
194
|
-
TYPE:
|
|
178
|
+
readonly TYPE: "SERIAL";
|
|
179
|
+
private _state;
|
|
180
|
+
private _connections;
|
|
195
181
|
private _serialport;
|
|
196
|
-
private
|
|
197
|
-
private
|
|
198
|
-
private _destroyed;
|
|
182
|
+
private _serialportOpts;
|
|
183
|
+
private _path;
|
|
199
184
|
private _baudRate;
|
|
200
|
-
|
|
201
|
-
|
|
185
|
+
private _pendingOpenCbs;
|
|
186
|
+
private _pendingCloseCbs;
|
|
187
|
+
private _cleanupFns;
|
|
188
|
+
get state(): PhysicalState;
|
|
189
|
+
get serialport(): SerialPort | null;
|
|
190
|
+
get path(): string;
|
|
202
191
|
get baudRate(): number;
|
|
203
192
|
constructor(options: SerialPhysicalLayerOptions);
|
|
204
|
-
open():
|
|
205
|
-
|
|
206
|
-
close(): Promise<void>;
|
|
207
|
-
destroy(): Promise<void>;
|
|
193
|
+
open(cb?: (err?: Error | null) => void): void;
|
|
194
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
208
195
|
}
|
|
209
196
|
|
|
210
197
|
declare class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
211
|
-
TYPE:
|
|
198
|
+
readonly TYPE: "TCP_CLIENT";
|
|
199
|
+
private _state;
|
|
200
|
+
private _connections;
|
|
212
201
|
private _socket;
|
|
213
|
-
private
|
|
214
|
-
private
|
|
215
|
-
private
|
|
216
|
-
private
|
|
217
|
-
|
|
218
|
-
get
|
|
219
|
-
get destroyed(): boolean;
|
|
202
|
+
private _socketOpts?;
|
|
203
|
+
private _pendingOpenCbs;
|
|
204
|
+
private _pendingCloseCbs;
|
|
205
|
+
private _cleanupFns;
|
|
206
|
+
get state(): PhysicalState;
|
|
207
|
+
get socket(): Socket | null;
|
|
220
208
|
constructor(options?: SocketConstructorOpts);
|
|
221
|
-
open(options?: SocketConnectOpts):
|
|
222
|
-
|
|
223
|
-
close(): Promise<void>;
|
|
224
|
-
destroy(): Promise<void>;
|
|
209
|
+
open(options?: SocketConnectOpts | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
210
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
225
211
|
}
|
|
226
212
|
|
|
213
|
+
interface TcpServerPhysicalLayerOptions {
|
|
214
|
+
/** Allowed client IP addresses. IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1) are normalized before checking. */
|
|
215
|
+
whitelist?: string[];
|
|
216
|
+
/** Maximum number of concurrent connections. When exceeded, new connections are silently dropped by Node.js. */
|
|
217
|
+
maxConnections?: number;
|
|
218
|
+
/** Idle timeout in ms. Connection is destroyed if no data is received within this time. 0 = disabled. */
|
|
219
|
+
idleTimeout?: number;
|
|
220
|
+
/** Forwarded to `net.createServer()`. */
|
|
221
|
+
serverOpts?: ServerOpts;
|
|
222
|
+
}
|
|
227
223
|
declare class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
228
|
-
TYPE:
|
|
229
|
-
private
|
|
230
|
-
private _isOpen;
|
|
231
|
-
private _isOpening;
|
|
232
|
-
private _destroyed;
|
|
224
|
+
readonly TYPE: "TCP_SERVER";
|
|
225
|
+
private _state;
|
|
233
226
|
private _connections;
|
|
234
|
-
private
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
227
|
+
private _server;
|
|
228
|
+
private _opts;
|
|
229
|
+
private _pendingOpenCbs;
|
|
230
|
+
private _pendingCloseCbs;
|
|
231
|
+
private _cleanupFns;
|
|
232
|
+
get state(): PhysicalState;
|
|
233
|
+
get server(): Server | null;
|
|
234
|
+
constructor(options?: TcpServerPhysicalLayerOptions);
|
|
235
|
+
open(options?: ListenOptions | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
236
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
242
237
|
}
|
|
243
238
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
239
|
+
declare class UdpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
240
|
+
readonly TYPE: "UDP_CLIENT";
|
|
241
|
+
private _state;
|
|
242
|
+
private _connections;
|
|
243
|
+
private _socket;
|
|
244
|
+
private _socketOpts;
|
|
245
|
+
private _pendingOpenCbs;
|
|
246
|
+
private _pendingCloseCbs;
|
|
247
|
+
private _cleanupFns;
|
|
248
|
+
get state(): PhysicalState;
|
|
249
|
+
get socket(): Socket$1 | null;
|
|
250
|
+
constructor(options?: Partial<SocketOptions>);
|
|
251
|
+
open(remote?: {
|
|
252
252
|
port?: number;
|
|
253
253
|
address?: string;
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
254
|
+
} | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
255
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
interface UdpServerPhysicalLayerOptions {
|
|
259
|
+
/** Allowed client IP addresses. IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1) are normalized before checking. */
|
|
260
|
+
whitelist?: string[];
|
|
261
|
+
/** Maximum number of concurrent virtual client connections. When exceeded, datagrams from new clients are silently ignored. */
|
|
262
|
+
maxConnections?: number;
|
|
263
|
+
/** Connection idle timeout in ms. Pass `0` to disable eviction. Defaults to 30000. */
|
|
261
264
|
idleTimeout?: number;
|
|
265
|
+
/** Forwarded to `dgram.createSocket()`. */
|
|
266
|
+
socketOpts?: Partial<SocketOptions>;
|
|
262
267
|
}
|
|
263
|
-
declare class
|
|
264
|
-
TYPE:
|
|
265
|
-
private
|
|
268
|
+
declare class UdpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
269
|
+
readonly TYPE: "UDP_SERVER";
|
|
270
|
+
private _state;
|
|
266
271
|
private _connections;
|
|
267
|
-
private
|
|
268
|
-
private
|
|
269
|
-
private
|
|
270
|
-
private
|
|
271
|
-
private
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
272
|
+
private _socket;
|
|
273
|
+
private _opts;
|
|
274
|
+
private _pendingOpenCbs;
|
|
275
|
+
private _pendingCloseCbs;
|
|
276
|
+
private _cleanupFns;
|
|
277
|
+
get state(): PhysicalState;
|
|
278
|
+
get socket(): Socket$1 | null;
|
|
279
|
+
constructor(options?: UdpServerPhysicalLayerOptions);
|
|
280
|
+
/**
|
|
281
|
+
* Bind the UDP socket and start accepting datagrams.
|
|
282
|
+
*
|
|
283
|
+
* @param options Bind options (port, address, etc.). Defaults to port 502.
|
|
284
|
+
* @param cb Callback invoked when binding completes or fails.
|
|
285
|
+
*/
|
|
286
|
+
open(options?: BindOptions | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
287
|
+
close(cb?: (err?: Error | null) => void): void;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
interface AbstractPhysicalConnectionEvents {
|
|
291
|
+
data: [data: Buffer];
|
|
292
|
+
close: [];
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* A one-way data transmission channel.
|
|
296
|
+
*
|
|
297
|
+
* State transitions are unidirectional: CONNECTED → DESTROYING → DESTROYED.
|
|
298
|
+
* Once closed, the instance cannot be reused; create a new connection instead.
|
|
299
|
+
*/
|
|
300
|
+
declare abstract class AbstractPhysicalConnection extends EventEmitter<AbstractPhysicalConnectionEvents> {
|
|
301
|
+
abstract readonly state: PhysicalConnectionState;
|
|
302
|
+
abstract readonly physicalLayer: AbstractPhysicalLayer;
|
|
303
|
+
abstract write(data: Buffer, cb?: (err?: Error | null) => void): void;
|
|
304
|
+
abstract destroy(cb?: (err?: Error | null) => void): void;
|
|
305
|
+
}
|
|
306
|
+
interface AbstractPhysicalLayerEvents {
|
|
307
|
+
open: [];
|
|
308
|
+
connect: [connection: AbstractPhysicalConnection];
|
|
309
|
+
close: [];
|
|
310
|
+
error: [error: Error];
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* An abstraction over local hardware or network resources.
|
|
314
|
+
*
|
|
315
|
+
* `open()` acquires the resource (serial port, TCP socket, UDP socket, etc.).
|
|
316
|
+
* Once ready, it emits `connect` with an {@link AbstractPhysicalConnection},
|
|
317
|
+
* unifying serial, TCP client, TCP server, and UDP under a single
|
|
318
|
+
* "connection-oriented" model similar to a TCP server accepting sockets.
|
|
319
|
+
*/
|
|
320
|
+
declare abstract class AbstractPhysicalLayer extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
321
|
+
abstract readonly TYPE: 'SERIAL' | 'TCP_CLIENT' | 'TCP_SERVER' | 'UDP_CLIENT' | 'UDP_SERVER';
|
|
322
|
+
is(type: 'SERIAL'): this is SerialPhysicalLayer;
|
|
323
|
+
is(type: 'TCP_CLIENT'): this is TcpClientPhysicalLayer;
|
|
324
|
+
is(type: 'TCP_SERVER'): this is TcpServerPhysicalLayer;
|
|
325
|
+
is(type: 'UDP_CLIENT'): this is UdpClientPhysicalLayer;
|
|
326
|
+
is(type: 'UDP_SERVER'): this is UdpServerPhysicalLayer;
|
|
327
|
+
abstract readonly state: PhysicalState;
|
|
328
|
+
/** Last argument is the callback: `(err?: Error | null) => void`. Callback is optional. */
|
|
329
|
+
abstract open(...args: any[]): void;
|
|
330
|
+
abstract close(cb?: (err?: Error | null) => void): void;
|
|
283
331
|
}
|
|
284
332
|
|
|
333
|
+
type PhysicalConfig = {
|
|
334
|
+
type: 'SERIAL';
|
|
335
|
+
opts: SerialPhysicalLayerOptions;
|
|
336
|
+
} | {
|
|
337
|
+
type: 'TCP_CLIENT';
|
|
338
|
+
socketOpts?: SocketConstructorOpts;
|
|
339
|
+
} | {
|
|
340
|
+
type: 'TCP_SERVER';
|
|
341
|
+
opts?: TcpServerPhysicalLayerOptions;
|
|
342
|
+
} | {
|
|
343
|
+
type: 'UDP_CLIENT';
|
|
344
|
+
socketOpts?: Partial<SocketOptions>;
|
|
345
|
+
} | {
|
|
346
|
+
type: 'UDP_SERVER';
|
|
347
|
+
opts?: UdpServerPhysicalLayerOptions;
|
|
348
|
+
} | {
|
|
349
|
+
type: 'CUSTOM';
|
|
350
|
+
layer: AbstractPhysicalLayer;
|
|
351
|
+
};
|
|
352
|
+
type OpenArgs<T extends PhysicalConfig> = T extends {
|
|
353
|
+
type: 'SERIAL';
|
|
354
|
+
} ? Parameters<SerialPhysicalLayer['open']> : T extends {
|
|
355
|
+
type: 'TCP_CLIENT';
|
|
356
|
+
} ? Parameters<TcpClientPhysicalLayer['open']> : T extends {
|
|
357
|
+
type: 'TCP_SERVER';
|
|
358
|
+
} ? Parameters<TcpServerPhysicalLayer['open']> : T extends {
|
|
359
|
+
type: 'UDP_CLIENT';
|
|
360
|
+
} ? Parameters<UdpClientPhysicalLayer['open']> : T extends {
|
|
361
|
+
type: 'UDP_SERVER';
|
|
362
|
+
} ? Parameters<UdpServerPhysicalLayer['open']> : never;
|
|
363
|
+
declare function createPhysicalLayer(config: PhysicalConfig): AbstractPhysicalLayer;
|
|
364
|
+
|
|
285
365
|
interface AbstractApplicationLayerEvents {
|
|
286
366
|
framing: [frame: ApplicationDataUnit & {
|
|
287
367
|
buffer: Buffer;
|
|
288
|
-
}
|
|
368
|
+
}];
|
|
289
369
|
'framing-error': [error: Error];
|
|
290
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* Application-layer protocol handler bound to a single physical connection.
|
|
373
|
+
*
|
|
374
|
+
* Its lifetime follows the channel: created when the underlying connection is
|
|
375
|
+
* established and discarded when the connection closes. Subclasses implement
|
|
376
|
+
* ASCII, RTU, or TCP framing rules.
|
|
377
|
+
*/
|
|
291
378
|
declare abstract class AbstractApplicationLayer extends EventEmitter<AbstractApplicationLayerEvents> {
|
|
292
|
-
abstract readonly PROTOCOL: '
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
set role(value: 'MASTER' | 'SLAVE');
|
|
379
|
+
abstract readonly PROTOCOL: 'ASCII' | 'RTU' | 'TCP';
|
|
380
|
+
abstract ROLE: 'MASTER' | 'SLAVE';
|
|
381
|
+
abstract readonly connection: AbstractPhysicalConnection;
|
|
296
382
|
flush(): void;
|
|
297
383
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
298
384
|
removeCustomFunctionCode(fc: number): void;
|
|
299
|
-
abstract encode(data:
|
|
300
|
-
abstract destroy(): void;
|
|
385
|
+
abstract encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
|
|
301
386
|
}
|
|
302
387
|
|
|
303
388
|
interface AsciiApplicationLayerOptions {
|
|
@@ -310,93 +395,113 @@ interface AsciiApplicationLayerOptions {
|
|
|
310
395
|
}
|
|
311
396
|
declare class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
312
397
|
readonly PROTOCOL: "ASCII";
|
|
398
|
+
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
313
399
|
readonly lenientHex: boolean;
|
|
314
|
-
private
|
|
315
|
-
private
|
|
316
|
-
private
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
flush(): void;
|
|
400
|
+
private _connection;
|
|
401
|
+
private _state;
|
|
402
|
+
private _cleanupFns;
|
|
403
|
+
get connection(): AbstractPhysicalConnection;
|
|
404
|
+
constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection, options?: AsciiApplicationLayerOptions);
|
|
320
405
|
private framing;
|
|
321
|
-
|
|
322
|
-
|
|
406
|
+
flush(): void;
|
|
407
|
+
encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
|
|
323
408
|
}
|
|
324
409
|
|
|
325
410
|
interface RtuApplicationLayerOptions {
|
|
411
|
+
/** Inter-frame silence in milliseconds (Modbus RTU t3.5). 0 = disabled (immediate parse). */
|
|
412
|
+
intervalBetweenFrames?: number;
|
|
413
|
+
/** Inter-character timeout in milliseconds (Modbus RTU t1.5). Opt-in. */
|
|
414
|
+
interCharTimeout?: number;
|
|
326
415
|
/**
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
* - `{ unit: 'bit', value: 38.5 }` — spec bit-time approximation
|
|
331
|
-
* - `{ unit: 'ms', value: 20 }` — explicit milliseconds
|
|
332
|
-
*
|
|
333
|
-
* Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 the spec uses a fixed
|
|
334
|
-
* 1.75 ms regardless of the bit value supplied.
|
|
335
|
-
*/
|
|
336
|
-
intervalBetweenFrames?: {
|
|
337
|
-
unit: 'bit' | 'ms';
|
|
338
|
-
value: number;
|
|
339
|
-
};
|
|
340
|
-
/**
|
|
341
|
-
* Inter-character timeout (Modbus RTU t1.5). Opt-in; **disabled** by default
|
|
342
|
-
* because Node.js `setTimeout` precision (~1 ms minimum, ~15.6 ms on Windows)
|
|
343
|
-
* is too coarse to reliably honor t1.5 at common baud rates without
|
|
344
|
-
* false-positive frame discards. When set, a mid-frame gap exceeding this
|
|
345
|
-
* duration discards the in-progress buffer and emits `framing-error`.
|
|
346
|
-
* Only takes effect on serial transports.
|
|
347
|
-
*
|
|
348
|
-
* - `{ unit: 'bit', value: 21 }` — bit-time approximation (~1.5 char times)
|
|
349
|
-
* - `{ unit: 'ms', value: 1 }` — explicit milliseconds
|
|
350
|
-
*
|
|
351
|
-
* Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 the spec uses a fixed
|
|
352
|
-
* 0.75 ms regardless of the bit value supplied.
|
|
416
|
+
* Buffer pool size per connection (bytes). Defaults to `MAX_FRAME_LENGTH * 2`
|
|
417
|
+
* (512 bytes). Increase this if you expect frames larger than 256 bytes or
|
|
418
|
+
* heavy pipelining on a single connection.
|
|
353
419
|
*/
|
|
354
|
-
|
|
355
|
-
unit: 'bit' | 'ms';
|
|
356
|
-
value: number;
|
|
357
|
-
};
|
|
420
|
+
poolSize?: number;
|
|
358
421
|
}
|
|
359
422
|
declare class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
360
423
|
readonly PROTOCOL: "RTU";
|
|
361
|
-
|
|
362
|
-
private
|
|
363
|
-
private
|
|
424
|
+
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
425
|
+
private _connection;
|
|
426
|
+
private _state;
|
|
427
|
+
private _poolSize;
|
|
364
428
|
private _threePointFiveT;
|
|
365
429
|
private _onePointFiveT;
|
|
366
|
-
private
|
|
367
|
-
|
|
368
|
-
|
|
430
|
+
private _customFunctionCodes;
|
|
431
|
+
private _cleanupFns;
|
|
432
|
+
get connection(): AbstractPhysicalConnection;
|
|
433
|
+
constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection, options?: RtuApplicationLayerOptions);
|
|
369
434
|
private clearStateTimers;
|
|
370
|
-
private
|
|
435
|
+
private flushBuffer;
|
|
371
436
|
flush(): void;
|
|
372
437
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
373
438
|
removeCustomFunctionCode(fc: number): void;
|
|
374
|
-
|
|
375
|
-
private tryExtract;
|
|
376
|
-
private checkExpected;
|
|
377
|
-
private crcMatches;
|
|
378
|
-
private deliverFrame;
|
|
379
|
-
encode(data: ApplicationDataUnit): Buffer;
|
|
380
|
-
destroy(): void;
|
|
439
|
+
encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
|
|
381
440
|
}
|
|
382
441
|
|
|
383
442
|
declare class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
384
443
|
readonly PROTOCOL: "TCP";
|
|
444
|
+
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
445
|
+
private _connection;
|
|
385
446
|
private _transactionId;
|
|
386
|
-
private
|
|
387
|
-
private
|
|
388
|
-
|
|
389
|
-
constructor(
|
|
447
|
+
private _buffer;
|
|
448
|
+
private _cleanupFns;
|
|
449
|
+
get connection(): AbstractPhysicalConnection;
|
|
450
|
+
constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection);
|
|
390
451
|
private tryExtract;
|
|
391
452
|
private processFrame;
|
|
392
|
-
|
|
393
|
-
|
|
453
|
+
flush(): void;
|
|
454
|
+
encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
|
|
394
455
|
}
|
|
395
456
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
457
|
+
/**
|
|
458
|
+
* RTU timing parameter — accepts either:
|
|
459
|
+
* - a bare `number` in milliseconds (`0` to disable the timer entirely)
|
|
460
|
+
* - `{ unit: 'ms', value: N }` — explicit milliseconds (equivalent to bare `N`)
|
|
461
|
+
* - `{ unit: 'bit', value: N }` — bit-time approximation, derived from `baudRate`
|
|
462
|
+
*
|
|
463
|
+
* The bare-number form is the recommended default; the object form exists for
|
|
464
|
+
* specs that quote bit-time. Pass `0` (or `{ unit: 'ms', value: 0 }`) to disable
|
|
465
|
+
* the timer; either form short-circuits the baudRate-derived fallback.
|
|
466
|
+
*/
|
|
467
|
+
type RtuTimingValue = number | {
|
|
468
|
+
unit: 'bit' | 'ms';
|
|
469
|
+
value: number;
|
|
470
|
+
};
|
|
471
|
+
/** User-facing RTU protocol options (supports both bit and ms units). */
|
|
472
|
+
interface RtuProtocolOptions {
|
|
473
|
+
/**
|
|
474
|
+
* Inter-frame silence (Modbus RTU t3.5).
|
|
475
|
+
*
|
|
476
|
+
* - `20` or `{ unit: 'ms', value: 20 }` — 20 ms
|
|
477
|
+
* - `{ unit: 'bit', value: 38.5 }` — spec bit-time approximation (default when `baudRate` is provided)
|
|
478
|
+
* - `0` — disable t3.5 timing (immediate parse on every chunk; useful for
|
|
479
|
+
* lossless transports such as RTU-over-TCP or PTY-based tests where the
|
|
480
|
+
* wire's silence semantics do not apply)
|
|
481
|
+
*
|
|
482
|
+
* Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 a fixed 1.75 ms is used
|
|
483
|
+
* regardless of the bit value.
|
|
484
|
+
*/
|
|
485
|
+
intervalBetweenFrames?: RtuTimingValue;
|
|
486
|
+
/**
|
|
487
|
+
* Inter-character timeout (Modbus RTU t1.5). Opt-in; **disabled** by default.
|
|
488
|
+
*
|
|
489
|
+
* - `1` or `{ unit: 'ms', value: 1 }` — 1 ms
|
|
490
|
+
* - `{ unit: 'bit', value: 21 }` — bit-time approximation (~1.5 char times)
|
|
491
|
+
* - `0` — disable explicitly
|
|
492
|
+
*
|
|
493
|
+
* Per Modbus V1.02 §2.5.1.1, at baud rates > 19200 a fixed 0.75 ms is used
|
|
494
|
+
* regardless of the bit value.
|
|
495
|
+
*/
|
|
496
|
+
interCharTimeout?: RtuTimingValue;
|
|
497
|
+
/**
|
|
498
|
+
* Buffer pool size per connection (bytes). Defaults to `MAX_FRAME_LENGTH * 2`
|
|
499
|
+
* (512 bytes). Increase this if you expect frames larger than 256 bytes or
|
|
500
|
+
* heavy pipelining on a single connection.
|
|
501
|
+
*/
|
|
502
|
+
poolSize?: number;
|
|
399
503
|
}
|
|
504
|
+
|
|
400
505
|
interface ReturnValue<T> {
|
|
401
506
|
transaction?: number;
|
|
402
507
|
unit: number;
|
|
@@ -413,22 +518,45 @@ interface ModbusMasterOptions {
|
|
|
413
518
|
* Default false (FIFO queue, requests are serialized).
|
|
414
519
|
*/
|
|
415
520
|
concurrent?: boolean;
|
|
521
|
+
physical: PhysicalConfig;
|
|
522
|
+
protocol: {
|
|
523
|
+
type: 'RTU';
|
|
524
|
+
opts?: RtuProtocolOptions;
|
|
525
|
+
} | {
|
|
526
|
+
type: 'TCP';
|
|
527
|
+
} | {
|
|
528
|
+
type: 'ASCII';
|
|
529
|
+
opts?: AsciiApplicationLayerOptions;
|
|
530
|
+
};
|
|
416
531
|
}
|
|
417
|
-
declare class ModbusMaster<
|
|
418
|
-
|
|
419
|
-
|
|
532
|
+
declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
533
|
+
readonly timeout: number;
|
|
534
|
+
readonly concurrent: boolean;
|
|
420
535
|
private _masterSession;
|
|
421
|
-
private
|
|
536
|
+
private _physicalLayer;
|
|
537
|
+
private _protocol;
|
|
538
|
+
private _appLayer?;
|
|
539
|
+
private _customFunctionCodes;
|
|
540
|
+
private _queueUnits;
|
|
541
|
+
private _queueFcs;
|
|
542
|
+
private _queueDatas;
|
|
543
|
+
private _queueTimeouts;
|
|
544
|
+
private _queueBroadcasts;
|
|
545
|
+
private _queueResolves;
|
|
546
|
+
private _queueRejects;
|
|
547
|
+
private _queueHead;
|
|
548
|
+
private _queueLen;
|
|
422
549
|
private _draining;
|
|
423
550
|
private _nextTid;
|
|
424
|
-
private
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
get
|
|
428
|
-
|
|
429
|
-
|
|
551
|
+
private _cleanupFns;
|
|
552
|
+
private _closePromise;
|
|
553
|
+
get state(): PhysicalState;
|
|
554
|
+
get physicalLayer(): AbstractPhysicalLayer;
|
|
555
|
+
constructor(options: T);
|
|
556
|
+
private _createAppLayer;
|
|
430
557
|
private send;
|
|
431
558
|
private _drain;
|
|
559
|
+
private _processNext;
|
|
432
560
|
private _exchange;
|
|
433
561
|
private writeFC1Or2;
|
|
434
562
|
writeFC1: this['readCoils'];
|
|
@@ -487,26 +615,41 @@ declare class ModbusMaster<A extends AbstractApplicationLayer, P extends Abstrac
|
|
|
487
615
|
removeCustomFunctionCode(fc: number): void;
|
|
488
616
|
sendCustomFC(unit: 0, fc: number, data: Buffer | number[], timeout?: number): Promise<void>;
|
|
489
617
|
sendCustomFC(unit: number, fc: number, data: Buffer | number[], timeout?: number): Promise<Buffer>;
|
|
490
|
-
|
|
491
|
-
|
|
618
|
+
/**
|
|
619
|
+
* Open the underlying physical layer and begin accepting connections.
|
|
620
|
+
*
|
|
621
|
+
* A `ModbusMaster` instance can only be opened once. Once {@link close}
|
|
622
|
+
* is called — explicitly or because the physical layer disconnected —
|
|
623
|
+
* the instance is permanently closed and cannot be reopened.
|
|
624
|
+
* Create a new `ModbusMaster` if a new connection is required.
|
|
625
|
+
*/
|
|
626
|
+
open(...args: OpenArgs<T['physical']>): Promise<void>;
|
|
627
|
+
private _close;
|
|
628
|
+
/**
|
|
629
|
+
* Permanently close the master and release all resources.
|
|
630
|
+
*
|
|
631
|
+
* After calling this method the instance is considered dead:
|
|
632
|
+
* - No further requests can be sent.
|
|
633
|
+
* - The instance cannot be reopened via {@link open}.
|
|
634
|
+
* - All event listeners registered on this master are removed.
|
|
635
|
+
*/
|
|
492
636
|
close(): Promise<void>;
|
|
493
|
-
destroy(): Promise<void>;
|
|
494
637
|
}
|
|
495
638
|
|
|
496
639
|
type Frame = ApplicationDataUnit & {
|
|
497
640
|
buffer: Buffer;
|
|
498
641
|
};
|
|
499
|
-
type PreCheck = (frame: Frame) => boolean | number | undefined;
|
|
500
642
|
type Callback = (error: Error | null, frame?: Frame) => void;
|
|
501
643
|
declare class MasterSession {
|
|
502
644
|
private _waiters;
|
|
503
|
-
|
|
645
|
+
/** Register a callback for `key`. No timer — timeout is managed by the caller. */
|
|
646
|
+
start(key: string | number, callback: Callback): void;
|
|
647
|
+
/** Cancel a pending waiter without firing its callback. */
|
|
504
648
|
stop(key: string | number): void;
|
|
505
649
|
stopAll(error: Error): void;
|
|
506
650
|
has(key: string | number): boolean;
|
|
507
651
|
handleFrame(frame: Frame): void;
|
|
508
652
|
handleError(error: Error): void;
|
|
509
|
-
private runPreChecks;
|
|
510
653
|
}
|
|
511
654
|
|
|
512
655
|
interface ModbusSlaveModel {
|
|
@@ -517,27 +660,27 @@ interface ModbusSlaveModel {
|
|
|
517
660
|
* If provide the return value, use this value as data of `PDU` to respond.
|
|
518
661
|
* Otherwise keep the default read and write behavior.
|
|
519
662
|
*/
|
|
520
|
-
interceptor?:
|
|
521
|
-
readDiscreteInputs?:
|
|
522
|
-
readCoils?:
|
|
523
|
-
writeSingleCoil?:
|
|
663
|
+
interceptor?: MaybeAsyncFunction<(fc: number, data: Buffer) => Buffer | undefined>;
|
|
664
|
+
readDiscreteInputs?: MaybeAsyncFunction<(address: number, length: number) => boolean[]>;
|
|
665
|
+
readCoils?: MaybeAsyncFunction<(address: number, length: number) => boolean[]>;
|
|
666
|
+
writeSingleCoil?: MaybeAsyncFunction<(address: number, value: boolean) => void>;
|
|
524
667
|
/**
|
|
525
668
|
* If omitted, defaults to loop and call `writeSingleCoil`.
|
|
526
669
|
*/
|
|
527
|
-
writeMultipleCoils?:
|
|
528
|
-
readInputRegisters?:
|
|
529
|
-
readHoldingRegisters?:
|
|
530
|
-
writeSingleRegister?:
|
|
670
|
+
writeMultipleCoils?: MaybeAsyncFunction<(address: number, value: boolean[]) => void>;
|
|
671
|
+
readInputRegisters?: MaybeAsyncFunction<(address: number, length: number) => number[]>;
|
|
672
|
+
readHoldingRegisters?: MaybeAsyncFunction<(address: number, length: number) => number[]>;
|
|
673
|
+
writeSingleRegister?: MaybeAsyncFunction<(address: number, value: number) => void>;
|
|
531
674
|
/**
|
|
532
675
|
* If omitted, defaults to loop and call `writeSingleRegister`.
|
|
533
676
|
*/
|
|
534
|
-
writeMultipleRegisters?:
|
|
677
|
+
writeMultipleRegisters?: MaybeAsyncFunction<(address: number, value: number[]) => void>;
|
|
535
678
|
/**
|
|
536
679
|
* If omitted, defaults to call `readHoldingRegisters` and `writeSingleRegister`.
|
|
537
680
|
*/
|
|
538
|
-
maskWriteRegister?:
|
|
539
|
-
reportServerId?:
|
|
540
|
-
readDeviceIdentification?:
|
|
681
|
+
maskWriteRegister?: MaybeAsyncFunction<(address: number, andMask: number, orMask: number) => void>;
|
|
682
|
+
reportServerId?: MaybeAsyncFunction<() => ServerId>;
|
|
683
|
+
readDeviceIdentification?: MaybeAsyncFunction<() => {
|
|
541
684
|
[index: number]: string;
|
|
542
685
|
}>;
|
|
543
686
|
getAddressRange?: () => {
|
|
@@ -547,10 +690,6 @@ interface ModbusSlaveModel {
|
|
|
547
690
|
holdingRegisters?: [number, number] | [number, number][];
|
|
548
691
|
};
|
|
549
692
|
}
|
|
550
|
-
interface ModbusSlaveEvents {
|
|
551
|
-
error: [error: Error];
|
|
552
|
-
close: [];
|
|
553
|
-
}
|
|
554
693
|
interface ModbusSlaveOptions {
|
|
555
694
|
/**
|
|
556
695
|
* Pipelined concurrent processing of requests within one connection.
|
|
@@ -558,19 +697,31 @@ interface ModbusSlaveOptions {
|
|
|
558
697
|
* Default false — per-connection FIFO. RTU/ASCII + concurrent=true throws.
|
|
559
698
|
*/
|
|
560
699
|
concurrent?: boolean;
|
|
700
|
+
physical: PhysicalConfig;
|
|
701
|
+
protocol: {
|
|
702
|
+
type: 'RTU';
|
|
703
|
+
opts?: RtuProtocolOptions;
|
|
704
|
+
} | {
|
|
705
|
+
type: 'TCP';
|
|
706
|
+
} | {
|
|
707
|
+
type: 'ASCII';
|
|
708
|
+
opts?: AsciiApplicationLayerOptions;
|
|
709
|
+
};
|
|
561
710
|
}
|
|
562
|
-
declare class ModbusSlave<
|
|
563
|
-
|
|
564
|
-
private physicalLayer;
|
|
565
|
-
models: Map<number, ModbusSlaveModel>;
|
|
711
|
+
declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
712
|
+
readonly models: Map<number, ModbusSlaveModel>;
|
|
566
713
|
readonly concurrent: boolean;
|
|
567
|
-
private
|
|
714
|
+
private _physicalLayer;
|
|
715
|
+
private _protocol;
|
|
716
|
+
private _appLayers;
|
|
568
717
|
private _customFunctionCodes;
|
|
569
718
|
private _locks;
|
|
570
|
-
private
|
|
571
|
-
|
|
572
|
-
get
|
|
573
|
-
|
|
719
|
+
private _cleanupFns;
|
|
720
|
+
private _closePromise;
|
|
721
|
+
get state(): PhysicalState;
|
|
722
|
+
get physicalLayer(): AbstractPhysicalLayer;
|
|
723
|
+
constructor(options: T);
|
|
724
|
+
private _createAppLayer;
|
|
574
725
|
private handleFC1;
|
|
575
726
|
private handleFC2;
|
|
576
727
|
private handleFC3;
|
|
@@ -587,17 +738,33 @@ declare class ModbusSlave<A extends AbstractApplicationLayer, P extends Abstract
|
|
|
587
738
|
private _drain;
|
|
588
739
|
private _processFrame;
|
|
589
740
|
private _intercept;
|
|
590
|
-
private
|
|
741
|
+
private _withAddressLock;
|
|
591
742
|
private _handleFC;
|
|
743
|
+
private _handleCustomFC;
|
|
592
744
|
add(model: ModbusSlaveModel): void;
|
|
593
745
|
remove(unit: number): void;
|
|
594
746
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
595
747
|
removeCustomFunctionCode(fc: number): void;
|
|
596
|
-
|
|
597
|
-
|
|
748
|
+
/**
|
|
749
|
+
* Open the underlying physical layer and begin accepting connections.
|
|
750
|
+
*
|
|
751
|
+
* A `ModbusSlave` instance can only be opened once. Once {@link close}
|
|
752
|
+
* is called — explicitly or because the physical layer disconnected —
|
|
753
|
+
* the instance is permanently closed and cannot be reopened.
|
|
754
|
+
* Create a new `ModbusSlave` if a new server is required.
|
|
755
|
+
*/
|
|
756
|
+
open(...args: OpenArgs<T['physical']>): Promise<void>;
|
|
757
|
+
private _close;
|
|
758
|
+
/**
|
|
759
|
+
* Permanently close the slave and release all resources.
|
|
760
|
+
*
|
|
761
|
+
* After calling this method the instance is considered dead:
|
|
762
|
+
* - No further requests can be processed.
|
|
763
|
+
* - The instance cannot be reopened via {@link open}.
|
|
764
|
+
* - All event listeners registered on this slave are removed.
|
|
765
|
+
*/
|
|
598
766
|
close(): Promise<void>;
|
|
599
|
-
destroy(): Promise<void>;
|
|
600
767
|
}
|
|
601
768
|
|
|
602
|
-
export { AbstractApplicationLayer, AbstractPhysicalLayer, AsciiApplicationLayer, COIL_OFF, COIL_ON, ConformityLevel, EXCEPTION_OFFSET, ErrorCode, FunctionCode, LIMITS, MEI_READ_DEVICE_ID, MasterSession, ModbusError,
|
|
603
|
-
export type { ApplicationDataUnit, AsciiApplicationLayerOptions, Callback$1 as Callback, CustomFunctionCode, DeviceIdentification,
|
|
769
|
+
export { AbstractApplicationLayer, AbstractPhysicalConnection, AbstractPhysicalLayer, AsciiApplicationLayer, COIL_OFF, COIL_ON, ConformityLevel, EMPTY_BUFFER, EXCEPTION_OFFSET, ErrorCode, FunctionCode, LIMITS, MEI_READ_DEVICE_ID, MasterSession, ModbusError, ModbusMaster, ModbusSlave, PhysicalConnectionState, PhysicalState, ReadDeviceIDCode, RtuApplicationLayer, SerialPhysicalLayer, TcpApplicationLayer, TcpClientPhysicalLayer, TcpServerPhysicalLayer, UdpClientPhysicalLayer, UdpServerPhysicalLayer, createPhysicalLayer, getCodeByError, getErrorByCode };
|
|
770
|
+
export type { AbstractPhysicalLayerEvents, ApplicationDataUnit, AsciiApplicationLayerOptions, Callback$1 as Callback, CustomFunctionCode, DeviceIdentification, MaybeAsyncFunction, ModbusMasterOptions, ModbusSlaveModel, ModbusSlaveOptions, OpenArgs, PhysicalConfig, RtuApplicationLayerOptions, ServerId, TcpServerPhysicalLayerOptions, UdpServerPhysicalLayerOptions };
|