@ya-modbus/transport 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +68 -0
- package/dist/cjs/src/connection.d.ts +90 -0
- package/dist/cjs/src/connection.d.ts.map +1 -0
- package/dist/cjs/src/connection.js +217 -0
- package/dist/cjs/src/connection.js.map +1 -0
- package/dist/cjs/src/create-modbus-transport.d.ts +4 -2
- package/dist/cjs/src/create-modbus-transport.d.ts.map +1 -1
- package/dist/cjs/src/create-modbus-transport.js +29 -28
- package/dist/cjs/src/create-modbus-transport.js.map +1 -1
- package/dist/cjs/src/index.d.ts +1 -0
- package/dist/cjs/src/index.d.ts.map +1 -1
- package/dist/cjs/src/index.js +4 -1
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/manager.d.ts +10 -0
- package/dist/cjs/src/manager.d.ts.map +1 -1
- package/dist/cjs/src/manager.js +18 -6
- package/dist/cjs/src/manager.js.map +1 -1
- package/dist/cjs/src/rtu-transport.d.ts +4 -0
- package/dist/cjs/src/rtu-transport.d.ts.map +1 -1
- package/dist/cjs/src/rtu-transport.js +19 -10
- package/dist/cjs/src/rtu-transport.js.map +1 -1
- package/dist/cjs/src/slave-transport.d.ts +10 -5
- package/dist/cjs/src/slave-transport.d.ts.map +1 -1
- package/dist/cjs/src/slave-transport.js +42 -39
- package/dist/cjs/src/slave-transport.js.map +1 -1
- package/dist/cjs/src/tcp-transport.d.ts +3 -0
- package/dist/cjs/src/tcp-transport.d.ts.map +1 -1
- package/dist/cjs/src/tcp-transport.js +14 -5
- package/dist/cjs/src/tcp-transport.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/connection.d.ts +90 -0
- package/dist/esm/src/connection.d.ts.map +1 -0
- package/dist/esm/src/connection.js +211 -0
- package/dist/esm/src/connection.js.map +1 -0
- package/dist/esm/src/create-modbus-transport.d.ts +4 -2
- package/dist/esm/src/create-modbus-transport.d.ts.map +1 -1
- package/dist/esm/src/create-modbus-transport.js +29 -28
- package/dist/esm/src/create-modbus-transport.js.map +1 -1
- package/dist/esm/src/index.d.ts +1 -0
- package/dist/esm/src/index.d.ts.map +1 -1
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/manager.d.ts +10 -0
- package/dist/esm/src/manager.d.ts.map +1 -1
- package/dist/esm/src/manager.js +18 -6
- package/dist/esm/src/manager.js.map +1 -1
- package/dist/esm/src/rtu-transport.d.ts +4 -0
- package/dist/esm/src/rtu-transport.d.ts.map +1 -1
- package/dist/esm/src/rtu-transport.js +19 -10
- package/dist/esm/src/rtu-transport.js.map +1 -1
- package/dist/esm/src/slave-transport.d.ts +10 -5
- package/dist/esm/src/slave-transport.d.ts.map +1 -1
- package/dist/esm/src/slave-transport.js +42 -39
- package/dist/esm/src/slave-transport.js.map +1 -1
- package/dist/esm/src/tcp-transport.d.ts +3 -0
- package/dist/esm/src/tcp-transport.d.ts.map +1 -1
- package/dist/esm/src/tcp-transport.js +14 -5
- package/dist/esm/src/tcp-transport.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection of lost connections and reopening of modbus-serial clients
|
|
3
|
+
*/
|
|
4
|
+
import type ModbusRTU from 'modbus-serial';
|
|
5
|
+
import { type ModbusError } from './normalize-error.js';
|
|
6
|
+
/** Delay before the first attempt to reopen a lost connection, in milliseconds */
|
|
7
|
+
export declare const REOPEN_DELAY_MS = 1000;
|
|
8
|
+
/** Longest delay between attempts to reopen a lost connection, in milliseconds */
|
|
9
|
+
export declare const MAX_REOPEN_DELAY_MS = 60000;
|
|
10
|
+
/**
|
|
11
|
+
* Opens a new connected and configured client
|
|
12
|
+
*/
|
|
13
|
+
export type OpenClient = () => Promise<ModbusRTU>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if an error means that the connection is lost (see ModbusConnection)
|
|
16
|
+
*
|
|
17
|
+
* @param error - Value that was thrown or used to reject a promise
|
|
18
|
+
* @returns True for a ConnectionLostError
|
|
19
|
+
*/
|
|
20
|
+
export declare function isConnectionLostError(error: unknown): error is ModbusError;
|
|
21
|
+
/** Marks ModbusConnection objects, the same for all copies of this package */
|
|
22
|
+
declare const CONNECTION: unique symbol;
|
|
23
|
+
/**
|
|
24
|
+
* A modbus-serial client together with the state of its connection.
|
|
25
|
+
*
|
|
26
|
+
* modbus-serial emits 'error' (for example when a USB serial adapter is unplugged)
|
|
27
|
+
* and 'close' when the port fails. Node.js throws an 'error' event that has no
|
|
28
|
+
* listener, which crashes the process. ModbusConnection listens for both events
|
|
29
|
+
* and for clients that are no longer open, and then marks the connection as lost:
|
|
30
|
+
* - requests in flight reject at once, without waiting for the response timeout
|
|
31
|
+
* - later requests reject with the same ConnectionLostError without using the port
|
|
32
|
+
* - with an `open` function, the first request after a delay opens a new client.
|
|
33
|
+
* The delay starts at REOPEN_DELAY_MS and doubles after each attempt that does
|
|
34
|
+
* not lead to a successful request, up to MAX_REOPEN_DELAY_MS.
|
|
35
|
+
* - without an `open` function, requests reject until the owner of the client
|
|
36
|
+
* opens it again
|
|
37
|
+
*/
|
|
38
|
+
export declare class ModbusConnection {
|
|
39
|
+
private readonly target?;
|
|
40
|
+
private readonly open?;
|
|
41
|
+
readonly [CONNECTION] = true;
|
|
42
|
+
private client;
|
|
43
|
+
private lostError;
|
|
44
|
+
private reopenDelay;
|
|
45
|
+
private reopenAt;
|
|
46
|
+
private reopening;
|
|
47
|
+
private closed;
|
|
48
|
+
private readonly inFlight;
|
|
49
|
+
/**
|
|
50
|
+
* @param client - Connected modbus-serial client
|
|
51
|
+
* @param target - Port path or host:port, used in error messages
|
|
52
|
+
* @param open - Opens a new client after the connection is lost
|
|
53
|
+
*/
|
|
54
|
+
constructor(client: ModbusRTU, target?: string | undefined, open?: OpenClient | undefined);
|
|
55
|
+
/**
|
|
56
|
+
* Run a request with the client
|
|
57
|
+
*
|
|
58
|
+
* @param request - Request to run
|
|
59
|
+
* @returns Result of the request
|
|
60
|
+
* @throws ConnectionLostError when the connection is lost before or during the request
|
|
61
|
+
*/
|
|
62
|
+
run<T>(request: (client: ModbusRTU) => Promise<T>): Promise<T>;
|
|
63
|
+
/**
|
|
64
|
+
* Close the client and stop reopening it
|
|
65
|
+
*/
|
|
66
|
+
close(): Promise<void>;
|
|
67
|
+
private watch;
|
|
68
|
+
private lose;
|
|
69
|
+
/** Set the time of the next reopen attempt, and wait longer after that one */
|
|
70
|
+
private delayReopen;
|
|
71
|
+
/**
|
|
72
|
+
* Get a working client for a lost connection, unless it is too early to try again
|
|
73
|
+
*
|
|
74
|
+
* @param lostError - The error that the connection was lost with
|
|
75
|
+
*/
|
|
76
|
+
private reopen;
|
|
77
|
+
private openClient;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Use a ModbusConnection as it is, or wrap a plain client in a new one
|
|
81
|
+
*
|
|
82
|
+
* Checks the mark instead of `instanceof`, because the CommonJS and ES module
|
|
83
|
+
* builds of this package each have their own ModbusConnection class.
|
|
84
|
+
*
|
|
85
|
+
* @param client - A ModbusConnection or a connected modbus-serial client
|
|
86
|
+
* @returns The connection
|
|
87
|
+
*/
|
|
88
|
+
export declare function toConnection(client: ModbusRTU | ModbusConnection): ModbusConnection;
|
|
89
|
+
export {};
|
|
90
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAwB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAE7E,kFAAkF;AAClF,eAAO,MAAM,eAAe,OAAO,CAAA;AAEnC,kFAAkF;AAClF,eAAO,MAAM,mBAAmB,QAAS,CAAA;AAEzC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;AAEjD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAE1E;AAeD,8EAA8E;AAC9E,QAAA,MAAM,UAAU,eAAsD,CAAA;AAqBtE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,gBAAgB;IAiBzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IAjBxB,QAAQ,CAAC,CAAC,UAAU,CAAC,QAAO;IAC5B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,MAAM,CAAQ;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0C;IAEnE;;;;OAIG;gBAED,MAAM,EAAE,SAAS,EACA,MAAM,CAAC,EAAE,MAAM,YAAA,EACf,IAAI,CAAC,EAAE,UAAU,YAAA;IAMpC;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA0BpE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5B,OAAO,CAAC,KAAK;IAOb,OAAO,CAAC,IAAI;IAYZ,8EAA8E;IAC9E,OAAO,CAAC,WAAW;IAKnB;;;;OAIG;IACH,OAAO,CAAC,MAAM;YAkBA,UAAU;CAqBzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,gBAAgB,GAAG,gBAAgB,CAEnF"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection of lost connections and reopening of modbus-serial clients
|
|
3
|
+
*/
|
|
4
|
+
var _a;
|
|
5
|
+
import { EventEmitter } from 'node:events';
|
|
6
|
+
import { normalizeModbusError } from './normalize-error.js';
|
|
7
|
+
/** Delay before the first attempt to reopen a lost connection, in milliseconds */
|
|
8
|
+
export const REOPEN_DELAY_MS = 1000;
|
|
9
|
+
/** Longest delay between attempts to reopen a lost connection, in milliseconds */
|
|
10
|
+
export const MAX_REOPEN_DELAY_MS = 60000;
|
|
11
|
+
/**
|
|
12
|
+
* Check if an error means that the connection is lost (see ModbusConnection)
|
|
13
|
+
*
|
|
14
|
+
* @param error - Value that was thrown or used to reject a promise
|
|
15
|
+
* @returns True for a ConnectionLostError
|
|
16
|
+
*/
|
|
17
|
+
export function isConnectionLostError(error) {
|
|
18
|
+
return error instanceof Error && error.name === 'ConnectionLostError';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Close a client so that a late 'error' event cannot crash the process
|
|
22
|
+
*
|
|
23
|
+
* modbus-serial stops forwarding the 'error' events of its port when the client
|
|
24
|
+
* closes. An error that the port emits after that (for example from an unplugged
|
|
25
|
+
* adapter) would have no listener, so the port keeps one that ignores it.
|
|
26
|
+
*/
|
|
27
|
+
function closeClient(client, callback) {
|
|
28
|
+
const port = Reflect.get(client, '_port');
|
|
29
|
+
if (port instanceof EventEmitter)
|
|
30
|
+
port.on('error', () => undefined);
|
|
31
|
+
client.close(callback);
|
|
32
|
+
}
|
|
33
|
+
/** Marks ModbusConnection objects, the same for all copies of this package */
|
|
34
|
+
const CONNECTION = Symbol.for('@ya-modbus/transport/ModbusConnection');
|
|
35
|
+
/**
|
|
36
|
+
* Error for a lost connection, with code and errno of a Node.js system error cause
|
|
37
|
+
*/
|
|
38
|
+
function connectionLostError(target, cause) {
|
|
39
|
+
const reason = normalizeModbusError(cause);
|
|
40
|
+
const error = new Error(`Connection ${target === undefined ? '' : `to ${target} `}lost: ${reason.message}`, { cause: reason });
|
|
41
|
+
error.name = 'ConnectionLostError';
|
|
42
|
+
// modbus-serial gives all its port errors errno 'ECONNREFUSED', also an unplugged
|
|
43
|
+
// serial adapter. Only Node.js system errors (they have a code) give a real errno.
|
|
44
|
+
if (reason.code !== undefined) {
|
|
45
|
+
error.code = reason.code;
|
|
46
|
+
error.errno = reason.errno;
|
|
47
|
+
}
|
|
48
|
+
return error;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A modbus-serial client together with the state of its connection.
|
|
52
|
+
*
|
|
53
|
+
* modbus-serial emits 'error' (for example when a USB serial adapter is unplugged)
|
|
54
|
+
* and 'close' when the port fails. Node.js throws an 'error' event that has no
|
|
55
|
+
* listener, which crashes the process. ModbusConnection listens for both events
|
|
56
|
+
* and for clients that are no longer open, and then marks the connection as lost:
|
|
57
|
+
* - requests in flight reject at once, without waiting for the response timeout
|
|
58
|
+
* - later requests reject with the same ConnectionLostError without using the port
|
|
59
|
+
* - with an `open` function, the first request after a delay opens a new client.
|
|
60
|
+
* The delay starts at REOPEN_DELAY_MS and doubles after each attempt that does
|
|
61
|
+
* not lead to a successful request, up to MAX_REOPEN_DELAY_MS.
|
|
62
|
+
* - without an `open` function, requests reject until the owner of the client
|
|
63
|
+
* opens it again
|
|
64
|
+
*/
|
|
65
|
+
export class ModbusConnection {
|
|
66
|
+
/**
|
|
67
|
+
* @param client - Connected modbus-serial client
|
|
68
|
+
* @param target - Port path or host:port, used in error messages
|
|
69
|
+
* @param open - Opens a new client after the connection is lost
|
|
70
|
+
*/
|
|
71
|
+
constructor(client, target, open) {
|
|
72
|
+
this.target = target;
|
|
73
|
+
this.open = open;
|
|
74
|
+
this[_a] = true;
|
|
75
|
+
this.reopenDelay = REOPEN_DELAY_MS;
|
|
76
|
+
this.reopenAt = 0;
|
|
77
|
+
this.closed = false;
|
|
78
|
+
this.inFlight = new Set();
|
|
79
|
+
this.client = client;
|
|
80
|
+
this.watch(client);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Run a request with the client
|
|
84
|
+
*
|
|
85
|
+
* @param request - Request to run
|
|
86
|
+
* @returns Result of the request
|
|
87
|
+
* @throws ConnectionLostError when the connection is lost before or during the request
|
|
88
|
+
*/
|
|
89
|
+
async run(request) {
|
|
90
|
+
// No await while the connection works, so the request starts at once
|
|
91
|
+
const client = this.lostError === undefined ? this.client : await this.reopen(this.lostError);
|
|
92
|
+
// Assigned at once: the promise executor runs synchronously
|
|
93
|
+
let rejectOnLoss;
|
|
94
|
+
const lost = new Promise((_resolve, reject) => {
|
|
95
|
+
rejectOnLoss = reject;
|
|
96
|
+
});
|
|
97
|
+
// Handled here too, in case request() throws before Promise.race() listens
|
|
98
|
+
lost.catch(() => undefined);
|
|
99
|
+
this.inFlight.add(rejectOnLoss);
|
|
100
|
+
try {
|
|
101
|
+
const value = await Promise.race([request(client), lost]);
|
|
102
|
+
// The port works, so the next loss starts again with the shortest delay
|
|
103
|
+
this.reopenDelay = REOPEN_DELAY_MS;
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// modbus-serial clears isOpen on some failures without an event (TCP socket errors)
|
|
108
|
+
if (!client.isOpen)
|
|
109
|
+
this.lose(client, error);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
finally {
|
|
113
|
+
this.inFlight.delete(rejectOnLoss);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Close the client and stop reopening it
|
|
118
|
+
*/
|
|
119
|
+
async close() {
|
|
120
|
+
this.closed = true;
|
|
121
|
+
// A lost client or a client that is not open needs no close. modbus-serial never
|
|
122
|
+
// calls back when it closes a TCP client whose socket is closed.
|
|
123
|
+
if (this.lostError !== undefined || !this.client.isOpen)
|
|
124
|
+
return;
|
|
125
|
+
const client = this.client;
|
|
126
|
+
await new Promise((resolve) => {
|
|
127
|
+
closeClient(client, () => resolve());
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
watch(client) {
|
|
131
|
+
// The listeners stay for the life of the client: a late 'error' from a lost
|
|
132
|
+
// client must not crash the process
|
|
133
|
+
client.on('error', (error) => this.lose(client, error));
|
|
134
|
+
client.on('close', () => this.lose(client, 'port closed'));
|
|
135
|
+
}
|
|
136
|
+
lose(client, cause) {
|
|
137
|
+
// Ignore events from clients that were replaced, and repeated events
|
|
138
|
+
if (client !== this.client || this.lostError !== undefined || this.closed)
|
|
139
|
+
return;
|
|
140
|
+
this.lostError = connectionLostError(this.target, cause);
|
|
141
|
+
this.delayReopen();
|
|
142
|
+
for (const reject of this.inFlight)
|
|
143
|
+
reject(this.lostError);
|
|
144
|
+
// serialport closes the port on a disconnect. A port that is still open keeps
|
|
145
|
+
// its lock, and the reopen would fail.
|
|
146
|
+
if (client.isOpen)
|
|
147
|
+
closeClient(client, () => undefined);
|
|
148
|
+
}
|
|
149
|
+
/** Set the time of the next reopen attempt, and wait longer after that one */
|
|
150
|
+
delayReopen() {
|
|
151
|
+
this.reopenAt = performance.now() + this.reopenDelay;
|
|
152
|
+
this.reopenDelay = Math.min(this.reopenDelay * 2, MAX_REOPEN_DELAY_MS);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get a working client for a lost connection, unless it is too early to try again
|
|
156
|
+
*
|
|
157
|
+
* @param lostError - The error that the connection was lost with
|
|
158
|
+
*/
|
|
159
|
+
reopen(lostError) {
|
|
160
|
+
if (this.open === undefined) {
|
|
161
|
+
// The owner of the client can open it again
|
|
162
|
+
if (this.client.isOpen && !this.closed) {
|
|
163
|
+
this.lostError = undefined;
|
|
164
|
+
return Promise.resolve(this.client);
|
|
165
|
+
}
|
|
166
|
+
return Promise.reject(lostError);
|
|
167
|
+
}
|
|
168
|
+
if (this.closed || performance.now() < this.reopenAt)
|
|
169
|
+
return Promise.reject(lostError);
|
|
170
|
+
// Requests that come while the client opens wait for the same attempt
|
|
171
|
+
this.reopening ?? (this.reopening = this.openClient(this.open, lostError).finally(() => {
|
|
172
|
+
this.reopening = undefined;
|
|
173
|
+
}));
|
|
174
|
+
return this.reopening;
|
|
175
|
+
}
|
|
176
|
+
async openClient(open, lostError) {
|
|
177
|
+
let client;
|
|
178
|
+
try {
|
|
179
|
+
client = await open();
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
const openError = connectionLostError(this.target, error);
|
|
183
|
+
this.lostError = openError;
|
|
184
|
+
this.delayReopen();
|
|
185
|
+
throw openError;
|
|
186
|
+
}
|
|
187
|
+
if (this.closed) {
|
|
188
|
+
// close() was called while the client was opening
|
|
189
|
+
closeClient(client, () => undefined);
|
|
190
|
+
throw lostError;
|
|
191
|
+
}
|
|
192
|
+
this.client = client;
|
|
193
|
+
this.lostError = undefined;
|
|
194
|
+
this.watch(client);
|
|
195
|
+
return client;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
_a = CONNECTION;
|
|
199
|
+
/**
|
|
200
|
+
* Use a ModbusConnection as it is, or wrap a plain client in a new one
|
|
201
|
+
*
|
|
202
|
+
* Checks the mark instead of `instanceof`, because the CommonJS and ES module
|
|
203
|
+
* builds of this package each have their own ModbusConnection class.
|
|
204
|
+
*
|
|
205
|
+
* @param client - A ModbusConnection or a connected modbus-serial client
|
|
206
|
+
* @returns The connection
|
|
207
|
+
*/
|
|
208
|
+
export function toConnection(client) {
|
|
209
|
+
return CONNECTION in client ? client : new ModbusConnection(client);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../../src/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import type { Transport } from '@ya-modbus/driver-types';
|
|
2
2
|
import type ModbusRTU from 'modbus-serial';
|
|
3
|
+
import { type ModbusConnection } from './connection.js';
|
|
3
4
|
import { type RetryLogger } from './retry.js';
|
|
4
5
|
/**
|
|
5
6
|
* Create a Transport implementation from a ModbusRTU client
|
|
6
7
|
*
|
|
7
8
|
* This factory wraps all modbus-serial client methods with retry logic
|
|
8
9
|
* and converts them to the Transport interface expected by device drivers.
|
|
10
|
+
* Requests on a lost connection reject with a ConnectionLostError (see ModbusConnection).
|
|
9
11
|
*
|
|
10
|
-
* @param client - Configured ModbusRTU client instance
|
|
12
|
+
* @param client - Configured ModbusRTU client instance, or a ModbusConnection that can reopen it
|
|
11
13
|
* @param maxRetries - Maximum retry attempts (default: 3, use 1 for discovery to disable retries)
|
|
12
14
|
* @param logger - Optional callback to log retry attempts for debugging
|
|
13
15
|
* @returns Transport implementation
|
|
14
16
|
*/
|
|
15
|
-
export declare function createModbusTransport(client: ModbusRTU, maxRetries?: number, logger?: RetryLogger): Transport;
|
|
17
|
+
export declare function createModbusTransport(client: ModbusRTU | ModbusConnection, maxRetries?: number, logger?: RetryLogger): Transport;
|
|
16
18
|
//# sourceMappingURL=create-modbus-transport.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-modbus-transport.d.ts","sourceRoot":"","sources":["../../../src/create-modbus-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAExD
|
|
1
|
+
{"version":3,"file":"create-modbus-transport.d.ts","sourceRoot":"","sources":["../../../src/create-modbus-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACrE,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAExD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,GAAG,gBAAgB,EACpC,UAAU,GAAE,MAAU,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,SAAS,CA4GX"}
|
|
@@ -1,58 +1,61 @@
|
|
|
1
|
+
import { toConnection } from './connection.js';
|
|
1
2
|
import { withRetry } from './retry.js';
|
|
2
3
|
/**
|
|
3
4
|
* Create a Transport implementation from a ModbusRTU client
|
|
4
5
|
*
|
|
5
6
|
* This factory wraps all modbus-serial client methods with retry logic
|
|
6
7
|
* and converts them to the Transport interface expected by device drivers.
|
|
8
|
+
* Requests on a lost connection reject with a ConnectionLostError (see ModbusConnection).
|
|
7
9
|
*
|
|
8
|
-
* @param client - Configured ModbusRTU client instance
|
|
10
|
+
* @param client - Configured ModbusRTU client instance, or a ModbusConnection that can reopen it
|
|
9
11
|
* @param maxRetries - Maximum retry attempts (default: 3, use 1 for discovery to disable retries)
|
|
10
12
|
* @param logger - Optional callback to log retry attempts for debugging
|
|
11
13
|
* @returns Transport implementation
|
|
12
14
|
*/
|
|
13
15
|
export function createModbusTransport(client, maxRetries = 3, logger) {
|
|
16
|
+
const connection = toConnection(client);
|
|
14
17
|
return {
|
|
15
18
|
async readHoldingRegisters(address, count) {
|
|
16
|
-
return withRetry(async () => {
|
|
17
|
-
const result = await
|
|
19
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
20
|
+
const result = await modbus.readHoldingRegisters(address, count);
|
|
18
21
|
return result.buffer;
|
|
19
|
-
}, maxRetries, logger);
|
|
22
|
+
}), maxRetries, logger);
|
|
20
23
|
},
|
|
21
24
|
async readInputRegisters(address, count) {
|
|
22
|
-
return withRetry(async () => {
|
|
23
|
-
const result = await
|
|
25
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
26
|
+
const result = await modbus.readInputRegisters(address, count);
|
|
24
27
|
return result.buffer;
|
|
25
|
-
}, maxRetries, logger);
|
|
28
|
+
}), maxRetries, logger);
|
|
26
29
|
},
|
|
27
30
|
async readCoils(address, count) {
|
|
28
|
-
return withRetry(async () => {
|
|
29
|
-
const result = await
|
|
31
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
32
|
+
const result = await modbus.readCoils(address, count);
|
|
30
33
|
return result.buffer;
|
|
31
|
-
}, maxRetries, logger);
|
|
34
|
+
}), maxRetries, logger);
|
|
32
35
|
},
|
|
33
36
|
async readDiscreteInputs(address, count) {
|
|
34
|
-
return withRetry(async () => {
|
|
35
|
-
const result = await
|
|
37
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
38
|
+
const result = await modbus.readDiscreteInputs(address, count);
|
|
36
39
|
return result.buffer;
|
|
37
|
-
}, maxRetries, logger);
|
|
40
|
+
}), maxRetries, logger);
|
|
38
41
|
},
|
|
39
42
|
async writeSingleRegister(address, value) {
|
|
40
|
-
return withRetry(async () => {
|
|
41
|
-
await
|
|
42
|
-
}, maxRetries, logger);
|
|
43
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
44
|
+
await modbus.writeRegister(address, value);
|
|
45
|
+
}), maxRetries, logger);
|
|
43
46
|
},
|
|
44
47
|
async writeMultipleRegisters(address, values) {
|
|
45
|
-
return withRetry(async () => {
|
|
46
|
-
await
|
|
47
|
-
}, maxRetries, logger);
|
|
48
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
49
|
+
await modbus.writeRegisters(address, values);
|
|
50
|
+
}), maxRetries, logger);
|
|
48
51
|
},
|
|
49
52
|
async writeSingleCoil(address, value) {
|
|
50
|
-
return withRetry(async () => {
|
|
51
|
-
await
|
|
52
|
-
}, maxRetries, logger);
|
|
53
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
54
|
+
await modbus.writeCoil(address, value);
|
|
55
|
+
}), maxRetries, logger);
|
|
53
56
|
},
|
|
54
57
|
async writeMultipleCoils(address, values) {
|
|
55
|
-
return withRetry(async () => {
|
|
58
|
+
return withRetry(() => connection.run(async (modbus) => {
|
|
56
59
|
// Convert Buffer to boolean array
|
|
57
60
|
const bools = [];
|
|
58
61
|
for (let i = 0; i < values.length * 8; i++) {
|
|
@@ -61,13 +64,11 @@ export function createModbusTransport(client, maxRetries = 3, logger) {
|
|
|
61
64
|
const byte = values[byteIndex]; // byteIndex < values.length due to loop condition
|
|
62
65
|
bools.push((byte & (1 << bitIndex)) !== 0);
|
|
63
66
|
}
|
|
64
|
-
await
|
|
65
|
-
}, maxRetries, logger);
|
|
67
|
+
await modbus.writeCoils(address, bools);
|
|
68
|
+
}), maxRetries, logger);
|
|
66
69
|
},
|
|
67
70
|
async close() {
|
|
68
|
-
return
|
|
69
|
-
client.close(resolve);
|
|
70
|
-
});
|
|
71
|
+
return connection.close();
|
|
71
72
|
},
|
|
72
73
|
};
|
|
73
74
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-modbus-transport.js","sourceRoot":"","sources":["../../../src/create-modbus-transport.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAoB,MAAM,YAAY,CAAA;AAExD
|
|
1
|
+
{"version":3,"file":"create-modbus-transport.js","sourceRoot":"","sources":["../../../src/create-modbus-transport.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/src/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { createTCPTransport, type TCPConfig } from './tcp-transport.js';
|
|
|
10
10
|
export { createModbusTransport } from './create-modbus-transport.js';
|
|
11
11
|
export { withRetry, MAX_RETRIES, RETRY_DELAY_MS, type RetryLogger } from './retry.js';
|
|
12
12
|
export { normalizeModbusError, type ModbusError } from './normalize-error.js';
|
|
13
|
+
export { isConnectionLostError, ModbusConnection, type OpenClient } from './connection.js';
|
|
13
14
|
export { TransportManager, type TransportStats } from './manager.js';
|
|
14
15
|
export { MutexTransport } from './mutex-transport.js';
|
|
15
16
|
export { SlaveTransport } from './slave-transport.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAE,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAE,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC1F,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/esm/src/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export { createTCPTransport } from './tcp-transport.js';
|
|
|
10
10
|
export { createModbusTransport } from './create-modbus-transport.js';
|
|
11
11
|
export { withRetry, MAX_RETRIES, RETRY_DELAY_MS } from './retry.js';
|
|
12
12
|
export { normalizeModbusError } from './normalize-error.js';
|
|
13
|
+
export { isConnectionLostError, ModbusConnection } from './connection.js';
|
|
13
14
|
export { TransportManager } from './manager.js';
|
|
14
15
|
export { MutexTransport } from './mutex-transport.js';
|
|
15
16
|
export { SlaveTransport } from './slave-transport.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAwB,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAoB,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,gBAAgB,EAAuB,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,eAAe,EAAwB,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,kBAAkB,EAAkB,MAAM,oBAAoB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAoB,MAAM,YAAY,CAAA;AACrF,OAAO,EAAE,oBAAoB,EAAoB,MAAM,sBAAsB,CAAA;AAC7E,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAmB,MAAM,iBAAiB,CAAA;AAC1F,OAAO,EAAE,gBAAgB,EAAuB,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
|
|
@@ -18,6 +18,9 @@ export interface TransportStats {
|
|
|
18
18
|
* - Returns SlaveTransport instances that set the slave ID before each operation
|
|
19
19
|
* - Multiple devices on the same connection share a single client and mutex
|
|
20
20
|
* - All operations are serialized using async-mutex to prevent race conditions
|
|
21
|
+
* - A lost connection (USB adapter unplugged, TCP connection closed) drops the client.
|
|
22
|
+
* The first request after a backoff opens a new client for all devices on the
|
|
23
|
+
* connection (see ModbusConnection)
|
|
21
24
|
*
|
|
22
25
|
* This architecture solves the multi-device problem:
|
|
23
26
|
* - Each device gets its own SlaveTransport with its own slave ID
|
|
@@ -64,6 +67,13 @@ export declare class TransportManager {
|
|
|
64
67
|
* @returns Physical connection key string
|
|
65
68
|
*/
|
|
66
69
|
private getPhysicalConnectionKey;
|
|
70
|
+
/**
|
|
71
|
+
* Describe a physical connection for error messages
|
|
72
|
+
*
|
|
73
|
+
* @param config - Transport configuration
|
|
74
|
+
* @returns Serial port path for RTU, host:port for TCP
|
|
75
|
+
*/
|
|
76
|
+
private getTarget;
|
|
67
77
|
/**
|
|
68
78
|
* Create and configure an RTU modbus-serial client.
|
|
69
79
|
* Does NOT set slave ID - that's handled by SlaveTransport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAMxD,OAAO,KAAK,EAAwB,eAAe,EAAE,MAAM,cAAc,CAAA;AAazE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IAEjE;;;;;;;OAOG;IACG,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IA8B/D;;;;OAIG;IACH,QAAQ,IAAI,cAAc;IAS1B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B;;;;;;;;OAQG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;;;OAKG;IACH,OAAO,CAAC,SAAS;IAIjB;;;;;;OAMG;YACW,eAAe;IAe7B;;;;;;OAMG;YACW,eAAe;IAU7B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CAGpB"}
|
package/dist/esm/src/manager.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Mutex } from 'async-mutex';
|
|
2
2
|
import ModbusRTU from 'modbus-serial';
|
|
3
3
|
import { DEFAULT_TIMEOUT_MS } from './client-config.js';
|
|
4
|
+
import { ModbusConnection } from './connection.js';
|
|
4
5
|
import { SlaveTransport } from './slave-transport.js';
|
|
5
6
|
/**
|
|
6
7
|
* TransportManager pools modbus-serial clients and provides slave-specific transports.
|
|
@@ -12,6 +13,9 @@ import { SlaveTransport } from './slave-transport.js';
|
|
|
12
13
|
* - Returns SlaveTransport instances that set the slave ID before each operation
|
|
13
14
|
* - Multiple devices on the same connection share a single client and mutex
|
|
14
15
|
* - All operations are serialized using async-mutex to prevent race conditions
|
|
16
|
+
* - A lost connection (USB adapter unplugged, TCP connection closed) drops the client.
|
|
17
|
+
* The first request after a backoff opens a new client for all devices on the
|
|
18
|
+
* connection (see ModbusConnection)
|
|
15
19
|
*
|
|
16
20
|
* This architecture solves the multi-device problem:
|
|
17
21
|
* - Each device gets its own SlaveTransport with its own slave ID
|
|
@@ -45,9 +49,10 @@ export class TransportManager {
|
|
|
45
49
|
let entry = this.connections.get(key);
|
|
46
50
|
if (!entry) {
|
|
47
51
|
// Create new client for this physical connection
|
|
48
|
-
const
|
|
52
|
+
const open = isRTU ? () => this.createRTUClient(config) : () => this.createTCPClient(config);
|
|
53
|
+
const client = await open();
|
|
49
54
|
entry = {
|
|
50
|
-
client,
|
|
55
|
+
connection: new ModbusConnection(client, this.getTarget(config), open),
|
|
51
56
|
mutex: new Mutex(),
|
|
52
57
|
config,
|
|
53
58
|
isRTU,
|
|
@@ -55,7 +60,7 @@ export class TransportManager {
|
|
|
55
60
|
this.connections.set(key, entry);
|
|
56
61
|
}
|
|
57
62
|
// Return a new SlaveTransport for this specific slave
|
|
58
|
-
return new SlaveTransport(config.slaveId, entry.
|
|
63
|
+
return new SlaveTransport(config.slaveId, entry.connection, entry.mutex, config.maxRetries ?? 3, config.logger);
|
|
59
64
|
}
|
|
60
65
|
/**
|
|
61
66
|
* Get statistics about managed connections
|
|
@@ -77,9 +82,7 @@ export class TransportManager {
|
|
|
77
82
|
async closeAll() {
|
|
78
83
|
const closePromises = Array.from(this.connections.values()).map(async (entry) => {
|
|
79
84
|
try {
|
|
80
|
-
await
|
|
81
|
-
entry.client.close(resolve);
|
|
82
|
-
});
|
|
85
|
+
await entry.connection.close();
|
|
83
86
|
}
|
|
84
87
|
catch (error) {
|
|
85
88
|
// Log but don't throw - we want to close all connections
|
|
@@ -105,6 +108,15 @@ export class TransportManager {
|
|
|
105
108
|
// TCP config - safe to access host/port because isRTUConfig returned false
|
|
106
109
|
return `tcp:${config.host}:${config.port ?? 502}`;
|
|
107
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Describe a physical connection for error messages
|
|
113
|
+
*
|
|
114
|
+
* @param config - Transport configuration
|
|
115
|
+
* @returns Serial port path for RTU, host:port for TCP
|
|
116
|
+
*/
|
|
117
|
+
getTarget(config) {
|
|
118
|
+
return this.isRTUConfig(config) ? config.port : `${config.host}:${config.port ?? 502}`;
|
|
119
|
+
}
|
|
108
120
|
/**
|
|
109
121
|
* Create and configure an RTU modbus-serial client.
|
|
110
122
|
* Does NOT set slave ID - that's handled by SlaveTransport.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACnC,OAAO,SAAS,MAAM,eAAe,CAAA;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,6 +26,10 @@ export interface RTUConfig {
|
|
|
26
26
|
/**
|
|
27
27
|
* Create an RTU transport
|
|
28
28
|
*
|
|
29
|
+
* When the serial port is lost (for example the USB adapter is unplugged), requests
|
|
30
|
+
* reject with a ConnectionLostError and the port is reopened on a later request
|
|
31
|
+
* (see ModbusConnection).
|
|
32
|
+
*
|
|
29
33
|
* @param config - RTU configuration
|
|
30
34
|
* @returns Transport implementation for RTU
|
|
31
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rtu-transport.d.ts","sourceRoot":"","sources":["../../../src/rtu-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;
|
|
1
|
+
{"version":3,"file":"rtu-transport.d.ts","sourceRoot":"","sources":["../../../src/rtu-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAM9F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,gBAAgB;IAChB,QAAQ,EAAE,QAAQ,CAAA;IAClB,gBAAgB;IAChB,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa;IACb,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB;IAChB,QAAQ,EAAE,QAAQ,CAAA;IAClB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAA;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAkB9E"}
|