jmri-client 4.0.0 → 4.1.1

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.
@@ -638,6 +638,23 @@ function turnoutStateToString(state) {
638
638
  return "UNKNOWN";
639
639
  }
640
640
  }
641
+ var LightState = /* @__PURE__ */ ((LightState2) => {
642
+ LightState2[LightState2["UNKNOWN"] = 0] = "UNKNOWN";
643
+ LightState2[LightState2["ON"] = 2] = "ON";
644
+ LightState2[LightState2["OFF"] = 4] = "OFF";
645
+ return LightState2;
646
+ })(LightState || {});
647
+ function lightStateToString(state) {
648
+ switch (state) {
649
+ case 2 /* ON */:
650
+ return "ON";
651
+ case 4 /* OFF */:
652
+ return "OFF";
653
+ case 0 /* UNKNOWN */:
654
+ default:
655
+ return "UNKNOWN";
656
+ }
657
+ }
641
658
 
642
659
  // src/mocks/mock-data.ts
643
660
  var mockData = {
@@ -823,6 +840,13 @@ var mockData = {
823
840
  }
824
841
  }
825
842
  },
843
+ "light": {
844
+ "list": [
845
+ { "type": "light", "data": { "name": "IL1", "userName": "Yard Light", "comment": null, "properties": [], "state": 4 } },
846
+ { "type": "light", "data": { "name": "IL2", "userName": "Platform Light", "comment": null, "properties": [], "state": 4 } },
847
+ { "type": "light", "data": { "name": "IL3", "userName": "Signal Lamp", "comment": null, "properties": [], "state": 2 } }
848
+ ]
849
+ },
826
850
  "turnout": {
827
851
  "list": [
828
852
  { "type": "turnout", "data": { "name": "LT1", "userName": "Main Diverge", "state": 2 } },
@@ -868,6 +892,11 @@ var mockData = {
868
892
  var MockResponseManager = class {
869
893
  constructor(options = {}) {
870
894
  this.throttles = /* @__PURE__ */ new Map();
895
+ this.lights = /* @__PURE__ */ new Map([
896
+ ["IL1", 4 /* OFF */],
897
+ ["IL2", 4 /* OFF */],
898
+ ["IL3", 2 /* ON */]
899
+ ]);
871
900
  this.turnouts = /* @__PURE__ */ new Map([
872
901
  ["LT1", 2 /* CLOSED */],
873
902
  ["LT2", 2 /* CLOSED */],
@@ -892,6 +921,8 @@ var MockResponseManager = class {
892
921
  return this.getRosterResponse(message);
893
922
  case "throttle":
894
923
  return this.getThrottleResponse(message);
924
+ case "light":
925
+ return this.getLightResponse(message);
895
926
  case "turnout":
896
927
  return this.getTurnoutResponse(message);
897
928
  case "ping":
@@ -1007,6 +1038,26 @@ var MockResponseManager = class {
1007
1038
  data: {}
1008
1039
  };
1009
1040
  }
1041
+ /**
1042
+ * Get light response
1043
+ */
1044
+ getLightResponse(message) {
1045
+ if (message.method === "list") {
1046
+ return {
1047
+ type: "light",
1048
+ data: JSON.parse(JSON.stringify(mockData.light.list))
1049
+ };
1050
+ }
1051
+ const name = message.data?.name;
1052
+ if (!name) {
1053
+ return { type: "light", data: { name: "", state: 0 /* UNKNOWN */ } };
1054
+ }
1055
+ if (message.method === "post" && message.data?.state !== void 0) {
1056
+ this.lights.set(name, message.data.state);
1057
+ }
1058
+ const state = this.lights.get(name) ?? 0 /* UNKNOWN */;
1059
+ return { type: "light", data: { name, state } };
1060
+ }
1010
1061
  /**
1011
1062
  * Get turnout response
1012
1063
  */
@@ -1057,6 +1108,12 @@ var MockResponseManager = class {
1057
1108
  getThrottles() {
1058
1109
  return this.throttles;
1059
1110
  }
1111
+ /**
1112
+ * Get all light states (for testing)
1113
+ */
1114
+ getLights() {
1115
+ return this.lights;
1116
+ }
1060
1117
  /**
1061
1118
  * Get all turnout states (for testing)
1062
1119
  */
@@ -1069,6 +1126,11 @@ var MockResponseManager = class {
1069
1126
  reset() {
1070
1127
  this.powerState = 4 /* OFF */;
1071
1128
  this.throttles.clear();
1129
+ this.lights = /* @__PURE__ */ new Map([
1130
+ ["IL1", 4 /* OFF */],
1131
+ ["IL2", 4 /* OFF */],
1132
+ ["IL3", 2 /* ON */]
1133
+ ]);
1072
1134
  this.turnouts = /* @__PURE__ */ new Map([
1073
1135
  ["LT1", 2 /* CLOSED */],
1074
1136
  ["LT2", 2 /* CLOSED */],
@@ -1891,6 +1953,104 @@ var TurnoutManager = class extends import_index.default {
1891
1953
  }
1892
1954
  };
1893
1955
 
1956
+ // src/managers/light-manager.ts
1957
+ var LightManager = class extends import_index.default {
1958
+ constructor(client) {
1959
+ super();
1960
+ this.lights = /* @__PURE__ */ new Map();
1961
+ this.client = client;
1962
+ this.client.on("update", (message) => {
1963
+ if (message.type === "light") {
1964
+ this.handleLightUpdate(message);
1965
+ }
1966
+ });
1967
+ }
1968
+ /**
1969
+ * Get the current state of a light.
1970
+ * Also registers a server-side listener so subsequent changes are pushed.
1971
+ */
1972
+ async getLight(name) {
1973
+ const message = {
1974
+ type: "light",
1975
+ data: { name }
1976
+ };
1977
+ const response = await this.client.request(message);
1978
+ const state = response.data?.state ?? 0 /* UNKNOWN */;
1979
+ this.lights.set(name, state);
1980
+ return state;
1981
+ }
1982
+ /**
1983
+ * Set a light to the given state
1984
+ */
1985
+ async setLight(name, state) {
1986
+ const message = {
1987
+ type: "light",
1988
+ method: "post",
1989
+ data: { name, state }
1990
+ };
1991
+ await this.client.request(message);
1992
+ const oldState = this.lights.get(name);
1993
+ this.lights.set(name, state);
1994
+ if (oldState !== state) {
1995
+ this.emit("light:changed", name, state);
1996
+ }
1997
+ }
1998
+ /**
1999
+ * Turn a light on
2000
+ */
2001
+ async turnOnLight(name) {
2002
+ return this.setLight(name, 2 /* ON */);
2003
+ }
2004
+ /**
2005
+ * Turn a light off
2006
+ */
2007
+ async turnOffLight(name) {
2008
+ return this.setLight(name, 4 /* OFF */);
2009
+ }
2010
+ /**
2011
+ * List all lights known to JMRI
2012
+ */
2013
+ async listLights() {
2014
+ const message = {
2015
+ type: "light",
2016
+ method: "list"
2017
+ };
2018
+ const response = await this.client.request(message);
2019
+ const entries = Array.isArray(response?.data) ? response.data.map((r) => r.data ?? r) : [];
2020
+ for (const entry of entries) {
2021
+ if (entry.name && entry.state !== void 0) {
2022
+ this.lights.set(entry.name, entry.state);
2023
+ }
2024
+ }
2025
+ return entries;
2026
+ }
2027
+ /**
2028
+ * Get cached light state without a network request
2029
+ */
2030
+ getLightState(name) {
2031
+ return this.lights.get(name);
2032
+ }
2033
+ /**
2034
+ * Get all cached light states
2035
+ */
2036
+ getCachedLights() {
2037
+ return new Map(this.lights);
2038
+ }
2039
+ /**
2040
+ * Handle unsolicited light state updates from JMRI
2041
+ */
2042
+ handleLightUpdate(message) {
2043
+ const name = message.data?.name;
2044
+ const state = message.data?.state;
2045
+ if (!name || state === void 0) return;
2046
+ const oldState = this.lights.get(name);
2047
+ this.lights.set(name, state);
2048
+ if (oldState !== state) {
2049
+ this.emit("light:changed", name, state);
2050
+ }
2051
+ }
2052
+ };
2053
+
1894
2054
  // src/types/client-options.ts
1895
2055
  var DEFAULT_CLIENT_OPTIONS = {
1896
2056
  host: "localhost",
@@ -1967,6 +2127,7 @@ var JmriClient = class extends import_index.default {
1967
2127
  this.rosterManager = new RosterManager(this.wsClient);
1968
2128
  this.throttleManager = new ThrottleManager(this.wsClient);
1969
2129
  this.turnoutManager = new TurnoutManager(this.wsClient);
2130
+ this.lightManager = new LightManager(this.wsClient);
1970
2131
  this.wsClient.on("connected", () => this.emit("connected"));
1971
2132
  this.wsClient.on("disconnected", (reason) => this.emit("disconnected", reason));
1972
2133
  this.wsClient.on(
@@ -1994,6 +2155,10 @@ var JmriClient = class extends import_index.default {
1994
2155
  "turnout:changed",
1995
2156
  (name, state) => this.emit("turnout:changed", name, state)
1996
2157
  );
2158
+ this.lightManager.on(
2159
+ "light:changed",
2160
+ (name, state) => this.emit("light:changed", name, state)
2161
+ );
1997
2162
  this.throttleManager.on(
1998
2163
  "throttle:acquired",
1999
2164
  (id) => this.emit("throttle:acquired", id)
@@ -2142,6 +2307,51 @@ var JmriClient = class extends import_index.default {
2142
2307
  return this.turnoutManager.getCachedTurnouts();
2143
2308
  }
2144
2309
  // ============================================================================
2310
+ // Light Control
2311
+ // ============================================================================
2312
+ /**
2313
+ * Get the current state of a light
2314
+ */
2315
+ async getLight(name) {
2316
+ return this.lightManager.getLight(name);
2317
+ }
2318
+ /**
2319
+ * Set a light to the given state
2320
+ */
2321
+ async setLight(name, state) {
2322
+ return this.lightManager.setLight(name, state);
2323
+ }
2324
+ /**
2325
+ * Turn a light on
2326
+ */
2327
+ async turnOnLight(name) {
2328
+ return this.lightManager.turnOnLight(name);
2329
+ }
2330
+ /**
2331
+ * Turn a light off
2332
+ */
2333
+ async turnOffLight(name) {
2334
+ return this.lightManager.turnOffLight(name);
2335
+ }
2336
+ /**
2337
+ * List all lights known to JMRI
2338
+ */
2339
+ async listLights() {
2340
+ return this.lightManager.listLights();
2341
+ }
2342
+ /**
2343
+ * Get cached light state without a network request
2344
+ */
2345
+ getLightState(name) {
2346
+ return this.lightManager.getLightState(name);
2347
+ }
2348
+ /**
2349
+ * Get all cached light states
2350
+ */
2351
+ getCachedLights() {
2352
+ return this.lightManager.getCachedLights();
2353
+ }
2354
+ // ============================================================================
2145
2355
  // Throttle Control
2146
2356
  // ============================================================================
2147
2357
  /**
@@ -2239,12 +2449,14 @@ var JmriClient = class extends import_index.default {
2239
2449
  export {
2240
2450
  ConnectionState,
2241
2451
  JmriClient,
2452
+ LightState,
2242
2453
  MockResponseManager,
2243
2454
  PowerState,
2244
2455
  TurnoutState,
2245
2456
  WebSocketClient,
2246
2457
  isThrottleFunctionKey,
2247
2458
  isValidSpeed,
2459
+ lightStateToString,
2248
2460
  mockData,
2249
2461
  mockResponseManager,
2250
2462
  powerStateToString,
@@ -10,6 +10,7 @@ const power_manager_js_1 = require("./managers/power-manager.js");
10
10
  const roster_manager_js_1 = require("./managers/roster-manager.js");
11
11
  const throttle_manager_js_1 = require("./managers/throttle-manager.js");
12
12
  const turnout_manager_js_1 = require("./managers/turnout-manager.js");
13
+ const light_manager_js_1 = require("./managers/light-manager.js");
13
14
  const client_options_js_1 = require("./types/client-options.js");
14
15
  /**
15
16
  * JMRI WebSocket Client
@@ -43,6 +44,7 @@ class JmriClient extends eventemitter3_1.EventEmitter {
43
44
  this.rosterManager = new roster_manager_js_1.RosterManager(this.wsClient);
44
45
  this.throttleManager = new throttle_manager_js_1.ThrottleManager(this.wsClient);
45
46
  this.turnoutManager = new turnout_manager_js_1.TurnoutManager(this.wsClient);
47
+ this.lightManager = new light_manager_js_1.LightManager(this.wsClient);
46
48
  // Forward events from WebSocket client
47
49
  this.wsClient.on('connected', () => this.emit('connected'));
48
50
  this.wsClient.on('disconnected', (reason) => this.emit('disconnected', reason));
@@ -57,6 +59,7 @@ class JmriClient extends eventemitter3_1.EventEmitter {
57
59
  // Forward events from managers
58
60
  this.powerManager.on('power:changed', (state) => this.emit('power:changed', state));
59
61
  this.turnoutManager.on('turnout:changed', (name, state) => this.emit('turnout:changed', name, state));
62
+ this.lightManager.on('light:changed', (name, state) => this.emit('light:changed', name, state));
60
63
  this.throttleManager.on('throttle:acquired', (id) => this.emit('throttle:acquired', id));
61
64
  this.throttleManager.on('throttle:updated', (id, data) => this.emit('throttle:updated', id, data));
62
65
  this.throttleManager.on('throttle:released', (id) => this.emit('throttle:released', id));
@@ -196,6 +199,51 @@ class JmriClient extends eventemitter3_1.EventEmitter {
196
199
  return this.turnoutManager.getCachedTurnouts();
197
200
  }
198
201
  // ============================================================================
202
+ // Light Control
203
+ // ============================================================================
204
+ /**
205
+ * Get the current state of a light
206
+ */
207
+ async getLight(name) {
208
+ return this.lightManager.getLight(name);
209
+ }
210
+ /**
211
+ * Set a light to the given state
212
+ */
213
+ async setLight(name, state) {
214
+ return this.lightManager.setLight(name, state);
215
+ }
216
+ /**
217
+ * Turn a light on
218
+ */
219
+ async turnOnLight(name) {
220
+ return this.lightManager.turnOnLight(name);
221
+ }
222
+ /**
223
+ * Turn a light off
224
+ */
225
+ async turnOffLight(name) {
226
+ return this.lightManager.turnOffLight(name);
227
+ }
228
+ /**
229
+ * List all lights known to JMRI
230
+ */
231
+ async listLights() {
232
+ return this.lightManager.listLights();
233
+ }
234
+ /**
235
+ * Get cached light state without a network request
236
+ */
237
+ getLightState(name) {
238
+ return this.lightManager.getLightState(name);
239
+ }
240
+ /**
241
+ * Get all cached light states
242
+ */
243
+ getCachedLights() {
244
+ return this.lightManager.getCachedLights();
245
+ }
246
+ // ============================================================================
199
247
  // Throttle Control
200
248
  // ============================================================================
201
249
  /**
package/dist/cjs/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * WebSocket client for JMRI with real-time updates and throttle control
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.mockData = exports.mockResponseManager = exports.MockResponseManager = exports.turnoutStateToString = exports.powerStateToString = exports.isValidSpeed = exports.isThrottleFunctionKey = exports.ConnectionState = exports.TurnoutState = exports.PowerState = exports.WebSocketClient = exports.JmriClient = void 0;
7
+ exports.mockData = exports.mockResponseManager = exports.MockResponseManager = exports.lightStateToString = exports.turnoutStateToString = exports.powerStateToString = exports.isValidSpeed = exports.isThrottleFunctionKey = exports.ConnectionState = exports.LightState = exports.TurnoutState = exports.PowerState = exports.WebSocketClient = exports.JmriClient = void 0;
8
8
  var client_js_1 = require("./client.js");
9
9
  Object.defineProperty(exports, "JmriClient", { enumerable: true, get: function () { return client_js_1.JmriClient; } });
10
10
  var websocket_client_js_1 = require("./core/websocket-client.js");
@@ -14,6 +14,7 @@ var index_js_1 = require("./types/index.js");
14
14
  // JMRI message types
15
15
  Object.defineProperty(exports, "PowerState", { enumerable: true, get: function () { return index_js_1.PowerState; } });
16
16
  Object.defineProperty(exports, "TurnoutState", { enumerable: true, get: function () { return index_js_1.TurnoutState; } });
17
+ Object.defineProperty(exports, "LightState", { enumerable: true, get: function () { return index_js_1.LightState; } });
17
18
  // Event types
18
19
  Object.defineProperty(exports, "ConnectionState", { enumerable: true, get: function () { return index_js_1.ConnectionState; } });
19
20
  // Export utility functions
@@ -23,6 +24,7 @@ Object.defineProperty(exports, "isValidSpeed", { enumerable: true, get: function
23
24
  var jmri_messages_js_1 = require("./types/jmri-messages.js");
24
25
  Object.defineProperty(exports, "powerStateToString", { enumerable: true, get: function () { return jmri_messages_js_1.powerStateToString; } });
25
26
  Object.defineProperty(exports, "turnoutStateToString", { enumerable: true, get: function () { return jmri_messages_js_1.turnoutStateToString; } });
27
+ Object.defineProperty(exports, "lightStateToString", { enumerable: true, get: function () { return jmri_messages_js_1.lightStateToString; } });
26
28
  // Export mock system for testing and demo purposes
27
29
  var index_js_2 = require("./mocks/index.js");
28
30
  Object.defineProperty(exports, "MockResponseManager", { enumerable: true, get: function () { return index_js_2.MockResponseManager; } });
@@ -21,3 +21,4 @@ __exportStar(require("./power-manager.js"), exports);
21
21
  __exportStar(require("./roster-manager.js"), exports);
22
22
  __exportStar(require("./throttle-manager.js"), exports);
23
23
  __exportStar(require("./turnout-manager.js"), exports);
24
+ __exportStar(require("./light-manager.js"), exports);
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * Light manager
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LightManager = void 0;
7
+ const eventemitter3_1 = require("eventemitter3");
8
+ const jmri_messages_js_1 = require("../types/jmri-messages.js");
9
+ /**
10
+ * Manages JMRI light state
11
+ */
12
+ class LightManager extends eventemitter3_1.EventEmitter {
13
+ constructor(client) {
14
+ super();
15
+ this.lights = new Map();
16
+ this.client = client;
17
+ this.client.on('update', (message) => {
18
+ if (message.type === 'light') {
19
+ this.handleLightUpdate(message);
20
+ }
21
+ });
22
+ }
23
+ /**
24
+ * Get the current state of a light.
25
+ * Also registers a server-side listener so subsequent changes are pushed.
26
+ */
27
+ async getLight(name) {
28
+ const message = {
29
+ type: 'light',
30
+ data: { name }
31
+ };
32
+ const response = await this.client.request(message);
33
+ const state = response.data?.state ?? jmri_messages_js_1.LightState.UNKNOWN;
34
+ this.lights.set(name, state);
35
+ return state;
36
+ }
37
+ /**
38
+ * Set a light to the given state
39
+ */
40
+ async setLight(name, state) {
41
+ const message = {
42
+ type: 'light',
43
+ method: 'post',
44
+ data: { name, state }
45
+ };
46
+ await this.client.request(message);
47
+ const oldState = this.lights.get(name);
48
+ this.lights.set(name, state);
49
+ if (oldState !== state) {
50
+ this.emit('light:changed', name, state);
51
+ }
52
+ }
53
+ /**
54
+ * Turn a light on
55
+ */
56
+ async turnOnLight(name) {
57
+ return this.setLight(name, jmri_messages_js_1.LightState.ON);
58
+ }
59
+ /**
60
+ * Turn a light off
61
+ */
62
+ async turnOffLight(name) {
63
+ return this.setLight(name, jmri_messages_js_1.LightState.OFF);
64
+ }
65
+ /**
66
+ * List all lights known to JMRI
67
+ */
68
+ async listLights() {
69
+ const message = {
70
+ type: 'light',
71
+ method: 'list'
72
+ };
73
+ const response = await this.client.request(message);
74
+ const entries = Array.isArray(response?.data)
75
+ ? response.data.map((r) => r.data ?? r)
76
+ : [];
77
+ for (const entry of entries) {
78
+ if (entry.name && entry.state !== undefined) {
79
+ this.lights.set(entry.name, entry.state);
80
+ }
81
+ }
82
+ return entries;
83
+ }
84
+ /**
85
+ * Get cached light state without a network request
86
+ */
87
+ getLightState(name) {
88
+ return this.lights.get(name);
89
+ }
90
+ /**
91
+ * Get all cached light states
92
+ */
93
+ getCachedLights() {
94
+ return new Map(this.lights);
95
+ }
96
+ /**
97
+ * Handle unsolicited light state updates from JMRI
98
+ */
99
+ handleLightUpdate(message) {
100
+ const name = message.data?.name;
101
+ const state = message.data?.state;
102
+ if (!name || state === undefined)
103
+ return;
104
+ const oldState = this.lights.get(name);
105
+ this.lights.set(name, state);
106
+ if (oldState !== state) {
107
+ this.emit('light:changed', name, state);
108
+ }
109
+ }
110
+ }
111
+ exports.LightManager = LightManager;
@@ -188,6 +188,13 @@ exports.mockData = {
188
188
  }
189
189
  }
190
190
  },
191
+ "light": {
192
+ "list": [
193
+ { "type": "light", "data": { "name": "IL1", "userName": "Yard Light", "comment": null, "properties": [], "state": 4 } },
194
+ { "type": "light", "data": { "name": "IL2", "userName": "Platform Light", "comment": null, "properties": [], "state": 4 } },
195
+ { "type": "light", "data": { "name": "IL3", "userName": "Signal Lamp", "comment": null, "properties": [], "state": 2 } }
196
+ ]
197
+ },
191
198
  "turnout": {
192
199
  "list": [
193
200
  { "type": "turnout", "data": { "name": "LT1", "userName": "Main Diverge", "state": 2 } },
@@ -13,6 +13,11 @@ const mock_data_js_1 = require("./mock-data.js");
13
13
  class MockResponseManager {
14
14
  constructor(options = {}) {
15
15
  this.throttles = new Map();
16
+ this.lights = new Map([
17
+ ['IL1', jmri_messages_js_1.LightState.OFF],
18
+ ['IL2', jmri_messages_js_1.LightState.OFF],
19
+ ['IL3', jmri_messages_js_1.LightState.ON]
20
+ ]);
16
21
  this.turnouts = new Map([
17
22
  ['LT1', jmri_messages_js_1.TurnoutState.CLOSED],
18
23
  ['LT2', jmri_messages_js_1.TurnoutState.CLOSED],
@@ -39,6 +44,8 @@ class MockResponseManager {
39
44
  return this.getRosterResponse(message);
40
45
  case 'throttle':
41
46
  return this.getThrottleResponse(message);
47
+ case 'light':
48
+ return this.getLightResponse(message);
42
49
  case 'turnout':
43
50
  return this.getTurnoutResponse(message);
44
51
  case 'ping':
@@ -164,6 +171,29 @@ class MockResponseManager {
164
171
  data: {}
165
172
  };
166
173
  }
174
+ /**
175
+ * Get light response
176
+ */
177
+ getLightResponse(message) {
178
+ // List all lights
179
+ if (message.method === 'list') {
180
+ return {
181
+ type: 'light',
182
+ data: JSON.parse(JSON.stringify(mock_data_js_1.mockData.light.list))
183
+ };
184
+ }
185
+ const name = message.data?.name;
186
+ if (!name) {
187
+ return { type: 'light', data: { name: '', state: jmri_messages_js_1.LightState.UNKNOWN } };
188
+ }
189
+ // Set light state
190
+ if (message.method === 'post' && message.data?.state !== undefined) {
191
+ this.lights.set(name, message.data.state);
192
+ }
193
+ // Get or confirm current state
194
+ const state = this.lights.get(name) ?? jmri_messages_js_1.LightState.UNKNOWN;
195
+ return { type: 'light', data: { name, state } };
196
+ }
167
197
  /**
168
198
  * Get turnout response
169
199
  */
@@ -217,6 +247,12 @@ class MockResponseManager {
217
247
  getThrottles() {
218
248
  return this.throttles;
219
249
  }
250
+ /**
251
+ * Get all light states (for testing)
252
+ */
253
+ getLights() {
254
+ return this.lights;
255
+ }
220
256
  /**
221
257
  * Get all turnout states (for testing)
222
258
  */
@@ -229,6 +265,11 @@ class MockResponseManager {
229
265
  reset() {
230
266
  this.powerState = jmri_messages_js_1.PowerState.OFF;
231
267
  this.throttles.clear();
268
+ this.lights = new Map([
269
+ ['IL1', jmri_messages_js_1.LightState.OFF],
270
+ ['IL2', jmri_messages_js_1.LightState.OFF],
271
+ ['IL3', jmri_messages_js_1.LightState.ON]
272
+ ]);
232
273
  this.turnouts = new Map([
233
274
  ['LT1', jmri_messages_js_1.TurnoutState.CLOSED],
234
275
  ['LT2', jmri_messages_js_1.TurnoutState.CLOSED],
@@ -4,9 +4,10 @@
4
4
  * Based on JMRI JSON protocol specification
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.TurnoutState = exports.PowerState = void 0;
7
+ exports.LightState = exports.TurnoutState = exports.PowerState = void 0;
8
8
  exports.powerStateToString = powerStateToString;
9
9
  exports.turnoutStateToString = turnoutStateToString;
10
+ exports.lightStateToString = lightStateToString;
10
11
  /**
11
12
  * Power state values (from JMRI JSON protocol constants)
12
13
  * UNKNOWN = 0 (state cannot be determined)
@@ -66,3 +67,29 @@ function turnoutStateToString(state) {
66
67
  return 'UNKNOWN';
67
68
  }
68
69
  }
70
+ /**
71
+ * Light state values (from JMRI JSON protocol constants)
72
+ * UNKNOWN = 0 (state cannot be determined)
73
+ * ON = 2 (light is on)
74
+ * OFF = 4 (light is off)
75
+ */
76
+ var LightState;
77
+ (function (LightState) {
78
+ LightState[LightState["UNKNOWN"] = 0] = "UNKNOWN";
79
+ LightState[LightState["ON"] = 2] = "ON";
80
+ LightState[LightState["OFF"] = 4] = "OFF";
81
+ })(LightState || (exports.LightState = LightState = {}));
82
+ /**
83
+ * Convert LightState enum to human-readable string
84
+ */
85
+ function lightStateToString(state) {
86
+ switch (state) {
87
+ case LightState.ON:
88
+ return 'ON';
89
+ case LightState.OFF:
90
+ return 'OFF';
91
+ case LightState.UNKNOWN:
92
+ default:
93
+ return 'UNKNOWN';
94
+ }
95
+ }