@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.
Files changed (61) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +68 -0
  3. package/dist/cjs/src/connection.d.ts +90 -0
  4. package/dist/cjs/src/connection.d.ts.map +1 -0
  5. package/dist/cjs/src/connection.js +217 -0
  6. package/dist/cjs/src/connection.js.map +1 -0
  7. package/dist/cjs/src/create-modbus-transport.d.ts +4 -2
  8. package/dist/cjs/src/create-modbus-transport.d.ts.map +1 -1
  9. package/dist/cjs/src/create-modbus-transport.js +29 -28
  10. package/dist/cjs/src/create-modbus-transport.js.map +1 -1
  11. package/dist/cjs/src/index.d.ts +1 -0
  12. package/dist/cjs/src/index.d.ts.map +1 -1
  13. package/dist/cjs/src/index.js +4 -1
  14. package/dist/cjs/src/index.js.map +1 -1
  15. package/dist/cjs/src/manager.d.ts +10 -0
  16. package/dist/cjs/src/manager.d.ts.map +1 -1
  17. package/dist/cjs/src/manager.js +18 -6
  18. package/dist/cjs/src/manager.js.map +1 -1
  19. package/dist/cjs/src/rtu-transport.d.ts +4 -0
  20. package/dist/cjs/src/rtu-transport.d.ts.map +1 -1
  21. package/dist/cjs/src/rtu-transport.js +19 -10
  22. package/dist/cjs/src/rtu-transport.js.map +1 -1
  23. package/dist/cjs/src/slave-transport.d.ts +10 -5
  24. package/dist/cjs/src/slave-transport.d.ts.map +1 -1
  25. package/dist/cjs/src/slave-transport.js +42 -39
  26. package/dist/cjs/src/slave-transport.js.map +1 -1
  27. package/dist/cjs/src/tcp-transport.d.ts +3 -0
  28. package/dist/cjs/src/tcp-transport.d.ts.map +1 -1
  29. package/dist/cjs/src/tcp-transport.js +14 -5
  30. package/dist/cjs/src/tcp-transport.js.map +1 -1
  31. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  32. package/dist/esm/src/connection.d.ts +90 -0
  33. package/dist/esm/src/connection.d.ts.map +1 -0
  34. package/dist/esm/src/connection.js +211 -0
  35. package/dist/esm/src/connection.js.map +1 -0
  36. package/dist/esm/src/create-modbus-transport.d.ts +4 -2
  37. package/dist/esm/src/create-modbus-transport.d.ts.map +1 -1
  38. package/dist/esm/src/create-modbus-transport.js +29 -28
  39. package/dist/esm/src/create-modbus-transport.js.map +1 -1
  40. package/dist/esm/src/index.d.ts +1 -0
  41. package/dist/esm/src/index.d.ts.map +1 -1
  42. package/dist/esm/src/index.js +1 -0
  43. package/dist/esm/src/index.js.map +1 -1
  44. package/dist/esm/src/manager.d.ts +10 -0
  45. package/dist/esm/src/manager.d.ts.map +1 -1
  46. package/dist/esm/src/manager.js +18 -6
  47. package/dist/esm/src/manager.js.map +1 -1
  48. package/dist/esm/src/rtu-transport.d.ts +4 -0
  49. package/dist/esm/src/rtu-transport.d.ts.map +1 -1
  50. package/dist/esm/src/rtu-transport.js +19 -10
  51. package/dist/esm/src/rtu-transport.js.map +1 -1
  52. package/dist/esm/src/slave-transport.d.ts +10 -5
  53. package/dist/esm/src/slave-transport.d.ts.map +1 -1
  54. package/dist/esm/src/slave-transport.js +42 -39
  55. package/dist/esm/src/slave-transport.js.map +1 -1
  56. package/dist/esm/src/tcp-transport.d.ts +3 -0
  57. package/dist/esm/src/tcp-transport.d.ts.map +1 -1
  58. package/dist/esm/src/tcp-transport.js +14 -5
  59. package/dist/esm/src/tcp-transport.js.map +1 -1
  60. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  61. 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;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,UAAU,GAAE,MAAU,EACtB,MAAM,CAAC,EAAE,WAAW,GACnB,SAAS,CAoGX"}
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 client.readHoldingRegisters(address, count);
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 client.readInputRegisters(address, count);
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 client.readCoils(address, count);
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 client.readDiscreteInputs(address, count);
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 client.writeRegister(address, value);
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 client.writeRegisters(address, values);
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 client.writeCoil(address, value);
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 client.writeCoils(address, bools);
65
- }, maxRetries, logger);
67
+ await modbus.writeCoils(address, bools);
68
+ }), maxRetries, logger);
66
69
  },
67
70
  async close() {
68
- return new Promise((resolve) => {
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":"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"}
1
+ {"version":3,"file":"create-modbus-transport.js","sourceRoot":"","sources":["../../../src/create-modbus-transport.ts"],"names":[],"mappings":"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"}
@@ -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"}
@@ -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;AAKxD,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;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IAEjE;;;;;;;OAOG;IACG,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IA6B/D;;;;OAIG;IACH,QAAQ,IAAI,cAAc;IAS1B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;;;;;;;OAQG;IACH,OAAO,CAAC,wBAAwB;IAShC;;;;;;OAMG;YACW,eAAe;IAe7B;;;;;;OAMG;YACW,eAAe;IAU7B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CAGpB"}
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"}
@@ -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 client = isRTU ? await this.createRTUClient(config) : await this.createTCPClient(config);
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.client, entry.mutex, config.maxRetries ?? 3, config.logger);
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 new Promise((resolve) => {
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":"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"}
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;AAK9F,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;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAc9E"}
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"}