@ya-modbus/cli 0.4.1-refactor-scope-driver-packages.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 (85) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +674 -0
  3. package/README.md +612 -0
  4. package/dist/bin/ya-modbus.d.ts +9 -0
  5. package/dist/bin/ya-modbus.d.ts.map +1 -0
  6. package/dist/bin/ya-modbus.js +10 -0
  7. package/dist/bin/ya-modbus.js.map +1 -0
  8. package/dist/src/commands/discover.d.ts +25 -0
  9. package/dist/src/commands/discover.d.ts.map +1 -0
  10. package/dist/src/commands/discover.js +160 -0
  11. package/dist/src/commands/discover.js.map +1 -0
  12. package/dist/src/commands/list-devices.d.ts +21 -0
  13. package/dist/src/commands/list-devices.d.ts.map +1 -0
  14. package/dist/src/commands/list-devices.js +75 -0
  15. package/dist/src/commands/list-devices.js.map +1 -0
  16. package/dist/src/commands/read.d.ts +25 -0
  17. package/dist/src/commands/read.d.ts.map +1 -0
  18. package/dist/src/commands/read.js +76 -0
  19. package/dist/src/commands/read.js.map +1 -0
  20. package/dist/src/commands/show-defaults.d.ts +21 -0
  21. package/dist/src/commands/show-defaults.d.ts.map +1 -0
  22. package/dist/src/commands/show-defaults.js +48 -0
  23. package/dist/src/commands/show-defaults.js.map +1 -0
  24. package/dist/src/commands/write.d.ts +26 -0
  25. package/dist/src/commands/write.d.ts.map +1 -0
  26. package/dist/src/commands/write.js +61 -0
  27. package/dist/src/commands/write.js.map +1 -0
  28. package/dist/src/discovery/constants.d.ts +37 -0
  29. package/dist/src/discovery/constants.d.ts.map +1 -0
  30. package/dist/src/discovery/constants.js +45 -0
  31. package/dist/src/discovery/constants.js.map +1 -0
  32. package/dist/src/discovery/device-identifier.d.ts +52 -0
  33. package/dist/src/discovery/device-identifier.d.ts.map +1 -0
  34. package/dist/src/discovery/device-identifier.js +193 -0
  35. package/dist/src/discovery/device-identifier.js.map +1 -0
  36. package/dist/src/discovery/parameter-generator-utils.d.ts +29 -0
  37. package/dist/src/discovery/parameter-generator-utils.d.ts.map +1 -0
  38. package/dist/src/discovery/parameter-generator-utils.js +59 -0
  39. package/dist/src/discovery/parameter-generator-utils.js.map +1 -0
  40. package/dist/src/discovery/parameter-generator.d.ts +97 -0
  41. package/dist/src/discovery/parameter-generator.d.ts.map +1 -0
  42. package/dist/src/discovery/parameter-generator.js +184 -0
  43. package/dist/src/discovery/parameter-generator.js.map +1 -0
  44. package/dist/src/discovery/progress.d.ts +24 -0
  45. package/dist/src/discovery/progress.d.ts.map +1 -0
  46. package/dist/src/discovery/progress.js +57 -0
  47. package/dist/src/discovery/progress.js.map +1 -0
  48. package/dist/src/discovery/scanner.d.ts +46 -0
  49. package/dist/src/discovery/scanner.d.ts.map +1 -0
  50. package/dist/src/discovery/scanner.js +143 -0
  51. package/dist/src/discovery/scanner.js.map +1 -0
  52. package/dist/src/formatters/discovery-results.d.ts +10 -0
  53. package/dist/src/formatters/discovery-results.d.ts.map +1 -0
  54. package/dist/src/formatters/discovery-results.js +57 -0
  55. package/dist/src/formatters/discovery-results.js.map +1 -0
  56. package/dist/src/formatters/json.d.ts +30 -0
  57. package/dist/src/formatters/json.d.ts.map +1 -0
  58. package/dist/src/formatters/json.js +33 -0
  59. package/dist/src/formatters/json.js.map +1 -0
  60. package/dist/src/formatters/performance.d.ts +19 -0
  61. package/dist/src/formatters/performance.d.ts.map +1 -0
  62. package/dist/src/formatters/performance.js +24 -0
  63. package/dist/src/formatters/performance.js.map +1 -0
  64. package/dist/src/formatters/table.d.ts +10 -0
  65. package/dist/src/formatters/table.d.ts.map +1 -0
  66. package/dist/src/formatters/table.js +91 -0
  67. package/dist/src/formatters/table.js.map +1 -0
  68. package/dist/src/index.d.ts +5 -0
  69. package/dist/src/index.d.ts.map +1 -0
  70. package/dist/src/index.js +154 -0
  71. package/dist/src/index.js.map +1 -0
  72. package/dist/src/utils/commands.d.ts +191 -0
  73. package/dist/src/utils/commands.d.ts.map +1 -0
  74. package/dist/src/utils/commands.js +400 -0
  75. package/dist/src/utils/commands.js.map +1 -0
  76. package/dist/src/utils/object-utils.d.ts +20 -0
  77. package/dist/src/utils/object-utils.d.ts.map +1 -0
  78. package/dist/src/utils/object-utils.js +28 -0
  79. package/dist/src/utils/object-utils.js.map +1 -0
  80. package/dist/src/utils/validation.d.ts +70 -0
  81. package/dist/src/utils/validation.d.ts.map +1 -0
  82. package/dist/src/utils/validation.js +158 -0
  83. package/dist/src/utils/validation.js.map +1 -0
  84. package/dist/tsconfig.tsbuildinfo +1 -0
  85. package/package.json +63 -0
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Standard Modbus baud rates for thorough scanning
3
+ * Ordered by commonality (most common first)
4
+ */
5
+ export const STANDARD_BAUD_RATES = [
6
+ 9600, // Most common
7
+ 19200, // Modbus spec default
8
+ 14400,
9
+ 38400,
10
+ 57600,
11
+ 115200,
12
+ 4800, // Less common
13
+ 2400, // Legacy
14
+ ];
15
+ /**
16
+ * Common baud rates for quick scanning
17
+ */
18
+ export const COMMON_BAUD_RATES = [9600, 19200];
19
+ /**
20
+ * Standard Modbus parity settings
21
+ * Ordered by commonality
22
+ */
23
+ export const STANDARD_PARITY = ['none', 'even', 'odd'];
24
+ /**
25
+ * Standard data bits options
26
+ */
27
+ export const STANDARD_DATA_BITS = [8, 7];
28
+ /**
29
+ * Common data bits for quick scanning
30
+ */
31
+ export const COMMON_DATA_BITS = [8];
32
+ /**
33
+ * Standard stop bits options
34
+ */
35
+ export const STANDARD_STOP_BITS = [1, 2];
36
+ /**
37
+ * Common stop bits for quick scanning
38
+ */
39
+ export const COMMON_STOP_BITS = [1];
40
+ /**
41
+ * Valid Modbus slave address range (0 is broadcast, 248-255 reserved)
42
+ */
43
+ export const MIN_SLAVE_ID = 1;
44
+ export const MAX_SLAVE_ID = 247;
45
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/discovery/constants.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAwB;IACtD,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,sBAAsB;IAC7B,KAAK;IACL,KAAK;IACL,KAAK;IACL,MAAM;IACN,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,SAAS;CACP,CAAA;AAEV;;GAEG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAwB,CAAC,IAAI,EAAE,KAAK,CAAU,CAAA;AAE5E;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAU,CAAA;AAElF;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,CAAC,CAAC,EAAE,CAAC,CAAU,CAAA;AAEtE;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwB,CAAC,CAAC,CAAU,CAAA;AAEjE;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,CAAC,CAAC,EAAE,CAAC,CAAU,CAAA;AAEtE;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAwB,CAAC,CAAC,CAAU,CAAA;AAEjE;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAA;AAC7B,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA"}
@@ -0,0 +1,52 @@
1
+ import type ModbusRTU from 'modbus-serial';
2
+ /**
3
+ * Device identification result from discovery attempt
4
+ * Provides comprehensive information about device presence and capabilities
5
+ */
6
+ export interface DeviceIdentificationResult {
7
+ /** Whether a Modbus device is present at this address/configuration */
8
+ present: boolean;
9
+ /** Response time in milliseconds */
10
+ responseTimeMs: number;
11
+ /** Vendor/manufacturer name (from FC43) */
12
+ vendorName?: string;
13
+ /** Product code/identifier (from FC43) */
14
+ productCode?: string;
15
+ /** Model name (from FC43) */
16
+ modelName?: string;
17
+ /** Firmware/hardware revision (from FC43) */
18
+ revision?: string;
19
+ /** Whether device supports FC43 (Read Device Identification) */
20
+ supportsFC43?: boolean;
21
+ /** Device present but returned Modbus exception code */
22
+ exceptionCode?: number;
23
+ /** Request timed out (no response) */
24
+ timeout?: boolean;
25
+ /** CRC check failed (wrong serial parameters) */
26
+ crcError?: boolean;
27
+ }
28
+ /**
29
+ * Attempt to identify a Modbus device at the current client configuration
30
+ *
31
+ * Uses FC43 (Read Device Identification) to probe for device presence.
32
+ * Any Modbus response (including exceptions) indicates a device is present.
33
+ * Only timeouts and CRC errors mean no device with these parameters.
34
+ *
35
+ * @param client - Configured ModbusRTU client (address, serial params, and timeout already set)
36
+ * @returns Device identification result
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const client = new ModbusRTU()
41
+ * await client.connectRTUBuffered('/dev/ttyUSB0', { baudRate: 9600 })
42
+ * client.setID(1)
43
+ * client.setTimeout(1000)
44
+ *
45
+ * const result = await identifyDevice(client)
46
+ * if (result.present) {
47
+ * console.log(`Found device: ${result.vendorName ?? 'Unknown'}`)
48
+ * }
49
+ * ```
50
+ */
51
+ export declare function identifyDevice(client: ModbusRTU): Promise<DeviceIdentificationResult>;
52
+ //# sourceMappingURL=device-identifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-identifier.d.ts","sourceRoot":"","sources":["../../../src/discovery/device-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,eAAe,CAAA;AAsC1C;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;IAEhB,oCAAoC;IACpC,cAAc,EAAE,MAAM,CAAA;IAGtB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAElB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAA;IAGjB,gEAAgE;IAChE,YAAY,CAAC,EAAE,OAAO,CAAA;IAGtB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAA;IAEjB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAgID;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAgC3F"}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * FC43 Read Device ID Code values (MEI type)
3
+ * See Modbus specification 6.21 - Read Device Identification (FC43/0x2B)
4
+ */
5
+ const FC43_READ_DEVICE_ID_CODE = {
6
+ /** Basic device identification (VendorName, ProductCode, Revision) */
7
+ BASIC: 1,
8
+ /** Regular device identification (adds additional standard objects) */
9
+ REGULAR: 2,
10
+ /** Extended device identification (includes vendor-specific objects) */
11
+ EXTENDED: 3,
12
+ /** Specific individual object request */
13
+ SPECIFIC: 4,
14
+ };
15
+ /**
16
+ * FC43 Object ID values for device identification
17
+ * See Modbus specification 6.21 - Read Device Identification object IDs
18
+ */
19
+ const FC43_OBJECT_ID = {
20
+ /** Vendor/manufacturer name */
21
+ VENDOR_NAME: 0,
22
+ /** Product code/identifier */
23
+ PRODUCT_CODE: 1,
24
+ /** Major/minor revision number */
25
+ MAJOR_MINOR_REVISION: 2,
26
+ /** Vendor URL */
27
+ VENDOR_URL: 3,
28
+ /** Product name/model */
29
+ PRODUCT_NAME: 4,
30
+ /** Model name */
31
+ MODEL_NAME: 5,
32
+ /** User application name */
33
+ USER_APPLICATION_NAME: 6,
34
+ };
35
+ /**
36
+ * Check if error is a Modbus exception (device present but unsupported function/address)
37
+ */
38
+ function isModbusException(error) {
39
+ if (error && typeof error === 'object' && 'modbusCode' in error) {
40
+ const code = error.modbusCode;
41
+ return typeof code === 'number' ? code : undefined;
42
+ }
43
+ return undefined;
44
+ }
45
+ /**
46
+ * Check if error is a timeout (device not responding)
47
+ *
48
+ * The modbus-serial library can return timeout errors in different formats:
49
+ * - Error with message containing "timeout" (most common)
50
+ * - Error with errno='ETIMEDOUT' (serial port timeout)
51
+ * - Error with code='ETIMEDOUT' (TCP socket timeout)
52
+ *
53
+ * We check all three formats to handle different error sources reliably.
54
+ */
55
+ function isTimeout(error) {
56
+ if (!error || typeof error !== 'object') {
57
+ return false;
58
+ }
59
+ const err = error;
60
+ return Boolean((err.message?.toLowerCase().includes('timeout') ?? false) ||
61
+ err.errno === 'ETIMEDOUT' ||
62
+ err.code === 'ETIMEDOUT');
63
+ }
64
+ /**
65
+ * Check if error is a CRC error (wrong serial parameters)
66
+ *
67
+ * The modbus-serial library can return CRC errors in different formats:
68
+ * - Error with message containing "crc" (most common, e.g., "CRC error")
69
+ * - Error with errno='CRC' (serial port CRC validation failure)
70
+ *
71
+ * CRC errors indicate wrong serial parameters (baud rate, parity, etc.)
72
+ * and are distinguished from timeouts to guide parameter tuning.
73
+ */
74
+ function isCRCError(error) {
75
+ if (!error || typeof error !== 'object') {
76
+ return false;
77
+ }
78
+ const err = error;
79
+ return Boolean((err.message?.toLowerCase().includes('crc') ?? false) || err.errno === 'CRC');
80
+ }
81
+ /**
82
+ * Try to identify device using FC43 (Read Device Identification)
83
+ *
84
+ * FC43/14 is the standard MEI (Modbus Encapsulated Interface) for device identification.
85
+ * Not all devices support this - device-level support is handled via exception codes.
86
+ *
87
+ * Any Modbus response (including exceptions) indicates a device is present.
88
+ * Throws for timeout/CRC errors which indicate no device with these parameters.
89
+ *
90
+ * @param client - Configured ModbusRTU client
91
+ * @param startTime - Start time for response time calculation
92
+ * @throws Error for timeout, CRC, or other communication failures
93
+ * @returns DeviceIdentificationResult with present: true guaranteed
94
+ */
95
+ async function tryFC43(client, startTime) {
96
+ try {
97
+ const response = await client.readDeviceIdentification(FC43_READ_DEVICE_ID_CODE.BASIC, FC43_OBJECT_ID.VENDOR_NAME);
98
+ // Build result object with response time
99
+ const result = {
100
+ present: true,
101
+ responseTimeMs: performance.now() - startTime,
102
+ supportsFC43: true,
103
+ };
104
+ // modbus-serial returns { data: { 0: "vendor", 1: "product", 2: "revision" }, conformityLevel }
105
+ if (response.data && typeof response.data === 'object') {
106
+ const data = response.data;
107
+ const vendorName = data[FC43_OBJECT_ID.VENDOR_NAME];
108
+ if (vendorName !== undefined) {
109
+ result.vendorName = vendorName;
110
+ }
111
+ const productCode = data[FC43_OBJECT_ID.PRODUCT_CODE];
112
+ if (productCode !== undefined) {
113
+ result.productCode = productCode;
114
+ }
115
+ const revision = data[FC43_OBJECT_ID.MAJOR_MINOR_REVISION];
116
+ if (revision !== undefined) {
117
+ result.revision = revision;
118
+ }
119
+ // Note: modelName requires requesting FC43_OBJECT_ID.MODEL_NAME specifically
120
+ }
121
+ return result;
122
+ }
123
+ catch (error) {
124
+ const responseTime = performance.now() - startTime;
125
+ const exceptionCode = isModbusException(error);
126
+ if (exceptionCode !== undefined) {
127
+ // Exception means device is present but doesn't support FC43 or the specific registers
128
+ // This is still a successful device detection - we found a device, just don't know what it is
129
+ return {
130
+ present: true,
131
+ responseTimeMs: responseTime,
132
+ supportsFC43: false,
133
+ exceptionCode,
134
+ };
135
+ }
136
+ // Timeout, CRC, or other communication error - let caller handle it
137
+ throw error;
138
+ }
139
+ }
140
+ /**
141
+ * Attempt to identify a Modbus device at the current client configuration
142
+ *
143
+ * Uses FC43 (Read Device Identification) to probe for device presence.
144
+ * Any Modbus response (including exceptions) indicates a device is present.
145
+ * Only timeouts and CRC errors mean no device with these parameters.
146
+ *
147
+ * @param client - Configured ModbusRTU client (address, serial params, and timeout already set)
148
+ * @returns Device identification result
149
+ *
150
+ * @example
151
+ * ```typescript
152
+ * const client = new ModbusRTU()
153
+ * await client.connectRTUBuffered('/dev/ttyUSB0', { baudRate: 9600 })
154
+ * client.setID(1)
155
+ * client.setTimeout(1000)
156
+ *
157
+ * const result = await identifyDevice(client)
158
+ * if (result.present) {
159
+ * console.log(`Found device: ${result.vendorName ?? 'Unknown'}`)
160
+ * }
161
+ * ```
162
+ */
163
+ export async function identifyDevice(client) {
164
+ const startTime = performance.now();
165
+ try {
166
+ // Try FC43 (provides device identification)
167
+ return await tryFC43(client, startTime);
168
+ }
169
+ catch (error) {
170
+ // Communication error - classify and return appropriate result
171
+ const responseTime = performance.now() - startTime;
172
+ if (isTimeout(error)) {
173
+ return {
174
+ present: false,
175
+ timeout: true,
176
+ responseTimeMs: responseTime,
177
+ };
178
+ }
179
+ if (isCRCError(error)) {
180
+ return {
181
+ present: false,
182
+ crcError: true,
183
+ responseTimeMs: responseTime,
184
+ };
185
+ }
186
+ // Other error (network, etc.) - treat as not present
187
+ return {
188
+ present: false,
189
+ responseTimeMs: responseTime,
190
+ };
191
+ }
192
+ }
193
+ //# sourceMappingURL=device-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-identifier.js","sourceRoot":"","sources":["../../../src/discovery/device-identifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { BaudRate, DataBits, Parity, StopBits, SupportedSerialConfig } from '@ya-modbus/driver-types';
2
+ import type { DiscoveryStrategy, GeneratorOptions } from './parameter-generator.js';
3
+ /**
4
+ * Get parameter arrays based on strategy and configuration
5
+ */
6
+ export declare function getParameterArrays(strategy: DiscoveryStrategy, supportedConfig?: SupportedSerialConfig): {
7
+ baudRates: readonly BaudRate[];
8
+ parities: readonly Parity[];
9
+ dataBits: readonly DataBits[];
10
+ stopBits: readonly StopBits[];
11
+ addressRange: readonly [number, number];
12
+ };
13
+ /**
14
+ * Count the total number of parameter combinations without materializing them
15
+ *
16
+ * This is much more efficient than Array.from(generateParameterCombinations()).length
17
+ * as it calculates the count mathematically instead of generating all combinations.
18
+ *
19
+ * @param options - Generator options
20
+ * @returns Total number of combinations that will be generated
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const count = countParameterCombinations({ strategy: 'quick' })
25
+ * console.log(`Will test ${count} combinations`) // Will test 3952 combinations
26
+ * ```
27
+ */
28
+ export declare function countParameterCombinations(options: GeneratorOptions): number;
29
+ //# sourceMappingURL=parameter-generator-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-generator-utils.d.ts","sourceRoot":"","sources":["../../../src/discovery/parameter-generator-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,qBAAqB,EACtB,MAAM,yBAAyB,CAAA;AAahC,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAEnF;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,iBAAiB,EAC3B,eAAe,CAAC,EAAE,qBAAqB,GACtC;IACD,SAAS,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC9B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC7B,QAAQ,EAAE,SAAS,QAAQ,EAAE,CAAA;IAC7B,YAAY,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC,CA+BA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAc5E"}
@@ -0,0 +1,59 @@
1
+ import { COMMON_BAUD_RATES, COMMON_DATA_BITS, COMMON_STOP_BITS, MAX_SLAVE_ID, MIN_SLAVE_ID, STANDARD_BAUD_RATES, STANDARD_DATA_BITS, STANDARD_PARITY, STANDARD_STOP_BITS, } from './constants.js';
2
+ /**
3
+ * Get parameter arrays based on strategy and configuration
4
+ */
5
+ export function getParameterArrays(strategy, supportedConfig) {
6
+ if (strategy === 'quick' && supportedConfig) {
7
+ // Quick mode with driver config: use supported values or fall back to common
8
+ return {
9
+ baudRates: supportedConfig.validBaudRates ?? COMMON_BAUD_RATES,
10
+ parities: supportedConfig.validParity ?? STANDARD_PARITY,
11
+ dataBits: supportedConfig.validDataBits ?? STANDARD_DATA_BITS,
12
+ stopBits: supportedConfig.validStopBits ?? STANDARD_STOP_BITS,
13
+ addressRange: supportedConfig.validAddressRange ?? [MIN_SLAVE_ID, MAX_SLAVE_ID],
14
+ };
15
+ }
16
+ if (strategy === 'thorough') {
17
+ // Thorough mode: use supported config if provided, otherwise standard Modbus
18
+ return {
19
+ baudRates: supportedConfig?.validBaudRates ?? STANDARD_BAUD_RATES,
20
+ parities: supportedConfig?.validParity ?? STANDARD_PARITY,
21
+ dataBits: supportedConfig?.validDataBits ?? STANDARD_DATA_BITS,
22
+ stopBits: supportedConfig?.validStopBits ?? STANDARD_STOP_BITS,
23
+ addressRange: supportedConfig?.validAddressRange ?? [MIN_SLAVE_ID, MAX_SLAVE_ID],
24
+ };
25
+ }
26
+ // Quick mode without driver config: use common parameters
27
+ return {
28
+ baudRates: COMMON_BAUD_RATES,
29
+ parities: STANDARD_PARITY,
30
+ dataBits: COMMON_DATA_BITS,
31
+ stopBits: COMMON_STOP_BITS,
32
+ addressRange: [MIN_SLAVE_ID, MAX_SLAVE_ID],
33
+ };
34
+ }
35
+ /**
36
+ * Count the total number of parameter combinations without materializing them
37
+ *
38
+ * This is much more efficient than Array.from(generateParameterCombinations()).length
39
+ * as it calculates the count mathematically instead of generating all combinations.
40
+ *
41
+ * @param options - Generator options
42
+ * @returns Total number of combinations that will be generated
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * const count = countParameterCombinations({ strategy: 'quick' })
47
+ * console.log(`Will test ${count} combinations`) // Will test 3952 combinations
48
+ * ```
49
+ */
50
+ export function countParameterCombinations(options) {
51
+ const { strategy, supportedConfig } = options;
52
+ const { baudRates, parities, dataBits, stopBits, addressRange } = getParameterArrays(strategy, supportedConfig);
53
+ // Calculate address count
54
+ const [minId, maxId] = addressRange;
55
+ const addressCount = maxId - minId + 1;
56
+ // Total combinations = addresses × baud rates × parities × data bits × stop bits
57
+ return addressCount * baudRates.length * parities.length * dataBits.length * stopBits.length;
58
+ }
59
+ //# sourceMappingURL=parameter-generator-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-generator-utils.js","sourceRoot":"","sources":["../../../src/discovery/parameter-generator-utils.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,GACnB,MAAM,gBAAgB,CAAA;AAGvB;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAA2B,EAC3B,eAAuC;IAQvC,IAAI,QAAQ,KAAK,OAAO,IAAI,eAAe,EAAE,CAAC;QAC5C,6EAA6E;QAC7E,OAAO;YACL,SAAS,EAAE,eAAe,CAAC,cAAc,IAAI,iBAAiB;YAC9D,QAAQ,EAAE,eAAe,CAAC,WAAW,IAAI,eAAe;YACxD,QAAQ,EAAE,eAAe,CAAC,aAAa,IAAI,kBAAkB;YAC7D,QAAQ,EAAE,eAAe,CAAC,aAAa,IAAI,kBAAkB;YAC7D,YAAY,EAAE,eAAe,CAAC,iBAAiB,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;SAChF,CAAA;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC5B,6EAA6E;QAC7E,OAAO;YACL,SAAS,EAAE,eAAe,EAAE,cAAc,IAAI,mBAAmB;YACjE,QAAQ,EAAE,eAAe,EAAE,WAAW,IAAI,eAAe;YACzD,QAAQ,EAAE,eAAe,EAAE,aAAa,IAAI,kBAAkB;YAC9D,QAAQ,EAAE,eAAe,EAAE,aAAa,IAAI,kBAAkB;YAC9D,YAAY,EAAE,eAAe,EAAE,iBAAiB,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC;SACjF,CAAA;IACH,CAAC;IAED,0DAA0D;IAC1D,OAAO;QACL,SAAS,EAAE,iBAAiB;QAC5B,QAAQ,EAAE,eAAe;QACzB,QAAQ,EAAE,gBAAgB;QAC1B,QAAQ,EAAE,gBAAgB;QAC1B,YAAY,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;KAC3C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAyB;IAClE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAA;IAE7C,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,kBAAkB,CAClF,QAAQ,EACR,eAAe,CAChB,CAAA;IAED,0BAA0B;IAC1B,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,YAAY,CAAA;IACnC,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,CAAC,CAAA;IAEtC,iFAAiF;IACjF,OAAO,YAAY,GAAG,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAA;AAC9F,CAAC"}
@@ -0,0 +1,97 @@
1
+ import type { BaudRate, DataBits, DefaultSerialConfig, Parity, StopBits, SupportedSerialConfig } from '@ya-modbus/driver-types';
2
+ /**
3
+ * Parameter combination for discovery testing
4
+ * Represents a complete set of Modbus RTU serial parameters
5
+ */
6
+ export interface ParameterCombination {
7
+ slaveId: number;
8
+ baudRate: BaudRate;
9
+ parity: Parity;
10
+ dataBits: DataBits;
11
+ stopBits: StopBits;
12
+ }
13
+ /**
14
+ * Discovery strategy type
15
+ *
16
+ * - quick: Tests only driver-supported parameters (5-10 minutes)
17
+ * - thorough: Tests all standard Modbus parameters (30-60 minutes)
18
+ */
19
+ export type DiscoveryStrategy = 'quick' | 'thorough';
20
+ /**
21
+ * Options for parameter combination generation
22
+ */
23
+ export interface GeneratorOptions {
24
+ /** Discovery strategy to use */
25
+ strategy: DiscoveryStrategy;
26
+ /** Driver-provided default configuration (prioritized first) */
27
+ defaultConfig?: DefaultSerialConfig;
28
+ /** Driver-provided supported configuration constraints */
29
+ supportedConfig?: SupportedSerialConfig;
30
+ }
31
+ /**
32
+ * Group of parameter combinations that share the same serial configuration
33
+ */
34
+ export interface ParameterGroup {
35
+ /** Serial parameters shared by all combinations in this group */
36
+ serialParams: {
37
+ baudRate: BaudRate;
38
+ parity: Parity;
39
+ dataBits: DataBits;
40
+ stopBits: StopBits;
41
+ };
42
+ /** All parameter combinations for this serial configuration (different slave IDs) */
43
+ combinations: ParameterCombination[];
44
+ }
45
+ /**
46
+ * Generate parameter combinations grouped by serial configuration
47
+ *
48
+ * This is a memory-efficient alternative to materializing all combinations.
49
+ * Instead of creating all ~1500+ combinations at once, this generator yields
50
+ * groups of ~247 combinations at a time (one per serial config).
51
+ *
52
+ * Each group shares the same serial parameters (baud, parity, data bits, stop bits)
53
+ * but has different slave IDs. This matches how the scanner works - it creates
54
+ * one connection per serial config and tests all slave IDs with that connection.
55
+ *
56
+ * @param options - Generation options
57
+ * @yields Parameter groups to test
58
+ *
59
+ * @example Iterate over groups without materializing all combinations
60
+ * ```typescript
61
+ * for (const group of generateParameterGroups(options)) {
62
+ * // Only this group's ~247 combinations are in memory
63
+ * const { serialParams, combinations } = group
64
+ * // ... use combinations ...
65
+ * }
66
+ * ```
67
+ */
68
+ export declare function generateParameterGroups(options: GeneratorOptions): Generator<ParameterGroup>;
69
+ /**
70
+ * Generate all parameter combinations for Modbus device discovery
71
+ *
72
+ * Produces combinations in priority order:
73
+ * 1. Default configuration (if provided) tested first
74
+ * 2. Common slave addresses (1, 2) before others
75
+ * 3. Common baud rates before exotic ones
76
+ *
77
+ * @param options - Generation options
78
+ * @yields Parameter combinations to test
79
+ *
80
+ * @example Quick discovery with driver config
81
+ * ```typescript
82
+ * const combinations = generateParameterCombinations({
83
+ * strategy: 'quick',
84
+ * defaultConfig: { baudRate: 9600, parity: 'even', ... },
85
+ * supportedConfig: { validBaudRates: [9600, 19200], ... }
86
+ * })
87
+ * ```
88
+ *
89
+ * @example Thorough discovery without driver
90
+ * ```typescript
91
+ * const combinations = generateParameterCombinations({
92
+ * strategy: 'thorough'
93
+ * })
94
+ * ```
95
+ */
96
+ export declare function generateParameterCombinations(options: GeneratorOptions): Generator<ParameterCombination>;
97
+ //# sourceMappingURL=parameter-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-generator.d.ts","sourceRoot":"","sources":["../../../src/discovery/parameter-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EACR,QAAQ,EACR,mBAAmB,EACnB,MAAM,EACN,QAAQ,EACR,qBAAqB,EACtB,MAAM,yBAAyB,CAAA;AAKhC;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,QAAQ,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,UAAU,CAAA;AAEpD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,QAAQ,EAAE,iBAAiB,CAAA;IAE3B,gEAAgE;IAChE,aAAa,CAAC,EAAE,mBAAmB,CAAA;IAEnC,0DAA0D;IAC1D,eAAe,CAAC,EAAE,qBAAqB,CAAA;CACxC;AAqED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,YAAY,EAAE;QACZ,QAAQ,EAAE,QAAQ,CAAA;QAClB,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,QAAQ,CAAA;QAClB,QAAQ,EAAE,QAAQ,CAAA;KACnB,CAAA;IACD,qFAAqF;IACrF,YAAY,EAAE,oBAAoB,EAAE,CAAA;CACrC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAiB,uBAAuB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAC,cAAc,CAAC,CA8C7F;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAiB,6BAA6B,CAC5C,OAAO,EAAE,gBAAgB,GACxB,SAAS,CAAC,oBAAoB,CAAC,CAsCjC"}