jmri-client 4.2.0-beta.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -1
- package/dist/cjs/index.js +2382 -31
- package/dist/esm/index.js +2333 -17
- package/docs/API.md +39 -4
- package/docs/BROWSER.md +4 -4
- package/docs/EXAMPLES.md +42 -0
- package/docs/MIGRATION.md +30 -1
- package/package.json +17 -18
- package/dist/cjs/client.js +0 -366
- package/dist/cjs/core/connection-state-manager.js +0 -84
- package/dist/cjs/core/heartbeat-manager.js +0 -79
- package/dist/cjs/core/index.js +0 -25
- package/dist/cjs/core/message-queue.js +0 -59
- package/dist/cjs/core/reconnection-manager.js +0 -97
- package/dist/cjs/core/websocket-adapter.js +0 -135
- package/dist/cjs/core/websocket-client.js +0 -388
- package/dist/cjs/managers/index.js +0 -25
- package/dist/cjs/managers/light-manager.js +0 -111
- package/dist/cjs/managers/power-manager.js +0 -90
- package/dist/cjs/managers/roster-manager.js +0 -118
- package/dist/cjs/managers/system-connections-manager.js +0 -28
- package/dist/cjs/managers/throttle-manager.js +0 -233
- package/dist/cjs/managers/turnout-manager.js +0 -111
- package/dist/cjs/mocks/index.js +0 -12
- package/dist/cjs/mocks/mock-data.js +0 -237
- package/dist/cjs/mocks/mock-response-manager.js +0 -290
- package/dist/cjs/types/client-options.js +0 -66
- package/dist/cjs/types/events.js +0 -16
- package/dist/cjs/types/index.js +0 -23
- package/dist/cjs/types/jmri-messages.js +0 -95
- package/dist/cjs/types/throttle.js +0 -19
- package/dist/cjs/utils/exponential-backoff.js +0 -40
- package/dist/cjs/utils/index.js +0 -21
- package/dist/cjs/utils/message-id.js +0 -40
- package/dist/esm/client.js +0 -362
- package/dist/esm/core/connection-state-manager.js +0 -80
- package/dist/esm/core/heartbeat-manager.js +0 -75
- package/dist/esm/core/index.js +0 -9
- package/dist/esm/core/message-queue.js +0 -55
- package/dist/esm/core/reconnection-manager.js +0 -93
- package/dist/esm/core/websocket-adapter.js +0 -98
- package/dist/esm/core/websocket-client.js +0 -384
- package/dist/esm/managers/index.js +0 -9
- package/dist/esm/managers/light-manager.js +0 -107
- package/dist/esm/managers/power-manager.js +0 -86
- package/dist/esm/managers/roster-manager.js +0 -114
- package/dist/esm/managers/system-connections-manager.js +0 -24
- package/dist/esm/managers/throttle-manager.js +0 -229
- package/dist/esm/managers/turnout-manager.js +0 -107
- package/dist/esm/mocks/index.js +0 -6
- package/dist/esm/mocks/mock-data.js +0 -234
- package/dist/esm/mocks/mock-response-manager.js +0 -286
- package/dist/esm/types/client-options.js +0 -62
- package/dist/esm/types/events.js +0 -13
- package/dist/esm/types/index.js +0 -7
- package/dist/esm/types/jmri-messages.js +0 -89
- package/dist/esm/types/throttle.js +0 -15
- package/dist/esm/utils/exponential-backoff.js +0 -36
- package/dist/esm/utils/index.js +0 -5
- package/dist/esm/utils/message-id.js +0 -36
package/docs/API.md
CHANGED
|
@@ -65,6 +65,9 @@ client.on('heartbeat:timeout', () => { });
|
|
|
65
65
|
// Get current power state
|
|
66
66
|
const state: PowerState = await client.getPower();
|
|
67
67
|
|
|
68
|
+
// Get power state for a specific hardware connection (see System Connections)
|
|
69
|
+
const state: PowerState = await client.getPower('L'); // LocoNet prefix
|
|
70
|
+
|
|
68
71
|
// PowerState enum values (from JMRI JSON protocol):
|
|
69
72
|
// PowerState.UNKNOWN = 0 (state cannot be determined)
|
|
70
73
|
// PowerState.ON = 2 (power is on)
|
|
@@ -83,10 +86,15 @@ switch (state) {
|
|
|
83
86
|
break;
|
|
84
87
|
}
|
|
85
88
|
|
|
86
|
-
// Set power
|
|
89
|
+
// Set power (all connections, or a specific one)
|
|
87
90
|
await client.setPower(PowerState.ON);
|
|
88
|
-
await client.
|
|
89
|
-
|
|
91
|
+
await client.setPower(PowerState.ON, 'L'); // LocoNet only
|
|
92
|
+
|
|
93
|
+
// Convenience methods — all accept an optional prefix
|
|
94
|
+
await client.powerOn(); // All connections
|
|
95
|
+
await client.powerOn('L'); // LocoNet only
|
|
96
|
+
await client.powerOff(); // All connections
|
|
97
|
+
await client.powerOff('D'); // DCC++ only
|
|
90
98
|
|
|
91
99
|
// Listen for power changes (including UNKNOWN states)
|
|
92
100
|
client.on('power:changed', (state: PowerState) => {
|
|
@@ -96,6 +104,29 @@ client.on('power:changed', (state: PowerState) => {
|
|
|
96
104
|
});
|
|
97
105
|
```
|
|
98
106
|
|
|
107
|
+
## System Connections
|
|
108
|
+
|
|
109
|
+
Discover the hardware connections JMRI has configured and their short prefix strings. Use these prefixes to target power and throttle commands at a specific connection when multiple are active.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// List all available system connections
|
|
113
|
+
const connections: SystemConnectionData[] = await client.getSystemConnections();
|
|
114
|
+
// [
|
|
115
|
+
// { name: 'LocoNet', prefix: 'L', userName: 'LocoNet' },
|
|
116
|
+
// { name: 'DCC++', prefix: 'D' }
|
|
117
|
+
// ]
|
|
118
|
+
|
|
119
|
+
// Use a prefix to target a specific connection
|
|
120
|
+
const [loconet] = connections.filter(c => c.name === 'LocoNet');
|
|
121
|
+
await client.powerOn(loconet.prefix);
|
|
122
|
+
|
|
123
|
+
// Acquire a throttle on a specific connection
|
|
124
|
+
const throttleId = await client.acquireThrottle({
|
|
125
|
+
address: 3,
|
|
126
|
+
prefix: loconet.prefix
|
|
127
|
+
});
|
|
128
|
+
```
|
|
129
|
+
|
|
99
130
|
## Roster Management
|
|
100
131
|
|
|
101
132
|
```typescript
|
|
@@ -150,6 +181,9 @@ client.on('light:changed', (name: string, state: LightState) => {
|
|
|
150
181
|
// Acquire throttle
|
|
151
182
|
const throttleId = await client.acquireThrottle({ address: 3 });
|
|
152
183
|
|
|
184
|
+
// Acquire throttle on a specific hardware connection
|
|
185
|
+
const throttleId = await client.acquireThrottle({ address: 3, prefix: 'L' });
|
|
186
|
+
|
|
153
187
|
// Control speed (0.0 to 1.0)
|
|
154
188
|
await client.setThrottleSpeed(throttleId, 0.0); // Stopped
|
|
155
189
|
await client.setThrottleSpeed(throttleId, 0.5); // Half speed
|
|
@@ -237,6 +271,7 @@ import {
|
|
|
237
271
|
TurnoutData,
|
|
238
272
|
ThrottleState,
|
|
239
273
|
ThrottleFunctionKey,
|
|
240
|
-
ConnectionState
|
|
274
|
+
ConnectionState,
|
|
275
|
+
SystemConnectionData
|
|
241
276
|
} from 'jmri-client';
|
|
242
277
|
```
|
package/docs/BROWSER.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Browser Usage Guide
|
|
2
2
|
|
|
3
|
-
jmri-client
|
|
3
|
+
jmri-client supports both Node.js and browser environments. This guide shows how to use jmri-client in web applications.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -112,7 +112,7 @@ For quick prototypes without a build step, use the browser bundle:
|
|
|
112
112
|
|
|
113
113
|
<script type="module">
|
|
114
114
|
// Use the browser bundle from CDN
|
|
115
|
-
import { JmriClient } from 'https://unpkg.com/jmri-client@
|
|
115
|
+
import { JmriClient } from 'https://unpkg.com/jmri-client@5.0.0/dist/browser/jmri-client.js';
|
|
116
116
|
|
|
117
117
|
const client = new JmriClient({
|
|
118
118
|
host: 'localhost',
|
|
@@ -144,8 +144,8 @@ For quick prototypes without a build step, use the browser bundle:
|
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
Alternative CDNs:
|
|
147
|
-
- **unpkg**: `https://unpkg.com/jmri-client@
|
|
148
|
-
- **jsDelivr**: `https://cdn.jsdelivr.net/npm/jmri-client@
|
|
147
|
+
- **unpkg**: `https://unpkg.com/jmri-client@5.0.0/dist/browser/jmri-client.js`
|
|
148
|
+
- **jsDelivr**: `https://cdn.jsdelivr.net/npm/jmri-client@5.0.0/dist/browser/jmri-client.js`
|
|
149
149
|
|
|
150
150
|
## React Example
|
|
151
151
|
|
package/docs/EXAMPLES.md
CHANGED
|
@@ -283,6 +283,48 @@ async function runLayout() {
|
|
|
283
283
|
runLayout();
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
+
## Multi-Connection / Hardware Prefix
|
|
287
|
+
|
|
288
|
+
When JMRI is configured with more than one hardware connection (e.g. both LocoNet and DCC++), use `getSystemConnections()` to discover the available prefixes, then pass them to power and throttle commands to target a specific connection.
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
import { JmriClient } from 'jmri-client';
|
|
292
|
+
|
|
293
|
+
const client = new JmriClient({ host: 'jmri.local' });
|
|
294
|
+
|
|
295
|
+
client.on('connected', async () => {
|
|
296
|
+
// Discover what hardware connections JMRI has configured
|
|
297
|
+
const connections = await client.getSystemConnections();
|
|
298
|
+
console.log('Available connections:');
|
|
299
|
+
for (const conn of connections) {
|
|
300
|
+
console.log(` ${conn.name} (prefix: "${conn.prefix}")`);
|
|
301
|
+
}
|
|
302
|
+
// Available connections:
|
|
303
|
+
// LocoNet (prefix: "L")
|
|
304
|
+
// DCC++ (prefix: "D")
|
|
305
|
+
|
|
306
|
+
// Power on via LocoNet only
|
|
307
|
+
await client.powerOn('L');
|
|
308
|
+
|
|
309
|
+
// Acquire a throttle on LocoNet
|
|
310
|
+
const throttle = await client.acquireThrottle({ address: 3, prefix: 'L' });
|
|
311
|
+
await client.setThrottleDirection(throttle, true);
|
|
312
|
+
await client.setThrottleSpeed(throttle, 0.3);
|
|
313
|
+
|
|
314
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
315
|
+
|
|
316
|
+
await client.setThrottleSpeed(throttle, 0);
|
|
317
|
+
await client.releaseThrottle(throttle);
|
|
318
|
+
|
|
319
|
+
// Power off via LocoNet only
|
|
320
|
+
await client.powerOff('L');
|
|
321
|
+
|
|
322
|
+
await client.disconnect();
|
|
323
|
+
});
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
Single-connection layouts work exactly as before — just omit the prefix and JMRI routes to the default connection.
|
|
327
|
+
|
|
286
328
|
## CommonJS Usage
|
|
287
329
|
|
|
288
330
|
```javascript
|
package/docs/MIGRATION.md
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
|
-
# Migration Guide
|
|
1
|
+
# Migration Guide
|
|
2
|
+
|
|
3
|
+
## v4.x to v5.0
|
|
4
|
+
|
|
5
|
+
### Breaking Changes
|
|
6
|
+
|
|
7
|
+
#### Node.js version requirement
|
|
8
|
+
|
|
9
|
+
**v4.x:** Node.js 18+
|
|
10
|
+
**v5.0:** Node.js 22+
|
|
11
|
+
|
|
12
|
+
Node 18 reached end-of-life in April 2025 and Node 20 in April 2026. v5.0 requires Node 22 (Active LTS, EOL April 2027) or later.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
node --version # Should be >= 22.0.0
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
#### No API changes
|
|
19
|
+
|
|
20
|
+
There are no API-level breaking changes between v4.x and v5.0. All existing code targeting v4.x will work without modification.
|
|
21
|
+
|
|
22
|
+
### What's new in v5.0
|
|
23
|
+
|
|
24
|
+
- Node.js 22+ required (drops EOL Node 18 and 20)
|
|
25
|
+
- Built with TypeScript 6
|
|
26
|
+
- esbuild-based build pipeline — faster, smaller outputs, no more dual `tsc` compilation
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## v2.x to v3.x
|
|
2
31
|
|
|
3
32
|
## Overview
|
|
4
33
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jmri-client",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "WebSocket client for JMRI with real-time updates and throttle control - works in both Node.js and browsers",
|
|
5
5
|
"main": "./dist/cjs/index.js",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -8,19 +8,18 @@
|
|
|
8
8
|
"types": "./dist/types/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"types": "./dist/types/index.d.ts",
|
|
11
12
|
"browser": "./dist/browser/jmri-client.js",
|
|
12
13
|
"import": "./dist/esm/index.js",
|
|
13
|
-
"require": "./dist/cjs/index.js"
|
|
14
|
-
"types": "./dist/types/index.d.ts"
|
|
14
|
+
"require": "./dist/cjs/index.js"
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"scripts": {
|
|
18
18
|
"prepublishOnly": "npm run build",
|
|
19
|
-
"
|
|
20
|
-
"build
|
|
21
|
-
"build:
|
|
22
|
-
"
|
|
23
|
-
"build:browser": "node build-browser.mjs",
|
|
19
|
+
"clean": "rm -rf dist",
|
|
20
|
+
"build": "npm run clean && node build.mjs && npm run build:types",
|
|
21
|
+
"build:types": "tsc -p tsconfig.json",
|
|
22
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
24
23
|
"test": "jest --no-cache --coverage",
|
|
25
24
|
"test:browser": "node ./tests/integration/serve-test.mjs",
|
|
26
25
|
"test:reconnect": "node ./tests/integration/forced-reconnect.mjs",
|
|
@@ -59,21 +58,21 @@
|
|
|
59
58
|
"url": "https://github.com/yamanote1138/jmri-client/issues"
|
|
60
59
|
},
|
|
61
60
|
"engines": {
|
|
62
|
-
"node": ">=
|
|
61
|
+
"node": ">=22"
|
|
63
62
|
},
|
|
64
63
|
"devDependencies": {
|
|
65
|
-
"@types/jest": "^
|
|
66
|
-
"@types/node": "^
|
|
67
|
-
"@types/ws": "^8.
|
|
68
|
-
"esbuild": "^0.
|
|
69
|
-
"jest": "^
|
|
70
|
-
"playwright": "^1.
|
|
71
|
-
"ts-jest": "^29.4.
|
|
72
|
-
"typescript": "^
|
|
64
|
+
"@types/jest": "^30.0.0",
|
|
65
|
+
"@types/node": "^22.0.0",
|
|
66
|
+
"@types/ws": "^8.18.0",
|
|
67
|
+
"esbuild": "^0.28.0",
|
|
68
|
+
"jest": "^30.0.0",
|
|
69
|
+
"playwright": "^1.60.0",
|
|
70
|
+
"ts-jest": "^29.4.11",
|
|
71
|
+
"typescript": "^6.0.0"
|
|
73
72
|
},
|
|
74
73
|
"dependencies": {
|
|
75
74
|
"eventemitter3": "^5.0.4",
|
|
76
|
-
"ws": "^8.
|
|
75
|
+
"ws": "^8.21.0"
|
|
77
76
|
},
|
|
78
77
|
"files": [
|
|
79
78
|
"dist",
|
package/dist/cjs/client.js
DELETED
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Main JMRI client class
|
|
4
|
-
*/
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.JmriClient = void 0;
|
|
7
|
-
const eventemitter3_1 = require("eventemitter3");
|
|
8
|
-
const websocket_client_js_1 = require("./core/websocket-client.js");
|
|
9
|
-
const power_manager_js_1 = require("./managers/power-manager.js");
|
|
10
|
-
const roster_manager_js_1 = require("./managers/roster-manager.js");
|
|
11
|
-
const throttle_manager_js_1 = require("./managers/throttle-manager.js");
|
|
12
|
-
const turnout_manager_js_1 = require("./managers/turnout-manager.js");
|
|
13
|
-
const light_manager_js_1 = require("./managers/light-manager.js");
|
|
14
|
-
const system_connections_manager_js_1 = require("./managers/system-connections-manager.js");
|
|
15
|
-
const client_options_js_1 = require("./types/client-options.js");
|
|
16
|
-
/**
|
|
17
|
-
* JMRI WebSocket Client
|
|
18
|
-
* Provides event-driven interface to JMRI with throttle control
|
|
19
|
-
*/
|
|
20
|
-
class JmriClient extends eventemitter3_1.EventEmitter {
|
|
21
|
-
/**
|
|
22
|
-
* Create a new JMRI client
|
|
23
|
-
*
|
|
24
|
-
* @param options - Client configuration options
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* const client = new JmriClient({
|
|
29
|
-
* host: 'jmri.local',
|
|
30
|
-
* port: 12080
|
|
31
|
-
* });
|
|
32
|
-
*
|
|
33
|
-
* client.on('connected', () => console.log('Connected!'));
|
|
34
|
-
* client.on('power:changed', (state) => console.log('Power:', state));
|
|
35
|
-
* ```
|
|
36
|
-
*/
|
|
37
|
-
constructor(options) {
|
|
38
|
-
super();
|
|
39
|
-
// Merge options with defaults
|
|
40
|
-
this.options = (0, client_options_js_1.mergeOptions)(options);
|
|
41
|
-
// Create WebSocket client
|
|
42
|
-
this.wsClient = new websocket_client_js_1.WebSocketClient(this.options);
|
|
43
|
-
// Create managers
|
|
44
|
-
this.powerManager = new power_manager_js_1.PowerManager(this.wsClient);
|
|
45
|
-
this.rosterManager = new roster_manager_js_1.RosterManager(this.wsClient);
|
|
46
|
-
this.throttleManager = new throttle_manager_js_1.ThrottleManager(this.wsClient);
|
|
47
|
-
this.turnoutManager = new turnout_manager_js_1.TurnoutManager(this.wsClient);
|
|
48
|
-
this.lightManager = new light_manager_js_1.LightManager(this.wsClient);
|
|
49
|
-
this.systemConnectionsManager = new system_connections_manager_js_1.SystemConnectionsManager(this.wsClient);
|
|
50
|
-
// Forward events from WebSocket client
|
|
51
|
-
this.wsClient.on('connected', () => this.emit('connected'));
|
|
52
|
-
this.wsClient.on('disconnected', (reason) => this.emit('disconnected', reason));
|
|
53
|
-
this.wsClient.on('reconnecting', (attempt, delay) => this.emit('reconnecting', attempt, delay));
|
|
54
|
-
this.wsClient.on('reconnected', () => this.emit('reconnected'));
|
|
55
|
-
this.wsClient.on('reconnectionFailed', (attempts) => this.emit('reconnectionFailed', attempts));
|
|
56
|
-
this.wsClient.on('connectionStateChanged', (state) => this.emit('connectionStateChanged', state));
|
|
57
|
-
this.wsClient.on('error', (error) => this.emit('error', error));
|
|
58
|
-
this.wsClient.on('heartbeat:sent', () => this.emit('heartbeat:sent'));
|
|
59
|
-
this.wsClient.on('heartbeat:timeout', () => this.emit('heartbeat:timeout'));
|
|
60
|
-
this.wsClient.on('hello', (data) => this.emit('hello', data));
|
|
61
|
-
// Forward events from managers
|
|
62
|
-
this.powerManager.on('power:changed', (state) => this.emit('power:changed', state));
|
|
63
|
-
this.turnoutManager.on('turnout:changed', (name, state) => this.emit('turnout:changed', name, state));
|
|
64
|
-
this.lightManager.on('light:changed', (name, state) => this.emit('light:changed', name, state));
|
|
65
|
-
this.throttleManager.on('throttle:acquired', (id) => this.emit('throttle:acquired', id));
|
|
66
|
-
this.throttleManager.on('throttle:updated', (id, data) => this.emit('throttle:updated', id, data));
|
|
67
|
-
this.throttleManager.on('throttle:released', (id) => this.emit('throttle:released', id));
|
|
68
|
-
this.throttleManager.on('throttle:lost', (id) => this.emit('throttle:lost', id));
|
|
69
|
-
// Auto-connect if enabled
|
|
70
|
-
if (this.options.autoConnect) {
|
|
71
|
-
this.connect().catch((error) => {
|
|
72
|
-
this.emit('error', error);
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Connect to JMRI server
|
|
78
|
-
*/
|
|
79
|
-
async connect() {
|
|
80
|
-
return this.wsClient.connect();
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Disconnect from JMRI server
|
|
84
|
-
* Releases all throttles and closes connection
|
|
85
|
-
*/
|
|
86
|
-
async disconnect() {
|
|
87
|
-
// Release all throttles first
|
|
88
|
-
await this.throttleManager.releaseAllThrottles();
|
|
89
|
-
// Disconnect WebSocket
|
|
90
|
-
return this.wsClient.disconnect();
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Get current connection state
|
|
94
|
-
*/
|
|
95
|
-
getConnectionState() {
|
|
96
|
-
return this.wsClient.getState();
|
|
97
|
-
}
|
|
98
|
-
/**
|
|
99
|
-
* Check if connected to JMRI
|
|
100
|
-
*/
|
|
101
|
-
isConnected() {
|
|
102
|
-
return this.wsClient.isConnected();
|
|
103
|
-
}
|
|
104
|
-
// ============================================================================
|
|
105
|
-
// Power Control
|
|
106
|
-
// ============================================================================
|
|
107
|
-
/**
|
|
108
|
-
* Get current track power state
|
|
109
|
-
* @param prefix - Optional JMRI connection prefix to target a specific hardware connection
|
|
110
|
-
*/
|
|
111
|
-
async getPower(prefix) {
|
|
112
|
-
return this.powerManager.getPower(prefix);
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Set track power state
|
|
116
|
-
* @param state - The desired power state
|
|
117
|
-
* @param prefix - Optional JMRI connection prefix to target a specific hardware connection
|
|
118
|
-
*/
|
|
119
|
-
async setPower(state, prefix) {
|
|
120
|
-
return this.powerManager.setPower(state, prefix);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Turn track power on
|
|
124
|
-
* @param prefix - Optional JMRI connection prefix to target a specific hardware connection
|
|
125
|
-
*/
|
|
126
|
-
async powerOn(prefix) {
|
|
127
|
-
return this.powerManager.powerOn(prefix);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Turn track power off
|
|
131
|
-
* @param prefix - Optional JMRI connection prefix to target a specific hardware connection
|
|
132
|
-
*/
|
|
133
|
-
async powerOff(prefix) {
|
|
134
|
-
return this.powerManager.powerOff(prefix);
|
|
135
|
-
}
|
|
136
|
-
// ============================================================================
|
|
137
|
-
// System Connections
|
|
138
|
-
// ============================================================================
|
|
139
|
-
/**
|
|
140
|
-
* List all available JMRI system connections and their prefixes.
|
|
141
|
-
* Use the returned prefix values with power and throttle commands to
|
|
142
|
-
* target a specific hardware connection when multiple are configured.
|
|
143
|
-
*
|
|
144
|
-
* @example
|
|
145
|
-
* ```typescript
|
|
146
|
-
* const connections = await client.getSystemConnections();
|
|
147
|
-
* // [{ name: 'LocoNet', prefix: 'L' }, { name: 'DCC++', prefix: 'D' }]
|
|
148
|
-
* await client.powerOn('L'); // power on via LocoNet only
|
|
149
|
-
* ```
|
|
150
|
-
*/
|
|
151
|
-
async getSystemConnections() {
|
|
152
|
-
return this.systemConnectionsManager.getSystemConnections();
|
|
153
|
-
}
|
|
154
|
-
// ============================================================================
|
|
155
|
-
// Roster Management
|
|
156
|
-
// ============================================================================
|
|
157
|
-
/**
|
|
158
|
-
* Get all roster entries
|
|
159
|
-
*/
|
|
160
|
-
async getRoster() {
|
|
161
|
-
return this.rosterManager.getRoster();
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Get roster entry by name
|
|
165
|
-
*/
|
|
166
|
-
async getRosterEntryByName(name) {
|
|
167
|
-
return this.rosterManager.getRosterEntryByName(name);
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Get roster entry by address
|
|
171
|
-
*/
|
|
172
|
-
async getRosterEntryByAddress(address) {
|
|
173
|
-
return this.rosterManager.getRosterEntryByAddress(address);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Search roster by partial name match
|
|
177
|
-
*/
|
|
178
|
-
async searchRoster(query) {
|
|
179
|
-
return this.rosterManager.searchRoster(query);
|
|
180
|
-
}
|
|
181
|
-
// ============================================================================
|
|
182
|
-
// Turnout Control
|
|
183
|
-
// ============================================================================
|
|
184
|
-
/**
|
|
185
|
-
* Get the current state of a turnout
|
|
186
|
-
*/
|
|
187
|
-
async getTurnout(name) {
|
|
188
|
-
return this.turnoutManager.getTurnout(name);
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Set a turnout to the given state
|
|
192
|
-
*/
|
|
193
|
-
async setTurnout(name, state) {
|
|
194
|
-
return this.turnoutManager.setTurnout(name, state);
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Throw a turnout (diverging route)
|
|
198
|
-
*/
|
|
199
|
-
async throwTurnout(name) {
|
|
200
|
-
return this.turnoutManager.throwTurnout(name);
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Close a turnout (straight through / normal)
|
|
204
|
-
*/
|
|
205
|
-
async closeTurnout(name) {
|
|
206
|
-
return this.turnoutManager.closeTurnout(name);
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* List all turnouts known to JMRI
|
|
210
|
-
*/
|
|
211
|
-
async listTurnouts() {
|
|
212
|
-
return this.turnoutManager.listTurnouts();
|
|
213
|
-
}
|
|
214
|
-
/**
|
|
215
|
-
* Get cached turnout state without a network request
|
|
216
|
-
*/
|
|
217
|
-
getTurnoutState(name) {
|
|
218
|
-
return this.turnoutManager.getTurnoutState(name);
|
|
219
|
-
}
|
|
220
|
-
/**
|
|
221
|
-
* Get all cached turnout states
|
|
222
|
-
*/
|
|
223
|
-
getCachedTurnouts() {
|
|
224
|
-
return this.turnoutManager.getCachedTurnouts();
|
|
225
|
-
}
|
|
226
|
-
// ============================================================================
|
|
227
|
-
// Light Control
|
|
228
|
-
// ============================================================================
|
|
229
|
-
/**
|
|
230
|
-
* Get the current state of a light
|
|
231
|
-
*/
|
|
232
|
-
async getLight(name) {
|
|
233
|
-
return this.lightManager.getLight(name);
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Set a light to the given state
|
|
237
|
-
*/
|
|
238
|
-
async setLight(name, state) {
|
|
239
|
-
return this.lightManager.setLight(name, state);
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Turn a light on
|
|
243
|
-
*/
|
|
244
|
-
async turnOnLight(name) {
|
|
245
|
-
return this.lightManager.turnOnLight(name);
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Turn a light off
|
|
249
|
-
*/
|
|
250
|
-
async turnOffLight(name) {
|
|
251
|
-
return this.lightManager.turnOffLight(name);
|
|
252
|
-
}
|
|
253
|
-
/**
|
|
254
|
-
* List all lights known to JMRI
|
|
255
|
-
*/
|
|
256
|
-
async listLights() {
|
|
257
|
-
return this.lightManager.listLights();
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Get cached light state without a network request
|
|
261
|
-
*/
|
|
262
|
-
getLightState(name) {
|
|
263
|
-
return this.lightManager.getLightState(name);
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Get all cached light states
|
|
267
|
-
*/
|
|
268
|
-
getCachedLights() {
|
|
269
|
-
return this.lightManager.getCachedLights();
|
|
270
|
-
}
|
|
271
|
-
// ============================================================================
|
|
272
|
-
// Throttle Control
|
|
273
|
-
// ============================================================================
|
|
274
|
-
/**
|
|
275
|
-
* Acquire a throttle for a locomotive
|
|
276
|
-
*
|
|
277
|
-
* @param options - Throttle acquisition options
|
|
278
|
-
* @returns Throttle ID for use in other throttle methods
|
|
279
|
-
*
|
|
280
|
-
* @example
|
|
281
|
-
* ```typescript
|
|
282
|
-
* const throttleId = await client.acquireThrottle({ address: 3 });
|
|
283
|
-
* await client.setThrottleSpeed(throttleId, 0.5); // Half speed
|
|
284
|
-
* ```
|
|
285
|
-
*/
|
|
286
|
-
async acquireThrottle(options) {
|
|
287
|
-
return this.throttleManager.acquireThrottle(options);
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Release a throttle
|
|
291
|
-
*/
|
|
292
|
-
async releaseThrottle(throttleId) {
|
|
293
|
-
return this.throttleManager.releaseThrottle(throttleId);
|
|
294
|
-
}
|
|
295
|
-
/**
|
|
296
|
-
* Set throttle speed (0.0 to 1.0)
|
|
297
|
-
*
|
|
298
|
-
* @param throttleId - Throttle ID from acquireThrottle
|
|
299
|
-
* @param speed - Speed value between 0.0 (stopped) and 1.0 (full speed)
|
|
300
|
-
*/
|
|
301
|
-
async setThrottleSpeed(throttleId, speed) {
|
|
302
|
-
return this.throttleManager.setSpeed(throttleId, speed);
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Set throttle direction
|
|
306
|
-
*
|
|
307
|
-
* @param throttleId - Throttle ID from acquireThrottle
|
|
308
|
-
* @param forward - True for forward, false for reverse
|
|
309
|
-
*/
|
|
310
|
-
async setThrottleDirection(throttleId, forward) {
|
|
311
|
-
return this.throttleManager.setDirection(throttleId, forward);
|
|
312
|
-
}
|
|
313
|
-
/**
|
|
314
|
-
* Set throttle function (F0-F28)
|
|
315
|
-
*
|
|
316
|
-
* @param throttleId - Throttle ID from acquireThrottle
|
|
317
|
-
* @param functionKey - Function key (F0-F28)
|
|
318
|
-
* @param value - True to activate, false to deactivate
|
|
319
|
-
*
|
|
320
|
-
* @example
|
|
321
|
-
* ```typescript
|
|
322
|
-
* await client.setThrottleFunction(throttleId, 'F0', true); // Headlight on
|
|
323
|
-
* await client.setThrottleFunction(throttleId, 'F2', true); // Horn
|
|
324
|
-
* ```
|
|
325
|
-
*/
|
|
326
|
-
async setThrottleFunction(throttleId, functionKey, value) {
|
|
327
|
-
return this.throttleManager.setFunction(throttleId, functionKey, value);
|
|
328
|
-
}
|
|
329
|
-
/**
|
|
330
|
-
* Emergency stop for a throttle (speed to 0)
|
|
331
|
-
*/
|
|
332
|
-
async emergencyStop(throttleId) {
|
|
333
|
-
return this.throttleManager.emergencyStop(throttleId);
|
|
334
|
-
}
|
|
335
|
-
/**
|
|
336
|
-
* Set throttle to idle (speed to 0, maintain direction)
|
|
337
|
-
*/
|
|
338
|
-
async idleThrottle(throttleId) {
|
|
339
|
-
return this.throttleManager.idle(throttleId);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Get throttle state
|
|
343
|
-
*/
|
|
344
|
-
getThrottleState(throttleId) {
|
|
345
|
-
return this.throttleManager.getThrottleState(throttleId);
|
|
346
|
-
}
|
|
347
|
-
/**
|
|
348
|
-
* Get all throttle IDs
|
|
349
|
-
*/
|
|
350
|
-
getThrottleIds() {
|
|
351
|
-
return this.throttleManager.getThrottleIds();
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Get all throttle states
|
|
355
|
-
*/
|
|
356
|
-
getAllThrottles() {
|
|
357
|
-
return this.throttleManager.getAllThrottles();
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Release all throttles
|
|
361
|
-
*/
|
|
362
|
-
async releaseAllThrottles() {
|
|
363
|
-
return this.throttleManager.releaseAllThrottles();
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
exports.JmriClient = JmriClient;
|