njs-modbus 3.3.0 → 3.4.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 +177 -131
- package/README.zh-CN.md +177 -130
- package/dist/index.cjs +715 -519
- package/dist/index.d.ts +86 -61
- package/dist/index.mjs +715 -519
- package/dist/utils.cjs +53 -25
- package/dist/utils.d.ts +15 -14
- package/dist/utils.mjs +49 -24
- package/package.json +3 -9
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ interface ServerId {
|
|
|
15
15
|
/** Server ID as a byte array (e.g. single-byte IDs use `[id]`). */
|
|
16
16
|
serverId?: number[];
|
|
17
17
|
runIndicatorStatus?: boolean;
|
|
18
|
-
|
|
18
|
+
/** Additional data bytes. Using Buffer avoids intermediate array conversions. */
|
|
19
|
+
additionalData?: Buffer;
|
|
19
20
|
}
|
|
20
21
|
interface DeviceIdentification {
|
|
21
22
|
readDeviceIDCode: number;
|
|
@@ -39,7 +40,8 @@ interface DeviceIdentification {
|
|
|
39
40
|
* (PDU + 2-byte CRC) from leading bytes; they are required so the framing FSM
|
|
40
41
|
* can advance without the deleted sliding-window CRC fallback.
|
|
41
42
|
*
|
|
42
|
-
* Return `
|
|
43
|
+
* Return `0` (`PREDICT_NEED_MORE`) to signal "need more bytes before I can decide".
|
|
44
|
+
* Return `-1` (`PREDICT_UNKNOWN`) to signal "cannot determine the length".
|
|
43
45
|
* Return a positive integer (>= 4, <= 256) for the total frame length.
|
|
44
46
|
*/
|
|
45
47
|
interface CustomFunctionCode {
|
|
@@ -47,29 +49,25 @@ interface CustomFunctionCode {
|
|
|
47
49
|
/**
|
|
48
50
|
* Predict total RTU frame length for an incoming request (slave-side framing).
|
|
49
51
|
*
|
|
50
|
-
* @param
|
|
51
|
-
*
|
|
52
|
-
* @param
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* `end - start` as available bytes, NOT `buffer.length` (pool capacity).
|
|
57
|
-
* @returns Total frame length (>= 4, <= 256), or `null` if more bytes are needed.
|
|
52
|
+
* @param getByte — Zero-based accessor; `getByte(i)` returns the byte at offset
|
|
53
|
+
* `i` within the candidate frame (0 = unit ID, 1 = function code, …).
|
|
54
|
+
* @param length — Number of bytes available so far. Use this for bounds checks
|
|
55
|
+
* rather than any buffer property.
|
|
56
|
+
* @returns Total frame length (>= 4, <= 256), `0` if more bytes are needed,
|
|
57
|
+
* or `-1` if the length cannot be determined.
|
|
58
58
|
*/
|
|
59
|
-
predictRequestLength: (
|
|
59
|
+
predictRequestLength: (getByte: (idx: number) => number, length: number) => number;
|
|
60
60
|
/**
|
|
61
61
|
* Predict total RTU frame length for an incoming response (master-side framing).
|
|
62
62
|
*
|
|
63
|
-
* @param
|
|
64
|
-
*
|
|
65
|
-
* @param
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* `end - start` as available bytes, NOT `buffer.length` (pool capacity).
|
|
70
|
-
* @returns Total frame length (>= 4, <= 256), or `null` if more bytes are needed.
|
|
63
|
+
* @param getByte — Zero-based accessor; `getByte(i)` returns the byte at offset
|
|
64
|
+
* `i` within the candidate frame (0 = unit ID, 1 = function code, …).
|
|
65
|
+
* @param length — Number of bytes available so far. Use this for bounds checks
|
|
66
|
+
* rather than any buffer property.
|
|
67
|
+
* @returns Total frame length (>= 4, <= 256), `0` if more bytes are needed,
|
|
68
|
+
* or `-1` if the length cannot be determined.
|
|
71
69
|
*/
|
|
72
|
-
predictResponseLength: (
|
|
70
|
+
predictResponseLength: (getByte: (idx: number) => number, length: number) => number;
|
|
73
71
|
/**
|
|
74
72
|
* Slave-side handler. Receives PDU payload (bytes after `fc`, before CRC) and
|
|
75
73
|
* the unit ID being addressed; must return the PDU payload of the response.
|
|
@@ -318,6 +316,18 @@ declare class UdpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
|
318
316
|
interface AbstractPhysicalConnectionEvents {
|
|
319
317
|
data: [data: Buffer];
|
|
320
318
|
close: [];
|
|
319
|
+
/**
|
|
320
|
+
* Emitted when raw data has been successfully written to the wire.
|
|
321
|
+
* The `buffer` is a live reference — mutating it will corrupt the frame
|
|
322
|
+
* that the connection is still processing. Treat it as read-only.
|
|
323
|
+
*/
|
|
324
|
+
tx: [buffer: Buffer];
|
|
325
|
+
/**
|
|
326
|
+
* Emitted when raw data is received from the wire.
|
|
327
|
+
* The `buffer` is a live reference — mutating it will corrupt the frame
|
|
328
|
+
* that the application layer is about to parse. Treat it as read-only.
|
|
329
|
+
*/
|
|
330
|
+
rx: [buffer: Buffer];
|
|
321
331
|
}
|
|
322
332
|
/**
|
|
323
333
|
* A one-way data transmission channel.
|
|
@@ -337,6 +347,28 @@ interface AbstractPhysicalLayerEvents {
|
|
|
337
347
|
close: [];
|
|
338
348
|
error: [error: Error];
|
|
339
349
|
}
|
|
350
|
+
/** Debug events emitted by individual connections and proxied through Master/Slave. */
|
|
351
|
+
interface ConnectionDebugEvents {
|
|
352
|
+
/**
|
|
353
|
+
* Emitted when raw data has been successfully written to the wire.
|
|
354
|
+
* The `buffer` is a live reference — mutating it will corrupt the frame
|
|
355
|
+
* that the connection is still processing. Treat it as read-only.
|
|
356
|
+
*/
|
|
357
|
+
tx: [buffer: Buffer, connection: AbstractPhysicalConnection];
|
|
358
|
+
/**
|
|
359
|
+
* Emitted when raw data is received from the wire.
|
|
360
|
+
* The `buffer` is a live reference — mutating it will corrupt the frame
|
|
361
|
+
* that the application layer is about to parse. Treat it as read-only.
|
|
362
|
+
*/
|
|
363
|
+
rx: [buffer: Buffer, connection: AbstractPhysicalConnection];
|
|
364
|
+
}
|
|
365
|
+
/** Application-layer framing events emitted by Master/Slave per connection. */
|
|
366
|
+
interface ConnectionApplicationEvents {
|
|
367
|
+
framing: [frame: ApplicationDataUnit & {
|
|
368
|
+
buffer: Buffer;
|
|
369
|
+
}, connection: AbstractPhysicalConnection];
|
|
370
|
+
framingError: [error: Error, connection: AbstractPhysicalConnection];
|
|
371
|
+
}
|
|
340
372
|
/**
|
|
341
373
|
* An abstraction over local hardware or network resources.
|
|
342
374
|
*
|
|
@@ -442,7 +474,6 @@ interface AsciiApplicationLayerOptions {
|
|
|
442
474
|
declare class AsciiApplicationLayer extends AbstractApplicationLayer {
|
|
443
475
|
readonly PROTOCOL: "ASCII";
|
|
444
476
|
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
445
|
-
readonly lenientHex: boolean;
|
|
446
477
|
private _connection;
|
|
447
478
|
private _state;
|
|
448
479
|
private _cleanupCbs;
|
|
@@ -459,34 +490,29 @@ interface RtuApplicationLayerOptions {
|
|
|
459
490
|
/** Inter-character timeout in milliseconds (Modbus RTU t1.5). Opt-in. */
|
|
460
491
|
interCharTimeout?: number;
|
|
461
492
|
/**
|
|
462
|
-
*
|
|
463
|
-
*
|
|
464
|
-
*
|
|
493
|
+
* Enforces strict Modbus RTU timing. When true, any frame containing a t1.5
|
|
494
|
+
* inter-character timeout event will be discarded immediately, even if the CRC16 is valid.
|
|
495
|
+
* @default false
|
|
465
496
|
*/
|
|
466
|
-
|
|
497
|
+
strictTiming?: boolean;
|
|
467
498
|
}
|
|
468
499
|
declare class RtuApplicationLayer extends AbstractApplicationLayer {
|
|
469
500
|
readonly PROTOCOL: "RTU";
|
|
470
501
|
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
471
502
|
private _connection;
|
|
472
|
-
private
|
|
473
|
-
private
|
|
474
|
-
private
|
|
475
|
-
private
|
|
503
|
+
private _residual;
|
|
504
|
+
private _residualLen;
|
|
505
|
+
private _expectedLen;
|
|
506
|
+
private _t15Time;
|
|
507
|
+
private _t35Time;
|
|
508
|
+
private _t15Strict;
|
|
509
|
+
private _t15Timer?;
|
|
510
|
+
private _t35Timer?;
|
|
511
|
+
private _t15Marker;
|
|
476
512
|
private _customFunctionCodes;
|
|
477
513
|
private _cleanupCbs;
|
|
478
514
|
get connection(): AbstractPhysicalConnection;
|
|
479
515
|
constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection, options?: RtuApplicationLayerOptions);
|
|
480
|
-
private clearStateTimers;
|
|
481
|
-
/**
|
|
482
|
-
* Shared handler for every "frame is not yet complete" exit in `flushBuffer`.
|
|
483
|
-
* Returns `true` when the caller should `return` (strict reset), `false` to
|
|
484
|
-
* `break` the parse loop. Hot path never reaches here — only error/incomplete
|
|
485
|
-
* edges. Extracted as a method so it is not recreated on every `flushBuffer`
|
|
486
|
-
* call.
|
|
487
|
-
*/
|
|
488
|
-
private _handleIncomplete;
|
|
489
|
-
private flushBuffer;
|
|
490
516
|
flush(): void;
|
|
491
517
|
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
492
518
|
removeCustomFunctionCode(fc: number): void;
|
|
@@ -498,12 +524,12 @@ declare class TcpApplicationLayer extends AbstractApplicationLayer {
|
|
|
498
524
|
readonly ROLE: 'MASTER' | 'SLAVE';
|
|
499
525
|
private _connection;
|
|
500
526
|
private _transactionId;
|
|
501
|
-
private
|
|
527
|
+
private _residual;
|
|
528
|
+
private _residualLen;
|
|
529
|
+
private _expectedLen;
|
|
502
530
|
private _cleanupCbs;
|
|
503
531
|
get connection(): AbstractPhysicalConnection;
|
|
504
532
|
constructor(role: 'MASTER' | 'SLAVE', connection: AbstractPhysicalConnection);
|
|
505
|
-
private tryExtract;
|
|
506
|
-
private processFrame;
|
|
507
533
|
flush(): void;
|
|
508
534
|
encode(unit: number, fc: number, data: Buffer, transaction?: number): Buffer;
|
|
509
535
|
}
|
|
@@ -549,11 +575,12 @@ interface RtuProtocolOptions {
|
|
|
549
575
|
*/
|
|
550
576
|
interCharTimeout?: RtuTimingValue;
|
|
551
577
|
/**
|
|
552
|
-
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
578
|
+
* Enforces strict Modbus RTU timing. When true, any frame containing a t1.5
|
|
579
|
+
* inter-character timeout event will be discarded immediately, even if the
|
|
580
|
+
* CRC16 is valid.
|
|
581
|
+
* @default false
|
|
555
582
|
*/
|
|
556
|
-
|
|
583
|
+
strictTiming?: boolean;
|
|
557
584
|
}
|
|
558
585
|
|
|
559
586
|
interface ReturnValue<T> {
|
|
@@ -583,7 +610,7 @@ interface ModbusMasterOptions {
|
|
|
583
610
|
opts?: AsciiApplicationLayerOptions;
|
|
584
611
|
};
|
|
585
612
|
}
|
|
586
|
-
declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
613
|
+
declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions> extends EventEmitter<AbstractPhysicalLayerEvents & ConnectionDebugEvents & ConnectionApplicationEvents> {
|
|
587
614
|
readonly timeout: number;
|
|
588
615
|
readonly concurrent: boolean;
|
|
589
616
|
private _masterSession;
|
|
@@ -617,10 +644,10 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
|
|
|
617
644
|
private writeFC1Or2;
|
|
618
645
|
writeFC1: this['readCoils'];
|
|
619
646
|
readCoils(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
620
|
-
readCoils(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<
|
|
647
|
+
readCoils(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<Uint8Array>>;
|
|
621
648
|
writeFC2: this['readDiscreteInputs'];
|
|
622
649
|
readDiscreteInputs(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
623
|
-
readDiscreteInputs(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<
|
|
650
|
+
readDiscreteInputs(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<Uint8Array>>;
|
|
624
651
|
private writeFC3Or4;
|
|
625
652
|
writeFC3: this['readHoldingRegisters'];
|
|
626
653
|
readHoldingRegisters(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
@@ -629,14 +656,14 @@ declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions>
|
|
|
629
656
|
readInputRegisters(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
630
657
|
readInputRegisters(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<number[]>>;
|
|
631
658
|
writeFC5: this['writeSingleCoil'];
|
|
632
|
-
writeSingleCoil(unit: 0, address: number, value:
|
|
633
|
-
writeSingleCoil(unit: number, address: number, value:
|
|
659
|
+
writeSingleCoil(unit: 0, address: number, value: number, timeout?: number): Promise<void>;
|
|
660
|
+
writeSingleCoil(unit: number, address: number, value: number, timeout?: number): Promise<ReturnValue<number>>;
|
|
634
661
|
writeFC6: this['writeSingleRegister'];
|
|
635
662
|
writeSingleRegister(unit: 0, address: number, value: number, timeout?: number): Promise<void>;
|
|
636
663
|
writeSingleRegister(unit: number, address: number, value: number, timeout?: number): Promise<ReturnValue<number>>;
|
|
637
664
|
writeFC15: this['writeMultipleCoils'];
|
|
638
|
-
writeMultipleCoils(unit: 0, address: number, value:
|
|
639
|
-
writeMultipleCoils(unit: number, address: number, value:
|
|
665
|
+
writeMultipleCoils(unit: 0, address: number, value: Uint8Array, timeout?: number): Promise<void>;
|
|
666
|
+
writeMultipleCoils(unit: number, address: number, value: Uint8Array, timeout?: number): Promise<ReturnValue<Uint8Array>>;
|
|
640
667
|
writeFC16: this['writeMultipleRegisters'];
|
|
641
668
|
writeMultipleRegisters(unit: 0, address: number, value: number[], timeout?: number): Promise<void>;
|
|
642
669
|
writeMultipleRegisters(unit: number, address: number, value: number[], timeout?: number): Promise<ReturnValue<number[]>>;
|
|
@@ -717,15 +744,13 @@ interface ModbusSlaveModel {
|
|
|
717
744
|
* Otherwise keep the default read and write behavior.
|
|
718
745
|
*/
|
|
719
746
|
interceptor?: MaybeAsyncFunction<(fc: number, data: Buffer) => Buffer | undefined>;
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
readCoils?: MaybeAsyncFunction<(address: number, length: number) => boolean[] | Uint8Array>;
|
|
724
|
-
writeSingleCoil?: MaybeAsyncFunction<(address: number, value: boolean) => void>;
|
|
747
|
+
readDiscreteInputs?: MaybeAsyncFunction<(address: number, length: number) => Uint8Array>;
|
|
748
|
+
readCoils?: MaybeAsyncFunction<(address: number, length: number) => Uint8Array>;
|
|
749
|
+
writeSingleCoil?: MaybeAsyncFunction<(address: number, value: number) => void>;
|
|
725
750
|
/**
|
|
726
751
|
* If omitted, defaults to loop and call `writeSingleCoil`.
|
|
727
752
|
*/
|
|
728
|
-
writeMultipleCoils?: MaybeAsyncFunction<(address: number, value:
|
|
753
|
+
writeMultipleCoils?: MaybeAsyncFunction<(address: number, value: Uint8Array) => void>;
|
|
729
754
|
/** Return `Uint16Array` to avoid the `Array.from` allocation overhead. */
|
|
730
755
|
readInputRegisters?: MaybeAsyncFunction<(address: number, length: number) => number[] | Uint16Array>;
|
|
731
756
|
/** Return `Uint16Array` to avoid the `Array.from` allocation overhead. */
|
|
@@ -768,7 +793,7 @@ interface ModbusSlaveOptions {
|
|
|
768
793
|
opts?: AsciiApplicationLayerOptions;
|
|
769
794
|
};
|
|
770
795
|
}
|
|
771
|
-
declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
796
|
+
declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> extends EventEmitter<AbstractPhysicalLayerEvents & ConnectionDebugEvents & ConnectionApplicationEvents> {
|
|
772
797
|
readonly models: Map<number, ModbusSlaveModel>;
|
|
773
798
|
readonly concurrent: boolean;
|
|
774
799
|
private _physicalLayer;
|
|
@@ -839,4 +864,4 @@ declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> ext
|
|
|
839
864
|
}
|
|
840
865
|
|
|
841
866
|
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, NOOP, PhysicalConnectionState, PhysicalState, ReadDeviceIDCode, RtuApplicationLayer, SerialPhysicalLayer, TcpApplicationLayer, TcpClientPhysicalLayer, TcpServerPhysicalLayer, UdpClientPhysicalLayer, UdpServerPhysicalLayer, createPhysicalLayer, getCodeByError, getErrorByCode };
|
|
842
|
-
export type { AbstractPhysicalLayerEvents, ApplicationDataUnit, AsciiApplicationLayerOptions, Callback$1 as Callback, CustomFunctionCode, DeviceIdentification, MaybeAsyncFunction, ModbusMasterOptions, ModbusSlaveModel, ModbusSlaveOptions, OpenArgs, PhysicalConfig, RtuApplicationLayerOptions, ServerId, TcpServerPhysicalLayerOptions, UdpServerPhysicalLayerOptions };
|
|
867
|
+
export type { AbstractPhysicalLayerEvents, ApplicationDataUnit, AsciiApplicationLayerOptions, Callback$1 as Callback, ConnectionApplicationEvents, ConnectionDebugEvents, CustomFunctionCode, DeviceIdentification, MaybeAsyncFunction, ModbusMasterOptions, ModbusSlaveModel, ModbusSlaveOptions, OpenArgs, PhysicalConfig, RtuApplicationLayerOptions, ServerId, TcpServerPhysicalLayerOptions, UdpServerPhysicalLayerOptions };
|