@ya-modbus/transport 0.7.1 → 0.7.2

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 CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.7.2](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/transport@0.7.1...@ya-modbus/transport@0.7.2) (2026-02-11)
7
+
8
+ ### Bug Fixes
9
+
10
+ - **transport:** multiple devices on same bus use correct slave ID ([#235](https://github.com/groupsky/ya-modbus/issues/235)) ([7259914](https://github.com/groupsky/ya-modbus/commit/7259914ca2583c5222c99f3306de87961975d2c4)), closes [#171](https://github.com/groupsky/ya-modbus/issues/171)
11
+
6
12
  ## [0.7.1](https://github.com/groupsky/ya-modbus/compare/@ya-modbus/transport@0.7.0...@ya-modbus/transport@0.7.1) (2026-02-06)
7
13
 
8
14
  **Note:** Version bump only for package @ya-modbus/transport
@@ -11,4 +11,5 @@ export { createModbusTransport } from './create-modbus-transport.js';
11
11
  export { withRetry, MAX_RETRIES, RETRY_DELAY_MS, type RetryLogger } from './retry.js';
12
12
  export { TransportManager, type TransportStats } from './manager.js';
13
13
  export { MutexTransport } from './mutex-transport.js';
14
+ export { SlaveTransport } from './slave-transport.js';
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -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,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AACpE,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,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA"}
@@ -6,7 +6,7 @@
6
6
  * and transport pooling with mutex-based RTU bus serialization
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.MutexTransport = exports.TransportManager = exports.RETRY_DELAY_MS = exports.MAX_RETRIES = exports.withRetry = exports.createModbusTransport = exports.createTCPTransport = exports.createRTUTransport = exports.createTransport = void 0;
9
+ exports.SlaveTransport = exports.MutexTransport = exports.TransportManager = exports.RETRY_DELAY_MS = exports.MAX_RETRIES = exports.withRetry = exports.createModbusTransport = exports.createTCPTransport = exports.createRTUTransport = exports.createTransport = void 0;
10
10
  var factory_js_1 = require("./factory.js");
11
11
  Object.defineProperty(exports, "createTransport", { enumerable: true, get: function () { return factory_js_1.createTransport; } });
12
12
  var rtu_transport_js_1 = require("./rtu-transport.js");
@@ -23,4 +23,6 @@ var manager_js_1 = require("./manager.js");
23
23
  Object.defineProperty(exports, "TransportManager", { enumerable: true, get: function () { return manager_js_1.TransportManager; } });
24
24
  var mutex_transport_js_1 = require("./mutex-transport.js");
25
25
  Object.defineProperty(exports, "MutexTransport", { enumerable: true, get: function () { return mutex_transport_js_1.MutexTransport; } });
26
+ var slave_transport_js_1 = require("./slave-transport.js");
27
+ Object.defineProperty(exports, "SlaveTransport", { enumerable: true, get: function () { return slave_transport_js_1.SlaveTransport; } });
26
28
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,2CAAoE;AAA3D,6GAAA,eAAe,OAAA;AACxB,uDAAuE;AAA9D,sHAAA,kBAAkB,OAAA;AAC3B,uDAAuE;AAA9D,sHAAA,kBAAkB,OAAA;AAC3B,2EAAoE;AAA3D,mIAAA,qBAAqB,OAAA;AAC9B,uCAAqF;AAA5E,qGAAA,SAAS,OAAA;AAAE,uGAAA,WAAW,OAAA;AAAE,0GAAA,cAAc,OAAA;AAC/C,2CAAoE;AAA3D,8GAAA,gBAAgB,OAAA;AACzB,2DAAqD;AAA5C,oHAAA,cAAc,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,2CAAoE;AAA3D,6GAAA,eAAe,OAAA;AACxB,uDAAuE;AAA9D,sHAAA,kBAAkB,OAAA;AAC3B,uDAAuE;AAA9D,sHAAA,kBAAkB,OAAA;AAC3B,2EAAoE;AAA3D,mIAAA,qBAAqB,OAAA;AAC9B,uCAAqF;AAA5E,qGAAA,SAAS,OAAA;AAAE,uGAAA,WAAW,OAAA;AAAE,0GAAA,cAAc,OAAA;AAC/C,2CAAoE;AAA3D,8GAAA,gBAAgB,OAAA;AACzB,2DAAqD;AAA5C,oHAAA,cAAc,OAAA;AACvB,2DAAqD;AAA5C,oHAAA,cAAc,OAAA"}
@@ -1,5 +1,5 @@
1
1
  import type { Transport } from '@ya-modbus/driver-types';
2
- import { type TransportConfig } from './factory.js';
2
+ import type { TransportConfig } from './factory.js';
3
3
  /**
4
4
  * Statistics about managed transports
5
5
  */
@@ -9,52 +9,77 @@ export interface TransportStats {
9
9
  tcpTransports: number;
10
10
  }
11
11
  /**
12
- * TransportManager pools transport instances and provides mutex-based
13
- * serialization for all transport operations to prevent concurrent access issues.
12
+ * TransportManager pools modbus-serial clients and provides slave-specific transports.
14
13
  *
15
14
  * Key behaviors:
16
- * - All transports (RTU and TCP) are pooled by connection configuration
17
- * - RTU transports are pooled by bus configuration (port, baud rate, parity, etc.)
18
- * - TCP transports are pooled by host and port
19
- * - Multiple devices on the same connection share a single transport instance
15
+ * - Pools modbus-serial clients by physical connection (excluding slave ID)
16
+ * - RTU clients are pooled by bus configuration (port, baud rate, parity, etc.)
17
+ * - TCP clients are pooled by host and port
18
+ * - Returns SlaveTransport instances that set the slave ID before each operation
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
21
  *
22
- * Why TCP needs mutex protection:
23
- * - Many Modbus devices allow only one or a limited number of TCP connections
24
- * - Even with multiple connections, devices often process requests sequentially
25
- * - Concurrent requests can cause timeouts, dropped packets, or incorrect responses
26
- * - Serialization ensures reliable communication regardless of device limitations
22
+ * This architecture solves the multi-device problem:
23
+ * - Each device gets its own SlaveTransport with its own slave ID
24
+ * - All devices on the same bus share the same client and mutex
25
+ * - Slave ID is set dynamically before each operation
26
+ * - No more hardcoded slave IDs that affect all devices on a bus
27
+ *
28
+ * IMPORTANT: Shared Resource Ownership
29
+ * Multiple SlaveTransport instances share the same client and mutex. This is
30
+ * intentional and correct:
31
+ * - Shared client: Avoids port contention (can't open serial port twice)
32
+ * - Shared mutex: Ensures serialized access to the bus
33
+ * - SlaveTransport.close(): Does not close shared client (use closeAll() for cleanup)
27
34
  */
28
35
  export declare class TransportManager {
29
- private readonly transports;
36
+ private readonly connections;
30
37
  /**
31
38
  * Get or create a transport for the given configuration.
32
- * Returns mutex-wrapped shared transport if one exists for the same connection.
39
+ * Returns a new SlaveTransport instance bound to the slave ID in the config.
40
+ * Multiple devices on the same physical connection share the same client and mutex.
33
41
  *
34
42
  * @param config - RTU or TCP transport configuration
35
- * @returns Transport instance wrapped with mutex for thread-safe operations
43
+ * @returns SlaveTransport instance for the specific slave device
36
44
  */
37
45
  getTransport(config: TransportConfig): Promise<Transport>;
38
46
  /**
39
- * Get statistics about managed transports
47
+ * Get statistics about managed connections
40
48
  *
41
49
  * @returns Transport statistics
42
50
  */
43
51
  getStats(): TransportStats;
44
52
  /**
45
- * Close all managed transports and clear the pool.
53
+ * Close all managed connections and clear the pool.
46
54
  * Errors during close are logged but do not stop the process.
47
55
  */
48
56
  closeAll(): Promise<void>;
49
57
  /**
50
- * Generate a unique key for a transport configuration.
58
+ * Generate a unique key for a physical connection.
59
+ * Excludes slave ID so multiple devices on the same bus share a connection.
51
60
  * For RTU: Key includes all bus parameters (port, baud, parity, etc.)
52
61
  * For TCP: Key includes host and port
53
62
  *
54
63
  * @param config - Transport configuration
55
- * @returns Connection key string
64
+ * @returns Physical connection key string
65
+ */
66
+ private getPhysicalConnectionKey;
67
+ /**
68
+ * Create and configure an RTU modbus-serial client.
69
+ * Does NOT set slave ID - that's handled by SlaveTransport.
70
+ *
71
+ * @param config - RTU configuration
72
+ * @returns Connected ModbusRTU client
73
+ */
74
+ private createRTUClient;
75
+ /**
76
+ * Create and configure a TCP modbus-serial client.
77
+ * Does NOT set slave ID - that's handled by SlaveTransport.
78
+ *
79
+ * @param config - TCP configuration
80
+ * @returns Connected ModbusRTU client
56
81
  */
57
- private getConnectionKey;
82
+ private createTCPClient;
58
83
  /**
59
84
  * Type guard to check if config is RTU
60
85
  *
@@ -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;AAGxD,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAA;AAepE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAE/D;;;;;;OAMG;IACG,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IAqD/D;;;;OAIG;IACH,QAAQ,IAAI,cAAc;IAS1B;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAc/B;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IASxB;;;;;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;AAIxD,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,89 +1,72 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TransportManager = void 0;
4
+ const tslib_1 = require("tslib");
4
5
  const async_mutex_1 = require("async-mutex");
5
- const factory_js_1 = require("./factory.js");
6
- const mutex_transport_js_1 = require("./mutex-transport.js");
6
+ const modbus_serial_1 = tslib_1.__importDefault(require("modbus-serial"));
7
+ const slave_transport_js_1 = require("./slave-transport.js");
7
8
  /**
8
- * TransportManager pools transport instances and provides mutex-based
9
- * serialization for all transport operations to prevent concurrent access issues.
9
+ * TransportManager pools modbus-serial clients and provides slave-specific transports.
10
10
  *
11
11
  * Key behaviors:
12
- * - All transports (RTU and TCP) are pooled by connection configuration
13
- * - RTU transports are pooled by bus configuration (port, baud rate, parity, etc.)
14
- * - TCP transports are pooled by host and port
15
- * - Multiple devices on the same connection share a single transport instance
12
+ * - Pools modbus-serial clients by physical connection (excluding slave ID)
13
+ * - RTU clients are pooled by bus configuration (port, baud rate, parity, etc.)
14
+ * - TCP clients are pooled by host and port
15
+ * - Returns SlaveTransport instances that set the slave ID before each operation
16
+ * - Multiple devices on the same connection share a single client and mutex
16
17
  * - All operations are serialized using async-mutex to prevent race conditions
17
18
  *
18
- * Why TCP needs mutex protection:
19
- * - Many Modbus devices allow only one or a limited number of TCP connections
20
- * - Even with multiple connections, devices often process requests sequentially
21
- * - Concurrent requests can cause timeouts, dropped packets, or incorrect responses
22
- * - Serialization ensures reliable communication regardless of device limitations
19
+ * This architecture solves the multi-device problem:
20
+ * - Each device gets its own SlaveTransport with its own slave ID
21
+ * - All devices on the same bus share the same client and mutex
22
+ * - Slave ID is set dynamically before each operation
23
+ * - No more hardcoded slave IDs that affect all devices on a bus
24
+ *
25
+ * IMPORTANT: Shared Resource Ownership
26
+ * Multiple SlaveTransport instances share the same client and mutex. This is
27
+ * intentional and correct:
28
+ * - Shared client: Avoids port contention (can't open serial port twice)
29
+ * - Shared mutex: Ensures serialized access to the bus
30
+ * - SlaveTransport.close(): Does not close shared client (use closeAll() for cleanup)
23
31
  */
24
32
  class TransportManager {
25
33
  constructor() {
26
- this.transports = new Map();
34
+ this.connections = new Map();
27
35
  }
28
36
  /**
29
37
  * Get or create a transport for the given configuration.
30
- * Returns mutex-wrapped shared transport if one exists for the same connection.
38
+ * Returns a new SlaveTransport instance bound to the slave ID in the config.
39
+ * Multiple devices on the same physical connection share the same client and mutex.
31
40
  *
32
41
  * @param config - RTU or TCP transport configuration
33
- * @returns Transport instance wrapped with mutex for thread-safe operations
42
+ * @returns SlaveTransport instance for the specific slave device
34
43
  */
35
44
  async getTransport(config) {
36
- const key = this.getConnectionKey(config);
45
+ const key = this.getPhysicalConnectionKey(config);
37
46
  const isRTU = this.isRTUConfig(config);
38
- // For RTU, reuse existing transport if available
39
- if (isRTU) {
40
- const entry = this.transports.get(key);
41
- if (entry) {
42
- return entry.wrappedTransport;
43
- }
44
- // Create new RTU transport with mutex wrapper
45
- const rawTransport = await (0, factory_js_1.createTransport)(config);
46
- const mutex = new async_mutex_1.Mutex();
47
- const wrappedTransport = new mutex_transport_js_1.MutexTransport(rawTransport, mutex);
48
- const newEntry = {
49
- rawTransport,
50
- wrappedTransport,
51
- mutex,
47
+ // Get or create the shared connection
48
+ let entry = this.connections.get(key);
49
+ if (!entry) {
50
+ // Create new client for this physical connection
51
+ const client = isRTU ? await this.createRTUClient(config) : await this.createTCPClient(config);
52
+ entry = {
53
+ client,
54
+ mutex: new async_mutex_1.Mutex(),
52
55
  config,
53
- isRTU: true,
56
+ isRTU,
54
57
  };
55
- this.transports.set(key, newEntry);
56
- return wrappedTransport;
58
+ this.connections.set(key, entry);
57
59
  }
58
- // For TCP, reuse existing transport if available
59
- // TCP is pooled like RTU because many devices support only one connection
60
- // or process requests sequentially even with multiple connections
61
- const entry = this.transports.get(key);
62
- if (entry) {
63
- return entry.wrappedTransport;
64
- }
65
- // Create new TCP transport with mutex wrapper
66
- // Mutex prevents concurrent requests that could cause timeouts or errors
67
- const rawTransport = await (0, factory_js_1.createTransport)(config);
68
- const mutex = new async_mutex_1.Mutex();
69
- const wrappedTransport = new mutex_transport_js_1.MutexTransport(rawTransport, mutex);
70
- const newEntry = {
71
- rawTransport,
72
- wrappedTransport,
73
- mutex,
74
- config,
75
- isRTU: false,
76
- };
77
- this.transports.set(key, newEntry);
78
- return wrappedTransport;
60
+ // Return a new SlaveTransport for this specific slave
61
+ return new slave_transport_js_1.SlaveTransport(config.slaveId, entry.client, entry.mutex, config.maxRetries ?? 3, config.logger);
79
62
  }
80
63
  /**
81
- * Get statistics about managed transports
64
+ * Get statistics about managed connections
82
65
  *
83
66
  * @returns Transport statistics
84
67
  */
85
68
  getStats() {
86
- const entries = Array.from(this.transports.values());
69
+ const entries = Array.from(this.connections.values());
87
70
  return {
88
71
  totalTransports: entries.length,
89
72
  rtuTransports: entries.filter((e) => e.isRTU).length,
@@ -91,37 +74,71 @@ class TransportManager {
91
74
  };
92
75
  }
93
76
  /**
94
- * Close all managed transports and clear the pool.
77
+ * Close all managed connections and clear the pool.
95
78
  * Errors during close are logged but do not stop the process.
96
79
  */
97
80
  async closeAll() {
98
- const closePromises = Array.from(this.transports.values()).map(async (entry) => {
81
+ const closePromises = Array.from(this.connections.values()).map(async (entry) => {
99
82
  try {
100
- await entry.rawTransport.close();
83
+ await new Promise((resolve) => {
84
+ entry.client.close(resolve);
85
+ });
101
86
  }
102
87
  catch (error) {
103
- // Log but don't throw - we want to close all transports
104
- console.error('Error closing transport:', error);
88
+ // Log but don't throw - we want to close all connections
89
+ console.error('Error closing connection:', error);
105
90
  }
106
91
  });
107
92
  await Promise.all(closePromises);
108
- this.transports.clear();
93
+ this.connections.clear();
109
94
  }
110
95
  /**
111
- * Generate a unique key for a transport configuration.
96
+ * Generate a unique key for a physical connection.
97
+ * Excludes slave ID so multiple devices on the same bus share a connection.
112
98
  * For RTU: Key includes all bus parameters (port, baud, parity, etc.)
113
99
  * For TCP: Key includes host and port
114
100
  *
115
101
  * @param config - Transport configuration
116
- * @returns Connection key string
102
+ * @returns Physical connection key string
117
103
  */
118
- getConnectionKey(config) {
104
+ getPhysicalConnectionKey(config) {
119
105
  if (this.isRTUConfig(config)) {
120
106
  return `rtu:${config.port}:${config.baudRate}:${config.dataBits}:${config.parity}:${config.stopBits}`;
121
107
  }
122
108
  // TCP config - safe to access host/port because isRTUConfig returned false
123
109
  return `tcp:${config.host}:${config.port ?? 502}`;
124
110
  }
111
+ /**
112
+ * Create and configure an RTU modbus-serial client.
113
+ * Does NOT set slave ID - that's handled by SlaveTransport.
114
+ *
115
+ * @param config - RTU configuration
116
+ * @returns Connected ModbusRTU client
117
+ */
118
+ async createRTUClient(config) {
119
+ const client = new modbus_serial_1.default();
120
+ await client.connectRTUBuffered(config.port, {
121
+ baudRate: config.baudRate,
122
+ dataBits: config.dataBits,
123
+ parity: config.parity,
124
+ stopBits: config.stopBits,
125
+ });
126
+ client.setTimeout(config.timeout ?? 1000);
127
+ return client;
128
+ }
129
+ /**
130
+ * Create and configure a TCP modbus-serial client.
131
+ * Does NOT set slave ID - that's handled by SlaveTransport.
132
+ *
133
+ * @param config - TCP configuration
134
+ * @returns Connected ModbusRTU client
135
+ */
136
+ async createTCPClient(config) {
137
+ const client = new modbus_serial_1.default();
138
+ await client.connectTCP(config.host, { port: config.port ?? 502 });
139
+ client.setTimeout(config.timeout ?? 1000);
140
+ return client;
141
+ }
125
142
  /**
126
143
  * Type guard to check if config is RTU
127
144
  *
@@ -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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"}
@@ -0,0 +1,61 @@
1
+ import type { Transport } from '@ya-modbus/driver-types';
2
+ import type { Mutex } from 'async-mutex';
3
+ import type ModbusRTU from 'modbus-serial';
4
+ import { type RetryLogger } from './retry.js';
5
+ /**
6
+ * SlaveTransport wraps a shared ModbusRTU client with slave-specific addressing.
7
+ *
8
+ * Multiple SlaveTransport instances can share the same physical connection (serial port or TCP),
9
+ * each communicating with a different slave device. The slave ID is set before each operation
10
+ * to ensure requests are directed to the correct device.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const client = new ModbusRTU()
15
+ * await client.connectRTUBuffered('/dev/ttyUSB0', { baudRate: 9600 })
16
+ * const mutex = new Mutex()
17
+ *
18
+ * // Two devices on the same serial port
19
+ * const device1 = new SlaveTransport(1, client, mutex, 3)
20
+ * const device2 = new SlaveTransport(2, client, mutex, 3)
21
+ *
22
+ * // Each device talks to its own slave ID
23
+ * await device1.readHoldingRegisters(0, 10) // Reads from slave 1
24
+ * await device2.readHoldingRegisters(0, 10) // Reads from slave 2
25
+ * ```
26
+ */
27
+ export declare class SlaveTransport implements Transport {
28
+ private readonly slaveId;
29
+ private readonly client;
30
+ private readonly mutex;
31
+ private readonly maxRetries;
32
+ private readonly logger?;
33
+ /**
34
+ * @param slaveId - Modbus slave/unit ID for this device
35
+ * @param client - Shared ModbusRTU client instance
36
+ * @param mutex - Shared mutex for serializing operations on the bus
37
+ * @param maxRetries - Maximum retry attempts for failed operations (default: 3)
38
+ * @param logger - Optional callback to log retry attempts
39
+ */
40
+ constructor(slaveId: number, client: ModbusRTU, mutex: Mutex, maxRetries?: number, logger?: RetryLogger | undefined);
41
+ readHoldingRegisters(address: number, count: number): Promise<Buffer>;
42
+ readInputRegisters(address: number, count: number): Promise<Buffer>;
43
+ readCoils(address: number, count: number): Promise<Buffer>;
44
+ readDiscreteInputs(address: number, count: number): Promise<Buffer>;
45
+ writeSingleRegister(address: number, value: number): Promise<void>;
46
+ writeMultipleRegisters(address: number, values: Buffer): Promise<void>;
47
+ writeSingleCoil(address: number, value: boolean): Promise<void>;
48
+ writeMultipleCoils(address: number, values: Buffer): Promise<void>;
49
+ /**
50
+ * Close the underlying client connection.
51
+ *
52
+ * IMPORTANT: This method does not use mutex protection and should only
53
+ * be called during shutdown via TransportManager.closeAll(). Calling
54
+ * this while operations are in progress may cause connection errors.
55
+ *
56
+ * Individual SlaveTransport instances should NOT call close() directly
57
+ * as the client is shared across multiple devices on the same bus.
58
+ */
59
+ close(): Promise<void>;
60
+ }
61
+ //# sourceMappingURL=slave-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slave-transport.d.ts","sourceRoot":"","sources":["../../../src/slave-transport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AAExD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,cAAe,YAAW,SAAS;IAS5C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAZ1B;;;;;;OAMG;gBAEgB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,EACZ,UAAU,GAAE,MAAU,EACtB,MAAM,CAAC,EAAE,WAAW,YAAA;IAGjC,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcrE,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAc1D,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAcnE,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAalE,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatE,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAa/D,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxE;;;;;;;;;OASG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAM7B"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SlaveTransport = void 0;
4
+ const retry_js_1 = require("./retry.js");
5
+ /**
6
+ * SlaveTransport wraps a shared ModbusRTU client with slave-specific addressing.
7
+ *
8
+ * Multiple SlaveTransport instances can share the same physical connection (serial port or TCP),
9
+ * each communicating with a different slave device. The slave ID is set before each operation
10
+ * to ensure requests are directed to the correct device.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const client = new ModbusRTU()
15
+ * await client.connectRTUBuffered('/dev/ttyUSB0', { baudRate: 9600 })
16
+ * const mutex = new Mutex()
17
+ *
18
+ * // Two devices on the same serial port
19
+ * const device1 = new SlaveTransport(1, client, mutex, 3)
20
+ * const device2 = new SlaveTransport(2, client, mutex, 3)
21
+ *
22
+ * // Each device talks to its own slave ID
23
+ * await device1.readHoldingRegisters(0, 10) // Reads from slave 1
24
+ * await device2.readHoldingRegisters(0, 10) // Reads from slave 2
25
+ * ```
26
+ */
27
+ class SlaveTransport {
28
+ /**
29
+ * @param slaveId - Modbus slave/unit ID for this device
30
+ * @param client - Shared ModbusRTU client instance
31
+ * @param mutex - Shared mutex for serializing operations on the bus
32
+ * @param maxRetries - Maximum retry attempts for failed operations (default: 3)
33
+ * @param logger - Optional callback to log retry attempts
34
+ */
35
+ constructor(slaveId, client, mutex, maxRetries = 3, logger) {
36
+ this.slaveId = slaveId;
37
+ this.client = client;
38
+ this.mutex = mutex;
39
+ this.maxRetries = maxRetries;
40
+ this.logger = logger;
41
+ }
42
+ async readHoldingRegisters(address, count) {
43
+ return this.mutex.runExclusive(async () => {
44
+ return (0, retry_js_1.withRetry)(async () => {
45
+ this.client.setID(this.slaveId);
46
+ const result = await this.client.readHoldingRegisters(address, count);
47
+ return result.buffer;
48
+ }, this.maxRetries, this.logger);
49
+ });
50
+ }
51
+ async readInputRegisters(address, count) {
52
+ return this.mutex.runExclusive(async () => {
53
+ return (0, retry_js_1.withRetry)(async () => {
54
+ this.client.setID(this.slaveId);
55
+ const result = await this.client.readInputRegisters(address, count);
56
+ return result.buffer;
57
+ }, this.maxRetries, this.logger);
58
+ });
59
+ }
60
+ async readCoils(address, count) {
61
+ return this.mutex.runExclusive(async () => {
62
+ return (0, retry_js_1.withRetry)(async () => {
63
+ this.client.setID(this.slaveId);
64
+ const result = await this.client.readCoils(address, count);
65
+ return result.buffer;
66
+ }, this.maxRetries, this.logger);
67
+ });
68
+ }
69
+ async readDiscreteInputs(address, count) {
70
+ return this.mutex.runExclusive(async () => {
71
+ return (0, retry_js_1.withRetry)(async () => {
72
+ this.client.setID(this.slaveId);
73
+ const result = await this.client.readDiscreteInputs(address, count);
74
+ return result.buffer;
75
+ }, this.maxRetries, this.logger);
76
+ });
77
+ }
78
+ async writeSingleRegister(address, value) {
79
+ return this.mutex.runExclusive(async () => {
80
+ return (0, retry_js_1.withRetry)(async () => {
81
+ this.client.setID(this.slaveId);
82
+ await this.client.writeRegister(address, value);
83
+ }, this.maxRetries, this.logger);
84
+ });
85
+ }
86
+ async writeMultipleRegisters(address, values) {
87
+ return this.mutex.runExclusive(async () => {
88
+ return (0, retry_js_1.withRetry)(async () => {
89
+ this.client.setID(this.slaveId);
90
+ await this.client.writeRegisters(address, values);
91
+ }, this.maxRetries, this.logger);
92
+ });
93
+ }
94
+ async writeSingleCoil(address, value) {
95
+ return this.mutex.runExclusive(async () => {
96
+ return (0, retry_js_1.withRetry)(async () => {
97
+ this.client.setID(this.slaveId);
98
+ await this.client.writeCoil(address, value);
99
+ }, this.maxRetries, this.logger);
100
+ });
101
+ }
102
+ async writeMultipleCoils(address, values) {
103
+ return this.mutex.runExclusive(async () => {
104
+ return (0, retry_js_1.withRetry)(async () => {
105
+ this.client.setID(this.slaveId);
106
+ // Convert Buffer to boolean array
107
+ const bools = [];
108
+ for (let i = 0; i < values.length * 8; i++) {
109
+ const byteIndex = Math.floor(i / 8);
110
+ const bitIndex = i % 8;
111
+ const byte = values[byteIndex];
112
+ bools.push((byte & (1 << bitIndex)) !== 0);
113
+ }
114
+ await this.client.writeCoils(address, bools);
115
+ }, this.maxRetries, this.logger);
116
+ });
117
+ }
118
+ /**
119
+ * Close the underlying client connection.
120
+ *
121
+ * IMPORTANT: This method does not use mutex protection and should only
122
+ * be called during shutdown via TransportManager.closeAll(). Calling
123
+ * this while operations are in progress may cause connection errors.
124
+ *
125
+ * Individual SlaveTransport instances should NOT call close() directly
126
+ * as the client is shared across multiple devices on the same bus.
127
+ */
128
+ async close() {
129
+ // Don't use mutex for close operation
130
+ return new Promise((resolve) => {
131
+ this.client.close(resolve);
132
+ });
133
+ }
134
+ }
135
+ exports.SlaveTransport = SlaveTransport;
136
+ //# sourceMappingURL=slave-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slave-transport.js","sourceRoot":"","sources":["../../../src/slave-transport.ts"],"names":[],"mappings":"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"}