njs-modbus 3.1.0 → 3.2.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 +20 -0
- package/README.zh-CN.md +20 -0
- package/dist/index.cjs +878 -390
- package/dist/index.d.ts +96 -30
- package/dist/index.mjs +878 -391
- package/dist/utils.cjs +439 -0
- package/dist/utils.d.ts +161 -0
- package/dist/utils.mjs +425 -0
- package/package.json +16 -3
- package/dist/src/error-code.d.ts +0 -17
- package/dist/src/index.d.ts +0 -7
- package/dist/src/layers/application/abstract-application-layer.d.ts +0 -26
- package/dist/src/layers/application/ascii-application-layer.d.ts +0 -23
- package/dist/src/layers/application/index.d.ts +0 -6
- package/dist/src/layers/application/rtu-application-layer.d.ts +0 -34
- package/dist/src/layers/application/tcp-application-layer.d.ts +0 -16
- package/dist/src/layers/physical/abstract-physical-layer.d.ts +0 -50
- package/dist/src/layers/physical/index.d.ts +0 -12
- package/dist/src/layers/physical/serial-physical-layer.d.ts +0 -70
- package/dist/src/layers/physical/tcp-client-physical-layer.d.ts +0 -19
- package/dist/src/layers/physical/tcp-physical-connection.d.ts +0 -16
- package/dist/src/layers/physical/tcp-server-physical-layer.d.ts +0 -28
- package/dist/src/layers/physical/udp-client-physical-layer.d.ts +0 -33
- package/dist/src/layers/physical/udp-server-physical-layer.d.ts +0 -50
- package/dist/src/layers/physical/utils.d.ts +0 -39
- package/dist/src/layers/physical/vars.d.ts +0 -11
- package/dist/src/master/index.d.ts +0 -3
- package/dist/src/master/master-session.d.ts +0 -18
- package/dist/src/master/master.d.ts +0 -140
- package/dist/src/slave/index.d.ts +0 -2
- package/dist/src/slave/slave.d.ts +0 -119
- package/dist/src/types.d.ts +0 -54
- package/dist/src/utils/bitsToMs.d.ts +0 -13
- package/dist/src/utils/callback.d.ts +0 -8
- package/dist/src/utils/checkRange.d.ts +0 -1
- package/dist/src/utils/crc.d.ts +0 -1
- package/dist/src/utils/index.d.ts +0 -11
- package/dist/src/utils/isUint8.d.ts +0 -8
- package/dist/src/utils/lrc.d.ts +0 -1
- package/dist/src/utils/predictRtuFrameLength.d.ts +0 -17
- package/dist/src/utils/promisify-cb.d.ts +0 -4
- package/dist/src/utils/rtu-timing.d.ts +0 -63
- package/dist/src/utils/whitelist.d.ts +0 -11
- package/dist/src/vars.d.ts +0 -49
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { SerialPort } from 'serialport';
|
|
2
|
-
import { AbstractPhysicalConnection, AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
3
|
-
import { PhysicalConnectionState, PhysicalState } from './vars';
|
|
4
|
-
export interface SerialPhysicalLayerOptions {
|
|
5
|
-
/** The system path of the serial port you want to open. For example, `/dev/tty.XXX` on Mac/Linux, or `COM1` on Windows */
|
|
6
|
-
path: string;
|
|
7
|
-
/**
|
|
8
|
-
* 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.
|
|
9
|
-
*/
|
|
10
|
-
baudRate: number;
|
|
11
|
-
/** Must be one of these: 5, 6, 7, or 8. Defaults to 8 */
|
|
12
|
-
dataBits?: 5 | 6 | 7 | 8;
|
|
13
|
-
/** Prevent other processes from opening the port. Windows does not currently support `false`. Defaults to true */
|
|
14
|
-
lock?: boolean;
|
|
15
|
-
/** Must be 1, 1.5 or 2. Defaults to 1 */
|
|
16
|
-
stopBits?: 1 | 1.5 | 2;
|
|
17
|
-
/** Device parity. Defaults to none */
|
|
18
|
-
parity?: 'none' | 'even' | 'odd' | 'mark' | 'space';
|
|
19
|
-
/** Flow control Setting. Defaults to false */
|
|
20
|
-
rtscts?: boolean;
|
|
21
|
-
/** Flow control Setting. Defaults to false */
|
|
22
|
-
xon?: boolean;
|
|
23
|
-
/** Flow control Setting. Defaults to false */
|
|
24
|
-
xoff?: boolean;
|
|
25
|
-
/** Flow control Setting. Defaults to false */
|
|
26
|
-
xany?: boolean;
|
|
27
|
-
/** drop DTR on close. Defaults to true */
|
|
28
|
-
hupcl?: boolean;
|
|
29
|
-
/** The size of the read and write buffers. Defaults to 64k */
|
|
30
|
-
highWaterMark?: number;
|
|
31
|
-
/** Emit 'end' on port close. Defaults to false */
|
|
32
|
-
endOnClose?: boolean;
|
|
33
|
-
/** see `man termios`. Defaults to 1 (Darwin/Linux only) */
|
|
34
|
-
vmin?: number;
|
|
35
|
-
/** see `man termios`. Defaults to 0 (Darwin/Linux only) */
|
|
36
|
-
vtime?: number;
|
|
37
|
-
/** RTS mode. Defaults to handshake (Windows only) */
|
|
38
|
-
rtsMode?: 'handshake' | 'enable' | 'toggle';
|
|
39
|
-
}
|
|
40
|
-
export declare class SerialPhysicalConnection extends AbstractPhysicalConnection {
|
|
41
|
-
private _state;
|
|
42
|
-
private _physicalLayer;
|
|
43
|
-
private _serialport;
|
|
44
|
-
private _pendingDestroyCbs;
|
|
45
|
-
private _cleanupFns;
|
|
46
|
-
get state(): PhysicalConnectionState;
|
|
47
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
48
|
-
constructor(physicalLayer: SerialPhysicalLayer, serialport: SerialPort);
|
|
49
|
-
write(data: Buffer, cb?: (err?: Error | null) => void): void;
|
|
50
|
-
destroy(cb?: (err?: Error | null) => void): void;
|
|
51
|
-
}
|
|
52
|
-
export declare class SerialPhysicalLayer extends AbstractPhysicalLayer {
|
|
53
|
-
readonly TYPE: "SERIAL";
|
|
54
|
-
private _state;
|
|
55
|
-
private _connections;
|
|
56
|
-
private _serialport;
|
|
57
|
-
private _serialportOpts;
|
|
58
|
-
private _path;
|
|
59
|
-
private _baudRate;
|
|
60
|
-
private _pendingOpenCbs;
|
|
61
|
-
private _pendingCloseCbs;
|
|
62
|
-
private _cleanupFns;
|
|
63
|
-
get state(): PhysicalState;
|
|
64
|
-
get serialport(): SerialPort | null;
|
|
65
|
-
get path(): string;
|
|
66
|
-
get baudRate(): number;
|
|
67
|
-
constructor(options: SerialPhysicalLayerOptions);
|
|
68
|
-
open(cb?: (err?: Error | null) => void): void;
|
|
69
|
-
close(cb?: (err?: Error | null) => void): void;
|
|
70
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { SocketConstructorOpts, SocketConnectOpts } from 'node:net';
|
|
2
|
-
import { Socket } from 'node:net';
|
|
3
|
-
import { AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
4
|
-
import { PhysicalState } from './vars';
|
|
5
|
-
export declare class TcpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
6
|
-
readonly TYPE: "TCP_CLIENT";
|
|
7
|
-
private _state;
|
|
8
|
-
private _connections;
|
|
9
|
-
private _socket;
|
|
10
|
-
private _socketOpts?;
|
|
11
|
-
private _pendingOpenCbs;
|
|
12
|
-
private _pendingCloseCbs;
|
|
13
|
-
private _cleanupFns;
|
|
14
|
-
get state(): PhysicalState;
|
|
15
|
-
get socket(): Socket | null;
|
|
16
|
-
constructor(options?: SocketConstructorOpts);
|
|
17
|
-
open(options?: SocketConnectOpts | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
18
|
-
close(cb?: (err?: Error | null) => void): void;
|
|
19
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
2
|
-
import type { Socket } from 'node:net';
|
|
3
|
-
import { AbstractPhysicalConnection } from './abstract-physical-layer';
|
|
4
|
-
import { PhysicalConnectionState } from './vars';
|
|
5
|
-
export declare class TcpPhysicalConnection extends AbstractPhysicalConnection {
|
|
6
|
-
private _state;
|
|
7
|
-
private _physicalLayer;
|
|
8
|
-
private _socket;
|
|
9
|
-
private _pendingDestroyCbs;
|
|
10
|
-
private _cleanupFns;
|
|
11
|
-
get state(): PhysicalConnectionState;
|
|
12
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
13
|
-
constructor(physicalLayer: AbstractPhysicalLayer, socket: Socket);
|
|
14
|
-
write(data: Buffer, cb?: (err?: Error | null) => void): void;
|
|
15
|
-
destroy(cb?: (err?: Error | null) => void): void;
|
|
16
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { Server, ListenOptions, ServerOpts } from 'node:net';
|
|
2
|
-
import { AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
3
|
-
import { PhysicalState } from './vars';
|
|
4
|
-
export interface TcpServerPhysicalLayerOptions {
|
|
5
|
-
/** Allowed client IP addresses. IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1) are normalized before checking. */
|
|
6
|
-
whitelist?: string[];
|
|
7
|
-
/** Maximum number of concurrent connections. When exceeded, new connections are silently dropped by Node.js. */
|
|
8
|
-
maxConnections?: number;
|
|
9
|
-
/** Idle timeout in ms. Connection is destroyed if no data is received within this time. 0 = disabled. */
|
|
10
|
-
idleTimeout?: number;
|
|
11
|
-
/** Forwarded to `net.createServer()`. */
|
|
12
|
-
serverOpts?: ServerOpts;
|
|
13
|
-
}
|
|
14
|
-
export declare class TcpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
15
|
-
readonly TYPE: "TCP_SERVER";
|
|
16
|
-
private _state;
|
|
17
|
-
private _connections;
|
|
18
|
-
private _server;
|
|
19
|
-
private _opts;
|
|
20
|
-
private _pendingOpenCbs;
|
|
21
|
-
private _pendingCloseCbs;
|
|
22
|
-
private _cleanupFns;
|
|
23
|
-
get state(): PhysicalState;
|
|
24
|
-
get server(): Server | null;
|
|
25
|
-
constructor(options?: TcpServerPhysicalLayerOptions);
|
|
26
|
-
open(options?: ListenOptions | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
27
|
-
close(cb?: (err?: Error | null) => void): void;
|
|
28
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { Socket, SocketOptions } from 'node:dgram';
|
|
2
|
-
import { AbstractPhysicalConnection, AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
3
|
-
import { PhysicalConnectionState, PhysicalState } from './vars';
|
|
4
|
-
export declare class UdpClientPhysicalConnection extends AbstractPhysicalConnection {
|
|
5
|
-
private _state;
|
|
6
|
-
private _physicalLayer;
|
|
7
|
-
private _socket;
|
|
8
|
-
private _pendingDestroyCbs;
|
|
9
|
-
private _cleanupFns;
|
|
10
|
-
get state(): PhysicalConnectionState;
|
|
11
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
12
|
-
constructor(physicalLayer: UdpClientPhysicalLayer, socket: Socket);
|
|
13
|
-
write(data: Buffer, cb?: (err?: Error | null) => void): void;
|
|
14
|
-
destroy(cb?: (err?: Error | null) => void): void;
|
|
15
|
-
}
|
|
16
|
-
export declare class UdpClientPhysicalLayer extends AbstractPhysicalLayer {
|
|
17
|
-
readonly TYPE: "UDP_CLIENT";
|
|
18
|
-
private _state;
|
|
19
|
-
private _connections;
|
|
20
|
-
private _socket;
|
|
21
|
-
private _socketOpts;
|
|
22
|
-
private _pendingOpenCbs;
|
|
23
|
-
private _pendingCloseCbs;
|
|
24
|
-
private _cleanupFns;
|
|
25
|
-
get state(): PhysicalState;
|
|
26
|
-
get socket(): Socket | null;
|
|
27
|
-
constructor(options?: Partial<SocketOptions>);
|
|
28
|
-
open(remote?: {
|
|
29
|
-
port?: number;
|
|
30
|
-
address?: string;
|
|
31
|
-
} | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
32
|
-
close(cb?: (err?: Error | null) => void): void;
|
|
33
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { BindOptions, RemoteInfo, Socket, SocketOptions } from 'node:dgram';
|
|
2
|
-
import { AbstractPhysicalConnection, AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
3
|
-
import { PhysicalConnectionState, PhysicalState } from './vars';
|
|
4
|
-
export interface UdpServerPhysicalLayerOptions {
|
|
5
|
-
/** Allowed client IP addresses. IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1) are normalized before checking. */
|
|
6
|
-
whitelist?: string[];
|
|
7
|
-
/** Maximum number of concurrent virtual client connections. When exceeded, datagrams from new clients are silently ignored. */
|
|
8
|
-
maxConnections?: number;
|
|
9
|
-
/** Connection idle timeout in ms. Pass `0` to disable eviction. Defaults to 30000. */
|
|
10
|
-
idleTimeout?: number;
|
|
11
|
-
/** Forwarded to `dgram.createSocket()`. */
|
|
12
|
-
socketOpts?: Partial<SocketOptions>;
|
|
13
|
-
}
|
|
14
|
-
export declare class UdpServerPhysicalConnection extends AbstractPhysicalConnection {
|
|
15
|
-
private _state;
|
|
16
|
-
private _physicalLayer;
|
|
17
|
-
private _socket;
|
|
18
|
-
private _remote;
|
|
19
|
-
private _idleTid;
|
|
20
|
-
private _cleanupFns;
|
|
21
|
-
get state(): PhysicalConnectionState;
|
|
22
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
23
|
-
constructor(physicalLayer: UdpServerPhysicalLayer, socket: Socket, remote: RemoteInfo, idleTimeout: number, messageEventDelegation: {
|
|
24
|
-
add: (listener: (msg: Buffer, rinfo: RemoteInfo) => void) => void;
|
|
25
|
-
remove: (listener: (...args: any[]) => void) => void;
|
|
26
|
-
});
|
|
27
|
-
write(data: Buffer, cb?: (err?: Error | null) => void): void;
|
|
28
|
-
destroy(cb?: (err?: Error | null) => void): void;
|
|
29
|
-
}
|
|
30
|
-
export declare class UdpServerPhysicalLayer extends AbstractPhysicalLayer {
|
|
31
|
-
readonly TYPE: "UDP_SERVER";
|
|
32
|
-
private _state;
|
|
33
|
-
private _connections;
|
|
34
|
-
private _socket;
|
|
35
|
-
private _opts;
|
|
36
|
-
private _pendingOpenCbs;
|
|
37
|
-
private _pendingCloseCbs;
|
|
38
|
-
private _cleanupFns;
|
|
39
|
-
get state(): PhysicalState;
|
|
40
|
-
get socket(): Socket | null;
|
|
41
|
-
constructor(options?: UdpServerPhysicalLayerOptions);
|
|
42
|
-
/**
|
|
43
|
-
* Bind the UDP socket and start accepting datagrams.
|
|
44
|
-
*
|
|
45
|
-
* @param options Bind options (port, address, etc.). Defaults to port 502.
|
|
46
|
-
* @param cb Callback invoked when binding completes or fails.
|
|
47
|
-
*/
|
|
48
|
-
open(options?: BindOptions | ((err?: Error | null) => void), cb?: (err?: Error | null) => void): void;
|
|
49
|
-
close(cb?: (err?: Error | null) => void): void;
|
|
50
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { AbstractPhysicalLayer } from './abstract-physical-layer';
|
|
2
|
-
import type { SocketOptions } from 'node:dgram';
|
|
3
|
-
import type { SocketConstructorOpts } from 'node:net';
|
|
4
|
-
import { SerialPhysicalLayer, type SerialPhysicalLayerOptions } from './serial-physical-layer';
|
|
5
|
-
import { TcpClientPhysicalLayer } from './tcp-client-physical-layer';
|
|
6
|
-
import { TcpServerPhysicalLayer, type TcpServerPhysicalLayerOptions } from './tcp-server-physical-layer';
|
|
7
|
-
import { UdpClientPhysicalLayer } from './udp-client-physical-layer';
|
|
8
|
-
import { UdpServerPhysicalLayer, type UdpServerPhysicalLayerOptions } from './udp-server-physical-layer';
|
|
9
|
-
export type PhysicalConfig = {
|
|
10
|
-
type: 'SERIAL';
|
|
11
|
-
opts: SerialPhysicalLayerOptions;
|
|
12
|
-
} | {
|
|
13
|
-
type: 'TCP_CLIENT';
|
|
14
|
-
socketOpts?: SocketConstructorOpts;
|
|
15
|
-
} | {
|
|
16
|
-
type: 'TCP_SERVER';
|
|
17
|
-
opts?: TcpServerPhysicalLayerOptions;
|
|
18
|
-
} | {
|
|
19
|
-
type: 'UDP_CLIENT';
|
|
20
|
-
socketOpts?: Partial<SocketOptions>;
|
|
21
|
-
} | {
|
|
22
|
-
type: 'UDP_SERVER';
|
|
23
|
-
opts?: UdpServerPhysicalLayerOptions;
|
|
24
|
-
} | {
|
|
25
|
-
type: 'CUSTOM';
|
|
26
|
-
layer: AbstractPhysicalLayer;
|
|
27
|
-
};
|
|
28
|
-
export type OpenArgs<T extends PhysicalConfig> = T extends {
|
|
29
|
-
type: 'SERIAL';
|
|
30
|
-
} ? Parameters<SerialPhysicalLayer['open']> : T extends {
|
|
31
|
-
type: 'TCP_CLIENT';
|
|
32
|
-
} ? Parameters<TcpClientPhysicalLayer['open']> : T extends {
|
|
33
|
-
type: 'TCP_SERVER';
|
|
34
|
-
} ? Parameters<TcpServerPhysicalLayer['open']> : T extends {
|
|
35
|
-
type: 'UDP_CLIENT';
|
|
36
|
-
} ? Parameters<UdpClientPhysicalLayer['open']> : T extends {
|
|
37
|
-
type: 'UDP_SERVER';
|
|
38
|
-
} ? Parameters<UdpServerPhysicalLayer['open']> : never;
|
|
39
|
-
export declare function createPhysicalLayer(config: PhysicalConfig): AbstractPhysicalLayer;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { ApplicationDataUnit } from '../types';
|
|
2
|
-
type Frame = ApplicationDataUnit & {
|
|
3
|
-
buffer: Buffer;
|
|
4
|
-
};
|
|
5
|
-
type Callback = (error: Error | null, frame?: Frame) => void;
|
|
6
|
-
export declare const FIFO_KEY: "fifo";
|
|
7
|
-
export declare class MasterSession {
|
|
8
|
-
private _waiters;
|
|
9
|
-
/** Register a callback for `key`. No timer — timeout is managed by the caller. */
|
|
10
|
-
start(key: string | number, callback: Callback): void;
|
|
11
|
-
/** Cancel a pending waiter without firing its callback. */
|
|
12
|
-
stop(key: string | number): void;
|
|
13
|
-
stopAll(error: Error): void;
|
|
14
|
-
has(key: string | number): boolean;
|
|
15
|
-
handleFrame(frame: Frame): void;
|
|
16
|
-
handleError(error: Error): void;
|
|
17
|
-
}
|
|
18
|
-
export {};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import type { AsciiApplicationLayerOptions } from '../layers/application';
|
|
2
|
-
import type { AbstractPhysicalLayer, AbstractPhysicalLayerEvents, OpenArgs, PhysicalConfig } from '../layers/physical';
|
|
3
|
-
import type { CustomFunctionCode, DeviceIdentification, ServerId } from '../types';
|
|
4
|
-
import type { RtuProtocolOptions } from '../utils';
|
|
5
|
-
import EventEmitter from 'node:events';
|
|
6
|
-
import { PhysicalState } from '../layers/physical';
|
|
7
|
-
interface ReturnValue<T> {
|
|
8
|
-
transaction?: number;
|
|
9
|
-
unit: number;
|
|
10
|
-
fc: number;
|
|
11
|
-
data: T;
|
|
12
|
-
buffer: Buffer;
|
|
13
|
-
}
|
|
14
|
-
export interface ModbusMasterOptions {
|
|
15
|
-
/** Per-request timeout in ms. Default 1000. */
|
|
16
|
-
timeout?: number;
|
|
17
|
-
/**
|
|
18
|
-
* Enable pipelined concurrent requests on a single connection.
|
|
19
|
-
* Only valid for Modbus TCP application layer.
|
|
20
|
-
* Default false (FIFO queue, requests are serialized).
|
|
21
|
-
*/
|
|
22
|
-
concurrent?: boolean;
|
|
23
|
-
physical: PhysicalConfig;
|
|
24
|
-
protocol: {
|
|
25
|
-
type: 'RTU';
|
|
26
|
-
opts?: RtuProtocolOptions;
|
|
27
|
-
} | {
|
|
28
|
-
type: 'TCP';
|
|
29
|
-
} | {
|
|
30
|
-
type: 'ASCII';
|
|
31
|
-
opts?: AsciiApplicationLayerOptions;
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export declare class ModbusMaster<T extends ModbusMasterOptions = ModbusMasterOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
35
|
-
readonly timeout: number;
|
|
36
|
-
readonly concurrent: boolean;
|
|
37
|
-
private _masterSession;
|
|
38
|
-
private _physicalLayer;
|
|
39
|
-
private _protocol;
|
|
40
|
-
private _appLayer?;
|
|
41
|
-
private _customFunctionCodes;
|
|
42
|
-
private _queueUnits;
|
|
43
|
-
private _queueFcs;
|
|
44
|
-
private _queueDatas;
|
|
45
|
-
private _queueTimeouts;
|
|
46
|
-
private _queueBroadcasts;
|
|
47
|
-
private _queueResolves;
|
|
48
|
-
private _queueRejects;
|
|
49
|
-
private _queueHead;
|
|
50
|
-
private _queueLen;
|
|
51
|
-
private _draining;
|
|
52
|
-
private _nextTid;
|
|
53
|
-
private _cleanupFns;
|
|
54
|
-
private _closePromise;
|
|
55
|
-
get state(): PhysicalState;
|
|
56
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
57
|
-
constructor(options: T);
|
|
58
|
-
private _createAppLayer;
|
|
59
|
-
private send;
|
|
60
|
-
private _drain;
|
|
61
|
-
private _processNext;
|
|
62
|
-
private _exchange;
|
|
63
|
-
private writeFC1Or2;
|
|
64
|
-
writeFC1: this['readCoils'];
|
|
65
|
-
readCoils(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
66
|
-
readCoils(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<boolean[]>>;
|
|
67
|
-
writeFC2: this['readDiscreteInputs'];
|
|
68
|
-
readDiscreteInputs(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
69
|
-
readDiscreteInputs(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<boolean[]>>;
|
|
70
|
-
private writeFC3Or4;
|
|
71
|
-
writeFC3: this['readHoldingRegisters'];
|
|
72
|
-
readHoldingRegisters(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
73
|
-
readHoldingRegisters(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<number[]>>;
|
|
74
|
-
writeFC4: this['readInputRegisters'];
|
|
75
|
-
readInputRegisters(unit: 0, address: number, length: number, timeout?: number): Promise<void>;
|
|
76
|
-
readInputRegisters(unit: number, address: number, length: number, timeout?: number): Promise<ReturnValue<number[]>>;
|
|
77
|
-
writeFC5: this['writeSingleCoil'];
|
|
78
|
-
writeSingleCoil(unit: 0, address: number, value: boolean, timeout?: number): Promise<void>;
|
|
79
|
-
writeSingleCoil(unit: number, address: number, value: boolean, timeout?: number): Promise<ReturnValue<boolean>>;
|
|
80
|
-
writeFC6: this['writeSingleRegister'];
|
|
81
|
-
writeSingleRegister(unit: 0, address: number, value: number, timeout?: number): Promise<void>;
|
|
82
|
-
writeSingleRegister(unit: number, address: number, value: number, timeout?: number): Promise<ReturnValue<number>>;
|
|
83
|
-
writeFC15: this['writeMultipleCoils'];
|
|
84
|
-
writeMultipleCoils(unit: 0, address: number, value: boolean[], timeout?: number): Promise<void>;
|
|
85
|
-
writeMultipleCoils(unit: number, address: number, value: boolean[], timeout?: number): Promise<ReturnValue<boolean[]>>;
|
|
86
|
-
writeFC16: this['writeMultipleRegisters'];
|
|
87
|
-
writeMultipleRegisters(unit: 0, address: number, value: number[], timeout?: number): Promise<void>;
|
|
88
|
-
writeMultipleRegisters(unit: number, address: number, value: number[], timeout?: number): Promise<ReturnValue<number[]>>;
|
|
89
|
-
handleFC17: this['reportServerId'];
|
|
90
|
-
reportServerId(unit: 0, serverIdLength?: number, timeout?: number): Promise<void>;
|
|
91
|
-
reportServerId(unit: number, serverIdLength?: number, timeout?: number): Promise<ReturnValue<ServerId>>;
|
|
92
|
-
handleFC22: this['maskWriteRegister'];
|
|
93
|
-
maskWriteRegister(unit: 0, address: number, andMask: number, orMask: number, timeout?: number): Promise<void>;
|
|
94
|
-
maskWriteRegister(unit: number, address: number, andMask: number, orMask: number, timeout?: number): Promise<ReturnValue<{
|
|
95
|
-
andMask: number;
|
|
96
|
-
orMask: number;
|
|
97
|
-
}>>;
|
|
98
|
-
handleFC23: this['readAndWriteMultipleRegisters'];
|
|
99
|
-
readAndWriteMultipleRegisters(unit: 0, read: {
|
|
100
|
-
address: number;
|
|
101
|
-
length: number;
|
|
102
|
-
}, write: {
|
|
103
|
-
address: number;
|
|
104
|
-
value: number[];
|
|
105
|
-
}, timeout?: number): Promise<void>;
|
|
106
|
-
readAndWriteMultipleRegisters(unit: number, read: {
|
|
107
|
-
address: number;
|
|
108
|
-
length: number;
|
|
109
|
-
}, write: {
|
|
110
|
-
address: number;
|
|
111
|
-
value: number[];
|
|
112
|
-
}, timeout?: number): Promise<ReturnValue<number[]>>;
|
|
113
|
-
handleFC43_14: this['readDeviceIdentification'];
|
|
114
|
-
readDeviceIdentification(unit: 0, readDeviceIDCode: number, objectId: number, timeout?: number): Promise<void>;
|
|
115
|
-
readDeviceIdentification(unit: number, readDeviceIDCode: number, objectId: number, timeout?: number): Promise<ReturnValue<DeviceIdentification>>;
|
|
116
|
-
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
117
|
-
removeCustomFunctionCode(fc: number): void;
|
|
118
|
-
sendCustomFC(unit: 0, fc: number, data: Buffer | number[], timeout?: number): Promise<void>;
|
|
119
|
-
sendCustomFC(unit: number, fc: number, data: Buffer | number[], timeout?: number): Promise<Buffer>;
|
|
120
|
-
/**
|
|
121
|
-
* Open the underlying physical layer and begin accepting connections.
|
|
122
|
-
*
|
|
123
|
-
* A `ModbusMaster` instance can only be opened once. Once {@link close}
|
|
124
|
-
* is called — explicitly or because the physical layer disconnected —
|
|
125
|
-
* the instance is permanently closed and cannot be reopened.
|
|
126
|
-
* Create a new `ModbusMaster` if a new connection is required.
|
|
127
|
-
*/
|
|
128
|
-
open(...args: OpenArgs<T['physical']>): Promise<void>;
|
|
129
|
-
private _close;
|
|
130
|
-
/**
|
|
131
|
-
* Permanently close the master and release all resources.
|
|
132
|
-
*
|
|
133
|
-
* After calling this method the instance is considered dead:
|
|
134
|
-
* - No further requests can be sent.
|
|
135
|
-
* - The instance cannot be reopened via {@link open}.
|
|
136
|
-
* - All event listeners registered on this master are removed.
|
|
137
|
-
*/
|
|
138
|
-
close(): Promise<void>;
|
|
139
|
-
}
|
|
140
|
-
export {};
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import type { AsciiApplicationLayerOptions } from '../layers/application';
|
|
2
|
-
import type { AbstractPhysicalLayer, AbstractPhysicalLayerEvents, OpenArgs, PhysicalConfig } from '../layers/physical';
|
|
3
|
-
import type { CustomFunctionCode, MaybeAsyncFunction, ServerId } from '../types';
|
|
4
|
-
import type { RtuProtocolOptions } from '../utils';
|
|
5
|
-
import EventEmitter from 'node:events';
|
|
6
|
-
import { PhysicalState } from '../layers/physical';
|
|
7
|
-
export interface ModbusSlaveModel {
|
|
8
|
-
unit?: number;
|
|
9
|
-
/**
|
|
10
|
-
* Intercept read and write behavior.
|
|
11
|
-
*
|
|
12
|
-
* If provide the return value, use this value as data of `PDU` to respond.
|
|
13
|
-
* Otherwise keep the default read and write behavior.
|
|
14
|
-
*/
|
|
15
|
-
interceptor?: MaybeAsyncFunction<(fc: number, data: Buffer) => Buffer | undefined>;
|
|
16
|
-
readDiscreteInputs?: MaybeAsyncFunction<(address: number, length: number) => boolean[]>;
|
|
17
|
-
readCoils?: MaybeAsyncFunction<(address: number, length: number) => boolean[]>;
|
|
18
|
-
writeSingleCoil?: MaybeAsyncFunction<(address: number, value: boolean) => void>;
|
|
19
|
-
/**
|
|
20
|
-
* If omitted, defaults to loop and call `writeSingleCoil`.
|
|
21
|
-
*/
|
|
22
|
-
writeMultipleCoils?: MaybeAsyncFunction<(address: number, value: boolean[]) => void>;
|
|
23
|
-
readInputRegisters?: MaybeAsyncFunction<(address: number, length: number) => number[]>;
|
|
24
|
-
readHoldingRegisters?: MaybeAsyncFunction<(address: number, length: number) => number[]>;
|
|
25
|
-
writeSingleRegister?: MaybeAsyncFunction<(address: number, value: number) => void>;
|
|
26
|
-
/**
|
|
27
|
-
* If omitted, defaults to loop and call `writeSingleRegister`.
|
|
28
|
-
*/
|
|
29
|
-
writeMultipleRegisters?: MaybeAsyncFunction<(address: number, value: number[]) => void>;
|
|
30
|
-
/**
|
|
31
|
-
* If omitted, defaults to call `readHoldingRegisters` and `writeSingleRegister`.
|
|
32
|
-
*/
|
|
33
|
-
maskWriteRegister?: MaybeAsyncFunction<(address: number, andMask: number, orMask: number) => void>;
|
|
34
|
-
reportServerId?: MaybeAsyncFunction<() => ServerId>;
|
|
35
|
-
readDeviceIdentification?: MaybeAsyncFunction<() => {
|
|
36
|
-
[index: number]: string;
|
|
37
|
-
}>;
|
|
38
|
-
getAddressRange?: () => {
|
|
39
|
-
discreteInputs?: [number, number] | [number, number][];
|
|
40
|
-
coils?: [number, number] | [number, number][];
|
|
41
|
-
inputRegisters?: [number, number] | [number, number][];
|
|
42
|
-
holdingRegisters?: [number, number] | [number, number][];
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
export interface ModbusSlaveOptions {
|
|
46
|
-
/**
|
|
47
|
-
* Pipelined concurrent processing of requests within one connection.
|
|
48
|
-
* Only valid for Modbus TCP application layer (TID disambiguates responses).
|
|
49
|
-
* Default false — per-connection FIFO. RTU/ASCII + concurrent=true throws.
|
|
50
|
-
*/
|
|
51
|
-
concurrent?: boolean;
|
|
52
|
-
physical: PhysicalConfig;
|
|
53
|
-
protocol: {
|
|
54
|
-
type: 'RTU';
|
|
55
|
-
opts?: RtuProtocolOptions;
|
|
56
|
-
} | {
|
|
57
|
-
type: 'TCP';
|
|
58
|
-
} | {
|
|
59
|
-
type: 'ASCII';
|
|
60
|
-
opts?: AsciiApplicationLayerOptions;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
export declare class ModbusSlave<T extends ModbusSlaveOptions = ModbusSlaveOptions> extends EventEmitter<AbstractPhysicalLayerEvents> {
|
|
64
|
-
readonly models: Map<number, ModbusSlaveModel>;
|
|
65
|
-
readonly concurrent: boolean;
|
|
66
|
-
private _physicalLayer;
|
|
67
|
-
private _protocol;
|
|
68
|
-
private _appLayers;
|
|
69
|
-
private _customFunctionCodes;
|
|
70
|
-
private _locks;
|
|
71
|
-
private _cleanupFns;
|
|
72
|
-
private _closePromise;
|
|
73
|
-
get state(): PhysicalState;
|
|
74
|
-
get physicalLayer(): AbstractPhysicalLayer;
|
|
75
|
-
constructor(options: T);
|
|
76
|
-
private _createAppLayer;
|
|
77
|
-
private handleFC1;
|
|
78
|
-
private handleFC2;
|
|
79
|
-
private handleFC3;
|
|
80
|
-
private handleFC4;
|
|
81
|
-
private handleFC5;
|
|
82
|
-
private handleFC6;
|
|
83
|
-
private handleFC15;
|
|
84
|
-
private handleFC16;
|
|
85
|
-
private handleFC17;
|
|
86
|
-
private handleFC22;
|
|
87
|
-
private handleFC23;
|
|
88
|
-
private handleFC43_14;
|
|
89
|
-
private responseError;
|
|
90
|
-
private _drain;
|
|
91
|
-
private _processFrame;
|
|
92
|
-
private _intercept;
|
|
93
|
-
private _withAddressLock;
|
|
94
|
-
private _handleFC;
|
|
95
|
-
private _handleCustomFC;
|
|
96
|
-
add(model: ModbusSlaveModel): void;
|
|
97
|
-
remove(unit: number): void;
|
|
98
|
-
addCustomFunctionCode(cfc: CustomFunctionCode): void;
|
|
99
|
-
removeCustomFunctionCode(fc: number): void;
|
|
100
|
-
/**
|
|
101
|
-
* Open the underlying physical layer and begin accepting connections.
|
|
102
|
-
*
|
|
103
|
-
* A `ModbusSlave` instance can only be opened once. Once {@link close}
|
|
104
|
-
* is called — explicitly or because the physical layer disconnected —
|
|
105
|
-
* the instance is permanently closed and cannot be reopened.
|
|
106
|
-
* Create a new `ModbusSlave` if a new server is required.
|
|
107
|
-
*/
|
|
108
|
-
open(...args: OpenArgs<T['physical']>): Promise<void>;
|
|
109
|
-
private _close;
|
|
110
|
-
/**
|
|
111
|
-
* Permanently close the slave and release all resources.
|
|
112
|
-
*
|
|
113
|
-
* After calling this method the instance is considered dead:
|
|
114
|
-
* - No further requests can be processed.
|
|
115
|
-
* - The instance cannot be reopened via {@link open}.
|
|
116
|
-
* - All event listeners registered on this slave are removed.
|
|
117
|
-
*/
|
|
118
|
-
close(): Promise<void>;
|
|
119
|
-
}
|
package/dist/src/types.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
export type Callback<T> = (error: Error | null, value: T) => void;
|
|
2
|
-
export type MaybeAsyncFunction<F extends (...args: any) => any> = F extends (...args: infer A) => infer R ? ((...args: A) => Promise<R>) | ((...args: A) => R) : never;
|
|
3
|
-
export interface ApplicationDataUnit {
|
|
4
|
-
transaction?: number;
|
|
5
|
-
unit: number;
|
|
6
|
-
fc: number;
|
|
7
|
-
data: Buffer;
|
|
8
|
-
}
|
|
9
|
-
export interface ServerId {
|
|
10
|
-
/** Server ID; may be 1 byte (number) or multi-byte (number[]) per device spec. */
|
|
11
|
-
serverId?: number[];
|
|
12
|
-
runIndicatorStatus?: boolean;
|
|
13
|
-
additionalData?: number[];
|
|
14
|
-
}
|
|
15
|
-
export interface DeviceIdentification {
|
|
16
|
-
readDeviceIDCode: number;
|
|
17
|
-
conformityLevel: number;
|
|
18
|
-
moreFollows: boolean;
|
|
19
|
-
nextObjectId: number;
|
|
20
|
-
objects: {
|
|
21
|
-
id: number;
|
|
22
|
-
value: string;
|
|
23
|
-
}[];
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Defines a non-standard / user-defined Modbus function code.
|
|
27
|
-
*
|
|
28
|
-
* Registration paths:
|
|
29
|
-
* - `RtuApplicationLayer.addCustomFunctionCode(cfc)` — framing only.
|
|
30
|
-
* - `ModbusSlave.addCustomFunctionCode(cfc)` — framing + slave-side dispatch via `handle`.
|
|
31
|
-
* - `ModbusMaster.addCustomFunctionCode(cfc)` + `ModbusMaster.sendCustomFC(...)` — framing + request issuance.
|
|
32
|
-
*
|
|
33
|
-
* The two `predict*` callbacks declare how to derive the total RTU frame length
|
|
34
|
-
* (PDU + 2-byte CRC) from leading bytes; they are required so the framing FSM
|
|
35
|
-
* can advance without the deleted sliding-window CRC fallback.
|
|
36
|
-
*
|
|
37
|
-
* Return `null` from a predictor to signal "need more bytes before I can decide".
|
|
38
|
-
* Return a positive integer (>= 4, <= 256) for the total frame length.
|
|
39
|
-
*/
|
|
40
|
-
export interface CustomFunctionCode {
|
|
41
|
-
fc: number;
|
|
42
|
-
/** Predict total RTU frame length for an incoming request (slave-side framing). */
|
|
43
|
-
predictRequestLength: (buffer: Buffer) => number | null;
|
|
44
|
-
/** Predict total RTU frame length for an incoming response (master-side framing). */
|
|
45
|
-
predictResponseLength: (buffer: Buffer) => number | null;
|
|
46
|
-
/**
|
|
47
|
-
* Slave-side handler. Receives PDU payload (bytes after `fc`, before CRC) and
|
|
48
|
-
* the unit ID being addressed; must return the PDU payload of the response.
|
|
49
|
-
*
|
|
50
|
-
* Throwing inside `handle` is turned into a Modbus exception response by the slave.
|
|
51
|
-
* If `handle` is omitted, the slave returns an ILLEGAL_FUNCTION exception for this FC.
|
|
52
|
-
*/
|
|
53
|
-
handle?: MaybeAsyncFunction<(data: Buffer, unit: number) => Buffer>;
|
|
54
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Convert a number of bits to milliseconds at a given baud rate.
|
|
3
|
-
*
|
|
4
|
-
* Used to derive Modbus RTU timing intervals from bit counts — e.g. 38.5 bits
|
|
5
|
-
* = 3.5 character times at 11 bits/char (t3.5 inter-frame silence), or 16.5
|
|
6
|
-
* bits = 1.5 character times (t1.5 inter-character timeout), per Modbus V1.02
|
|
7
|
-
* §2.5.1.1.
|
|
8
|
-
*
|
|
9
|
-
* @param baudRate Serial port baud rate.
|
|
10
|
-
* @param bits Number of bits to convert.
|
|
11
|
-
* @returns Duration in milliseconds.
|
|
12
|
-
*/
|
|
13
|
-
export declare function bitsToMs(baudRate: number, bits: number): number;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Drain a pending-callback array: invoke each callback with the given error (or null).
|
|
3
|
-
*
|
|
4
|
-
* Handles `null`/`undefined` entries (from optional `cb?` parameters) gracefully.
|
|
5
|
-
* Used by physical layers and connections to resolve queued
|
|
6
|
-
* open / close / destroy callbacks.
|
|
7
|
-
*/
|
|
8
|
-
export declare function drainCbs(cbs: (((err?: Error | null) => void) | undefined)[] | null, err?: Error | null): void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function checkRange(value: number | number[], range?: [number, number] | [number, number][]): boolean;
|
package/dist/src/utils/crc.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function crc(data: Uint8Array, start?: number, end?: number): number;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export type { RtuProtocolOptions, ResolvedRtuTiming } from './rtu-timing';
|
|
2
|
-
export { bitsToMs } from './bitsToMs';
|
|
3
|
-
export { drainCbs } from './callback';
|
|
4
|
-
export { checkRange } from './checkRange';
|
|
5
|
-
export { crc } from './crc';
|
|
6
|
-
export { isUint8 } from './isUint8';
|
|
7
|
-
export { lrc } from './lrc';
|
|
8
|
-
export { PREDICT_NEED_MORE, PREDICT_UNKNOWN, predictRtuFrameLength } from './predictRtuFrameLength';
|
|
9
|
-
export { promisifyCb } from './promisify-cb';
|
|
10
|
-
export { resolveRtuTiming } from './rtu-timing';
|
|
11
|
-
export { isWhitelisted } from './whitelist';
|