@ecobridge.xyz/devicemanager 3.0.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.
Files changed (137) hide show
  1. package/.gitea/workflows/default_nottags.yaml +66 -0
  2. package/.gitea/workflows/default_tags.yaml +124 -0
  3. package/.vscode/launch.json +11 -0
  4. package/.vscode/settings.json +26 -0
  5. package/changelog.md +91 -0
  6. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  7. package/dist_ts/00_commitinfo_data.js +9 -0
  8. package/dist_ts/device/device.classes.device.d.ts +205 -0
  9. package/dist_ts/device/device.classes.device.js +344 -0
  10. package/dist_ts/devicemanager.classes.devicemanager.d.ts +210 -0
  11. package/dist_ts/devicemanager.classes.devicemanager.js +835 -0
  12. package/dist_ts/discovery/discovery.classes.homeassistant.d.ts +101 -0
  13. package/dist_ts/discovery/discovery.classes.homeassistant.js +313 -0
  14. package/dist_ts/discovery/discovery.classes.mdns.d.ts +90 -0
  15. package/dist_ts/discovery/discovery.classes.mdns.js +291 -0
  16. package/dist_ts/discovery/discovery.classes.networkscanner.d.ts +64 -0
  17. package/dist_ts/discovery/discovery.classes.networkscanner.js +535 -0
  18. package/dist_ts/discovery/discovery.classes.ssdp.d.ts +112 -0
  19. package/dist_ts/discovery/discovery.classes.ssdp.js +255 -0
  20. package/dist_ts/factories/index.d.ts +190 -0
  21. package/dist_ts/factories/index.js +350 -0
  22. package/dist_ts/features/feature.abstract.d.ts +118 -0
  23. package/dist_ts/features/feature.abstract.js +172 -0
  24. package/dist_ts/features/feature.camera.d.ts +95 -0
  25. package/dist_ts/features/feature.camera.js +162 -0
  26. package/dist_ts/features/feature.climate.d.ts +174 -0
  27. package/dist_ts/features/feature.climate.js +328 -0
  28. package/dist_ts/features/feature.cover.d.ts +121 -0
  29. package/dist_ts/features/feature.cover.js +217 -0
  30. package/dist_ts/features/feature.fan.d.ts +127 -0
  31. package/dist_ts/features/feature.fan.js +235 -0
  32. package/dist_ts/features/feature.light.d.ts +156 -0
  33. package/dist_ts/features/feature.light.js +296 -0
  34. package/dist_ts/features/feature.lock.d.ts +103 -0
  35. package/dist_ts/features/feature.lock.js +170 -0
  36. package/dist_ts/features/feature.playback.d.ts +98 -0
  37. package/dist_ts/features/feature.playback.js +191 -0
  38. package/dist_ts/features/feature.power.d.ts +79 -0
  39. package/dist_ts/features/feature.power.js +173 -0
  40. package/dist_ts/features/feature.print.d.ts +78 -0
  41. package/dist_ts/features/feature.print.js +226 -0
  42. package/dist_ts/features/feature.scan.d.ts +79 -0
  43. package/dist_ts/features/feature.scan.js +315 -0
  44. package/dist_ts/features/feature.sensor.d.ts +95 -0
  45. package/dist_ts/features/feature.sensor.js +147 -0
  46. package/dist_ts/features/feature.snmp.d.ts +88 -0
  47. package/dist_ts/features/feature.snmp.js +175 -0
  48. package/dist_ts/features/feature.switch.d.ts +75 -0
  49. package/dist_ts/features/feature.switch.js +126 -0
  50. package/dist_ts/features/feature.volume.d.ts +104 -0
  51. package/dist_ts/features/feature.volume.js +186 -0
  52. package/dist_ts/features/index.d.ts +19 -0
  53. package/dist_ts/features/index.js +23 -0
  54. package/dist_ts/helpers/helpers.iprange.d.ts +35 -0
  55. package/dist_ts/helpers/helpers.iprange.js +151 -0
  56. package/dist_ts/helpers/helpers.retry.d.ts +25 -0
  57. package/dist_ts/helpers/helpers.retry.js +69 -0
  58. package/dist_ts/index.d.ts +15 -0
  59. package/dist_ts/index.js +40 -0
  60. package/dist_ts/interfaces/feature.interfaces.d.ts +255 -0
  61. package/dist_ts/interfaces/feature.interfaces.js +6 -0
  62. package/dist_ts/interfaces/homeassistant.interfaces.d.ts +550 -0
  63. package/dist_ts/interfaces/homeassistant.interfaces.js +111 -0
  64. package/dist_ts/interfaces/index.d.ts +330 -0
  65. package/dist_ts/interfaces/index.js +16 -0
  66. package/dist_ts/interfaces/smarthome.interfaces.d.ts +282 -0
  67. package/dist_ts/interfaces/smarthome.interfaces.js +7 -0
  68. package/dist_ts/paths.d.ts +1 -0
  69. package/dist_ts/paths.js +3 -0
  70. package/dist_ts/plugins.d.ts +23 -0
  71. package/dist_ts/plugins.js +30 -0
  72. package/dist_ts/protocols/index.d.ts +12 -0
  73. package/dist_ts/protocols/index.js +21 -0
  74. package/dist_ts/protocols/protocol.escl.d.ts +58 -0
  75. package/dist_ts/protocols/protocol.escl.js +364 -0
  76. package/dist_ts/protocols/protocol.homeassistant.d.ts +248 -0
  77. package/dist_ts/protocols/protocol.homeassistant.js +611 -0
  78. package/dist_ts/protocols/protocol.ipp.d.ts +45 -0
  79. package/dist_ts/protocols/protocol.ipp.js +284 -0
  80. package/dist_ts/protocols/protocol.nut.d.ts +160 -0
  81. package/dist_ts/protocols/protocol.nut.js +364 -0
  82. package/dist_ts/protocols/protocol.sane.d.ts +104 -0
  83. package/dist_ts/protocols/protocol.sane.js +597 -0
  84. package/dist_ts/protocols/protocol.snmp.d.ts +133 -0
  85. package/dist_ts/protocols/protocol.snmp.js +333 -0
  86. package/dist_ts/protocols/protocol.upnp.d.ts +207 -0
  87. package/dist_ts/protocols/protocol.upnp.js +442 -0
  88. package/dist_ts/protocols/protocol.upssnmp.d.ts +160 -0
  89. package/dist_ts/protocols/protocol.upssnmp.js +263 -0
  90. package/npmextra.json +24 -0
  91. package/package.json +39 -0
  92. package/readme.hints.md +115 -0
  93. package/readme.md +624 -0
  94. package/test/test.ts +261 -0
  95. package/ts/00_commitinfo_data.ts +8 -0
  96. package/ts/device/device.classes.device.ts +454 -0
  97. package/ts/devicemanager.classes.devicemanager.ts +1219 -0
  98. package/ts/discovery/discovery.classes.homeassistant.ts +376 -0
  99. package/ts/discovery/discovery.classes.mdns.ts +347 -0
  100. package/ts/discovery/discovery.classes.networkscanner.ts +648 -0
  101. package/ts/discovery/discovery.classes.ssdp.ts +357 -0
  102. package/ts/factories/index.ts +696 -0
  103. package/ts/features/feature.abstract.ts +251 -0
  104. package/ts/features/feature.camera.ts +214 -0
  105. package/ts/features/feature.climate.ts +407 -0
  106. package/ts/features/feature.cover.ts +278 -0
  107. package/ts/features/feature.fan.ts +296 -0
  108. package/ts/features/feature.light.ts +369 -0
  109. package/ts/features/feature.lock.ts +223 -0
  110. package/ts/features/feature.playback.ts +246 -0
  111. package/ts/features/feature.power.ts +231 -0
  112. package/ts/features/feature.print.ts +297 -0
  113. package/ts/features/feature.scan.ts +370 -0
  114. package/ts/features/feature.sensor.ts +202 -0
  115. package/ts/features/feature.snmp.ts +235 -0
  116. package/ts/features/feature.switch.ts +170 -0
  117. package/ts/features/feature.volume.ts +256 -0
  118. package/ts/features/index.ts +25 -0
  119. package/ts/helpers/helpers.iprange.ts +172 -0
  120. package/ts/helpers/helpers.retry.ts +100 -0
  121. package/ts/index.ts +165 -0
  122. package/ts/interfaces/feature.interfaces.ts +359 -0
  123. package/ts/interfaces/homeassistant.interfaces.ts +666 -0
  124. package/ts/interfaces/index.ts +421 -0
  125. package/ts/interfaces/smarthome.interfaces.ts +421 -0
  126. package/ts/paths.ts +5 -0
  127. package/ts/plugins.ts +41 -0
  128. package/ts/protocols/index.ts +59 -0
  129. package/ts/protocols/protocol.escl.ts +439 -0
  130. package/ts/protocols/protocol.homeassistant.ts +737 -0
  131. package/ts/protocols/protocol.ipp.ts +329 -0
  132. package/ts/protocols/protocol.nut.ts +471 -0
  133. package/ts/protocols/protocol.sane.ts +694 -0
  134. package/ts/protocols/protocol.snmp.ts +439 -0
  135. package/ts/protocols/protocol.upnp.ts +627 -0
  136. package/ts/protocols/protocol.upssnmp.ts +377 -0
  137. package/tsconfig.json +12 -0
@@ -0,0 +1,666 @@
1
+ /**
2
+ * Home Assistant Specific Interfaces
3
+ * Types for Home Assistant WebSocket API, entities, and configuration
4
+ */
5
+
6
+ // ============================================================================
7
+ // Configuration
8
+ // ============================================================================
9
+
10
+ /**
11
+ * Configuration for connecting to a Home Assistant instance
12
+ */
13
+ export interface IHomeAssistantInstanceConfig {
14
+ /** Home Assistant host (IP or hostname) */
15
+ host: string;
16
+ /** Port number (default: 8123) */
17
+ port?: number;
18
+ /** Long-lived access token from HA */
19
+ token: string;
20
+ /** Use secure WebSocket (wss://) */
21
+ secure?: boolean;
22
+ /** Friendly name for this instance */
23
+ friendlyName?: string;
24
+ /** Auto-reconnect on disconnect (default: true) */
25
+ autoReconnect?: boolean;
26
+ /** Reconnect delay in ms (default: 5000) */
27
+ reconnectDelay?: number;
28
+ }
29
+
30
+ /**
31
+ * Home Assistant configuration in DeviceManager options
32
+ */
33
+ export interface IHomeAssistantOptions {
34
+ /** Enable mDNS auto-discovery of HA instances */
35
+ autoDiscovery?: boolean;
36
+ /** Manually configured HA instances */
37
+ instances?: IHomeAssistantInstanceConfig[];
38
+ /** Filter: only discover these domains (default: all) */
39
+ enabledDomains?: THomeAssistantDomain[];
40
+ /** Auto-reconnect on disconnect (default: true) */
41
+ autoReconnect?: boolean;
42
+ /** Reconnect delay in ms (default: 5000) */
43
+ reconnectDelay?: number;
44
+ }
45
+
46
+ // ============================================================================
47
+ // Entity Types
48
+ // ============================================================================
49
+
50
+ /**
51
+ * Supported Home Assistant domains that map to features
52
+ */
53
+ export type THomeAssistantDomain =
54
+ | 'light'
55
+ | 'switch'
56
+ | 'sensor'
57
+ | 'binary_sensor'
58
+ | 'climate'
59
+ | 'fan'
60
+ | 'cover'
61
+ | 'lock'
62
+ | 'camera'
63
+ | 'media_player';
64
+
65
+ /**
66
+ * Home Assistant entity state
67
+ */
68
+ export interface IHomeAssistantEntity {
69
+ /** Entity ID (e.g., "light.living_room") */
70
+ entity_id: string;
71
+ /** Current state value (e.g., "on", "off", "25.5") */
72
+ state: string;
73
+ /** Additional attributes */
74
+ attributes: IHomeAssistantEntityAttributes;
75
+ /** Last changed timestamp */
76
+ last_changed: string;
77
+ /** Last updated timestamp */
78
+ last_updated: string;
79
+ /** Context information */
80
+ context: IHomeAssistantContext;
81
+ }
82
+
83
+ /**
84
+ * Common entity attributes
85
+ */
86
+ export interface IHomeAssistantEntityAttributes {
87
+ /** Friendly name */
88
+ friendly_name?: string;
89
+ /** Device class */
90
+ device_class?: string;
91
+ /** Unit of measurement */
92
+ unit_of_measurement?: string;
93
+ /** Icon */
94
+ icon?: string;
95
+ /** Entity category */
96
+ entity_category?: string;
97
+ /** Assumed state (for optimistic updates) */
98
+ assumed_state?: boolean;
99
+ /** Supported features bitmask */
100
+ supported_features?: number;
101
+ /** Additional dynamic attributes */
102
+ [key: string]: unknown;
103
+ }
104
+
105
+ /**
106
+ * Light-specific attributes
107
+ */
108
+ export interface IHomeAssistantLightAttributes extends IHomeAssistantEntityAttributes {
109
+ brightness?: number; // 0-255
110
+ color_temp?: number; // Mireds
111
+ color_temp_kelvin?: number; // Kelvin
112
+ hs_color?: [number, number]; // [hue 0-360, saturation 0-100]
113
+ rgb_color?: [number, number, number];
114
+ xy_color?: [number, number];
115
+ rgbw_color?: [number, number, number, number];
116
+ rgbww_color?: [number, number, number, number, number];
117
+ effect?: string;
118
+ effect_list?: string[];
119
+ color_mode?: string;
120
+ supported_color_modes?: string[];
121
+ min_mireds?: number;
122
+ max_mireds?: number;
123
+ min_color_temp_kelvin?: number;
124
+ max_color_temp_kelvin?: number;
125
+ }
126
+
127
+ /**
128
+ * Climate-specific attributes
129
+ */
130
+ export interface IHomeAssistantClimateAttributes extends IHomeAssistantEntityAttributes {
131
+ hvac_modes?: string[];
132
+ hvac_action?: string;
133
+ current_temperature?: number;
134
+ target_temp_high?: number;
135
+ target_temp_low?: number;
136
+ temperature?: number;
137
+ preset_mode?: string;
138
+ preset_modes?: string[];
139
+ fan_mode?: string;
140
+ fan_modes?: string[];
141
+ swing_mode?: string;
142
+ swing_modes?: string[];
143
+ aux_heat?: boolean;
144
+ current_humidity?: number;
145
+ humidity?: number;
146
+ min_temp?: number;
147
+ max_temp?: number;
148
+ target_temp_step?: number;
149
+ min_humidity?: number;
150
+ max_humidity?: number;
151
+ }
152
+
153
+ /**
154
+ * Sensor-specific attributes
155
+ */
156
+ export interface IHomeAssistantSensorAttributes extends IHomeAssistantEntityAttributes {
157
+ state_class?: 'measurement' | 'total' | 'total_increasing';
158
+ native_unit_of_measurement?: string;
159
+ native_value?: string | number;
160
+ }
161
+
162
+ /**
163
+ * Cover-specific attributes
164
+ */
165
+ export interface IHomeAssistantCoverAttributes extends IHomeAssistantEntityAttributes {
166
+ current_position?: number; // 0-100
167
+ current_tilt_position?: number; // 0-100
168
+ }
169
+
170
+ /**
171
+ * Fan-specific attributes
172
+ */
173
+ export interface IHomeAssistantFanAttributes extends IHomeAssistantEntityAttributes {
174
+ percentage?: number; // 0-100
175
+ percentage_step?: number;
176
+ preset_mode?: string;
177
+ preset_modes?: string[];
178
+ oscillating?: boolean;
179
+ direction?: 'forward' | 'reverse';
180
+ }
181
+
182
+ /**
183
+ * Lock-specific attributes
184
+ */
185
+ export interface IHomeAssistantLockAttributes extends IHomeAssistantEntityAttributes {
186
+ is_locked?: boolean;
187
+ is_locking?: boolean;
188
+ is_unlocking?: boolean;
189
+ is_jammed?: boolean;
190
+ }
191
+
192
+ /**
193
+ * Camera-specific attributes
194
+ */
195
+ export interface IHomeAssistantCameraAttributes extends IHomeAssistantEntityAttributes {
196
+ access_token?: string;
197
+ entity_picture?: string;
198
+ frontend_stream_type?: 'hls' | 'web_rtc';
199
+ is_streaming?: boolean;
200
+ motion_detection?: boolean;
201
+ }
202
+
203
+ /**
204
+ * Media player-specific attributes
205
+ */
206
+ export interface IHomeAssistantMediaPlayerAttributes extends IHomeAssistantEntityAttributes {
207
+ volume_level?: number; // 0-1
208
+ is_volume_muted?: boolean;
209
+ media_content_id?: string;
210
+ media_content_type?: string;
211
+ media_duration?: number;
212
+ media_position?: number;
213
+ media_position_updated_at?: string;
214
+ media_title?: string;
215
+ media_artist?: string;
216
+ media_album_name?: string;
217
+ media_album_artist?: string;
218
+ media_track?: number;
219
+ media_series_title?: string;
220
+ media_season?: number;
221
+ media_episode?: number;
222
+ app_id?: string;
223
+ app_name?: string;
224
+ source?: string;
225
+ source_list?: string[];
226
+ sound_mode?: string;
227
+ sound_mode_list?: string[];
228
+ shuffle?: boolean;
229
+ repeat?: 'off' | 'all' | 'one';
230
+ entity_picture_local?: string;
231
+ }
232
+
233
+ /**
234
+ * Context for entity state changes
235
+ */
236
+ export interface IHomeAssistantContext {
237
+ id: string;
238
+ parent_id?: string;
239
+ user_id?: string;
240
+ }
241
+
242
+ // ============================================================================
243
+ // WebSocket Message Types
244
+ // ============================================================================
245
+
246
+ /**
247
+ * Base message structure
248
+ */
249
+ export interface IHomeAssistantMessage {
250
+ id?: number;
251
+ type: string;
252
+ }
253
+
254
+ /**
255
+ * Authentication required message
256
+ */
257
+ export interface IHomeAssistantAuthRequired extends IHomeAssistantMessage {
258
+ type: 'auth_required';
259
+ ha_version: string;
260
+ }
261
+
262
+ /**
263
+ * Authentication message to send
264
+ */
265
+ export interface IHomeAssistantAuth extends IHomeAssistantMessage {
266
+ type: 'auth';
267
+ access_token: string;
268
+ }
269
+
270
+ /**
271
+ * Authentication success
272
+ */
273
+ export interface IHomeAssistantAuthOk extends IHomeAssistantMessage {
274
+ type: 'auth_ok';
275
+ ha_version: string;
276
+ }
277
+
278
+ /**
279
+ * Authentication invalid
280
+ */
281
+ export interface IHomeAssistantAuthInvalid extends IHomeAssistantMessage {
282
+ type: 'auth_invalid';
283
+ message: string;
284
+ }
285
+
286
+ /**
287
+ * Result message
288
+ */
289
+ export interface IHomeAssistantResult extends IHomeAssistantMessage {
290
+ id: number;
291
+ type: 'result';
292
+ success: boolean;
293
+ result?: unknown;
294
+ error?: {
295
+ code: string;
296
+ message: string;
297
+ };
298
+ }
299
+
300
+ /**
301
+ * Event message
302
+ */
303
+ export interface IHomeAssistantEvent extends IHomeAssistantMessage {
304
+ id: number;
305
+ type: 'event';
306
+ event: {
307
+ event_type: string;
308
+ data: unknown;
309
+ origin: string;
310
+ time_fired: string;
311
+ context: IHomeAssistantContext;
312
+ };
313
+ }
314
+
315
+ /**
316
+ * State changed event data
317
+ */
318
+ export interface IHomeAssistantStateChangedEvent {
319
+ entity_id: string;
320
+ old_state: IHomeAssistantEntity | null;
321
+ new_state: IHomeAssistantEntity | null;
322
+ }
323
+
324
+ /**
325
+ * Subscribe events request
326
+ */
327
+ export interface IHomeAssistantSubscribeEvents extends IHomeAssistantMessage {
328
+ id: number;
329
+ type: 'subscribe_events';
330
+ event_type?: string;
331
+ }
332
+
333
+ /**
334
+ * Get states request
335
+ */
336
+ export interface IHomeAssistantGetStates extends IHomeAssistantMessage {
337
+ id: number;
338
+ type: 'get_states';
339
+ }
340
+
341
+ /**
342
+ * Call service request
343
+ */
344
+ export interface IHomeAssistantCallService extends IHomeAssistantMessage {
345
+ id: number;
346
+ type: 'call_service';
347
+ domain: string;
348
+ service: string;
349
+ target?: {
350
+ entity_id?: string | string[];
351
+ device_id?: string | string[];
352
+ area_id?: string | string[];
353
+ };
354
+ service_data?: Record<string, unknown>;
355
+ }
356
+
357
+ /**
358
+ * Get services request
359
+ */
360
+ export interface IHomeAssistantGetServices extends IHomeAssistantMessage {
361
+ id: number;
362
+ type: 'get_services';
363
+ }
364
+
365
+ /**
366
+ * Get config request
367
+ */
368
+ export interface IHomeAssistantGetConfig extends IHomeAssistantMessage {
369
+ id: number;
370
+ type: 'get_config';
371
+ }
372
+
373
+ /**
374
+ * Home Assistant config response
375
+ */
376
+ export interface IHomeAssistantConfig {
377
+ latitude: number;
378
+ longitude: number;
379
+ elevation: number;
380
+ unit_system: {
381
+ length: string;
382
+ mass: string;
383
+ pressure: string;
384
+ temperature: string;
385
+ volume: string;
386
+ };
387
+ location_name: string;
388
+ time_zone: string;
389
+ components: string[];
390
+ config_dir: string;
391
+ allowlist_external_dirs: string[];
392
+ allowlist_external_urls: string[];
393
+ version: string;
394
+ config_source: string;
395
+ safe_mode: boolean;
396
+ state: 'NOT_RUNNING' | 'STARTING' | 'RUNNING' | 'STOPPING' | 'FINAL_WRITE';
397
+ external_url: string | null;
398
+ internal_url: string | null;
399
+ currency: string;
400
+ country: string;
401
+ language: string;
402
+ }
403
+
404
+ // ============================================================================
405
+ // Service Definitions
406
+ // ============================================================================
407
+
408
+ /**
409
+ * Light service data
410
+ */
411
+ export interface IHomeAssistantLightServiceData {
412
+ brightness?: number; // 0-255
413
+ brightness_pct?: number; // 0-100
414
+ brightness_step?: number; // Step to increase/decrease
415
+ brightness_step_pct?: number; // Step percentage
416
+ color_temp?: number; // Mireds
417
+ color_temp_kelvin?: number; // Kelvin
418
+ hs_color?: [number, number]; // [hue, saturation]
419
+ rgb_color?: [number, number, number];
420
+ xy_color?: [number, number];
421
+ rgbw_color?: [number, number, number, number];
422
+ rgbww_color?: [number, number, number, number, number];
423
+ color_name?: string;
424
+ kelvin?: number;
425
+ effect?: string;
426
+ transition?: number; // Seconds
427
+ flash?: 'short' | 'long';
428
+ profile?: string;
429
+ [key: string]: unknown; // Index signature for Record<string, unknown>
430
+ }
431
+
432
+ /**
433
+ * Climate service data
434
+ */
435
+ export interface IHomeAssistantClimateServiceData {
436
+ hvac_mode?: string;
437
+ temperature?: number;
438
+ target_temp_high?: number;
439
+ target_temp_low?: number;
440
+ humidity?: number;
441
+ fan_mode?: string;
442
+ swing_mode?: string;
443
+ preset_mode?: string;
444
+ aux_heat?: boolean;
445
+ [key: string]: unknown; // Index signature for Record<string, unknown>
446
+ }
447
+
448
+ /**
449
+ * Cover service data
450
+ */
451
+ export interface IHomeAssistantCoverServiceData {
452
+ position?: number; // 0-100
453
+ tilt_position?: number; // 0-100
454
+ }
455
+
456
+ /**
457
+ * Fan service data
458
+ */
459
+ export interface IHomeAssistantFanServiceData {
460
+ percentage?: number; // 0-100
461
+ percentage_step?: number;
462
+ preset_mode?: string;
463
+ direction?: 'forward' | 'reverse';
464
+ oscillating?: boolean;
465
+ [key: string]: unknown; // Index signature for Record<string, unknown>
466
+ }
467
+
468
+ /**
469
+ * Media player service data
470
+ */
471
+ export interface IHomeAssistantMediaPlayerServiceData {
472
+ volume_level?: number; // 0-1
473
+ is_volume_muted?: boolean;
474
+ media_content_id?: string;
475
+ media_content_type?: string;
476
+ enqueue?: 'play' | 'next' | 'add' | 'replace';
477
+ seek_position?: number;
478
+ source?: string;
479
+ sound_mode?: string;
480
+ shuffle?: boolean;
481
+ repeat?: 'off' | 'all' | 'one';
482
+ }
483
+
484
+ // ============================================================================
485
+ // Discovery Types
486
+ // ============================================================================
487
+
488
+ /**
489
+ * Discovered Home Assistant instance via mDNS
490
+ */
491
+ export interface IHomeAssistantDiscoveredInstance {
492
+ /** Instance ID (derived from host) */
493
+ id: string;
494
+ /** Host address */
495
+ host: string;
496
+ /** Port number */
497
+ port: number;
498
+ /** Base URL */
499
+ base_url: string;
500
+ /** mDNS TXT records */
501
+ txtRecords: Record<string, string>;
502
+ /** Whether connection requires token */
503
+ requires_api_password: boolean;
504
+ /** Friendly name from mDNS */
505
+ friendlyName?: string;
506
+ }
507
+
508
+ // ============================================================================
509
+ // Protocol Events
510
+ // ============================================================================
511
+
512
+ /**
513
+ * Events emitted by HomeAssistantProtocol
514
+ */
515
+ export type THomeAssistantProtocolEvents = {
516
+ 'connected': () => void;
517
+ 'disconnected': () => void;
518
+ 'reconnecting': (attempt: number) => void;
519
+ 'authenticated': (config: IHomeAssistantConfig) => void;
520
+ 'auth:failed': (message: string) => void;
521
+ 'state:changed': (event: IHomeAssistantStateChangedEvent) => void;
522
+ 'states:loaded': (entities: IHomeAssistantEntity[]) => void;
523
+ 'error': (error: Error) => void;
524
+ };
525
+
526
+ /**
527
+ * Events emitted by HomeAssistantDiscovery
528
+ */
529
+ export type THomeAssistantDiscoveryEvents = {
530
+ 'instance:found': (instance: IHomeAssistantDiscoveredInstance) => void;
531
+ 'instance:lost': (instanceId: string) => void;
532
+ 'entity:found': (entity: IHomeAssistantEntity) => void;
533
+ 'entity:updated': (entity: IHomeAssistantEntity) => void;
534
+ 'entity:removed': (entityId: string) => void;
535
+ 'error': (error: Error) => void;
536
+ };
537
+
538
+ // ============================================================================
539
+ // Helper Types
540
+ // ============================================================================
541
+
542
+ /**
543
+ * Extract domain from entity_id
544
+ */
545
+ export function getEntityDomain(entityId: string): THomeAssistantDomain | null {
546
+ const domain = entityId.split('.')[0];
547
+ const validDomains: THomeAssistantDomain[] = [
548
+ 'light', 'switch', 'sensor', 'binary_sensor', 'climate',
549
+ 'fan', 'cover', 'lock', 'camera', 'media_player'
550
+ ];
551
+ return validDomains.includes(domain as THomeAssistantDomain)
552
+ ? domain as THomeAssistantDomain
553
+ : null;
554
+ }
555
+
556
+ /**
557
+ * Map HA domain to feature type
558
+ */
559
+ export function domainToFeatureType(domain: THomeAssistantDomain): string {
560
+ const mapping: Record<THomeAssistantDomain, string> = {
561
+ 'light': 'light',
562
+ 'switch': 'switch',
563
+ 'sensor': 'sensor',
564
+ 'binary_sensor': 'sensor',
565
+ 'climate': 'climate',
566
+ 'fan': 'fan',
567
+ 'cover': 'cover',
568
+ 'lock': 'lock',
569
+ 'camera': 'camera',
570
+ 'media_player': 'playback',
571
+ };
572
+ return mapping[domain];
573
+ }
574
+
575
+ /**
576
+ * Supported light color modes in HA
577
+ */
578
+ export type THomeAssistantColorMode =
579
+ | 'unknown'
580
+ | 'onoff'
581
+ | 'brightness'
582
+ | 'color_temp'
583
+ | 'hs'
584
+ | 'xy'
585
+ | 'rgb'
586
+ | 'rgbw'
587
+ | 'rgbww'
588
+ | 'white';
589
+
590
+ /**
591
+ * Light supported features bitmask
592
+ */
593
+ export const LIGHT_SUPPORT = {
594
+ EFFECT: 4,
595
+ FLASH: 8,
596
+ TRANSITION: 32,
597
+ } as const;
598
+
599
+ /**
600
+ * Climate supported features bitmask
601
+ */
602
+ export const CLIMATE_SUPPORT = {
603
+ TARGET_TEMPERATURE: 1,
604
+ TARGET_TEMPERATURE_RANGE: 2,
605
+ TARGET_HUMIDITY: 4,
606
+ FAN_MODE: 8,
607
+ PRESET_MODE: 16,
608
+ SWING_MODE: 32,
609
+ AUX_HEAT: 64,
610
+ } as const;
611
+
612
+ /**
613
+ * Cover supported features bitmask
614
+ */
615
+ export const COVER_SUPPORT = {
616
+ OPEN: 1,
617
+ CLOSE: 2,
618
+ SET_POSITION: 4,
619
+ STOP: 8,
620
+ OPEN_TILT: 16,
621
+ CLOSE_TILT: 32,
622
+ STOP_TILT: 64,
623
+ SET_TILT_POSITION: 128,
624
+ } as const;
625
+
626
+ /**
627
+ * Fan supported features bitmask
628
+ */
629
+ export const FAN_SUPPORT = {
630
+ SET_SPEED: 1,
631
+ OSCILLATE: 2,
632
+ DIRECTION: 4,
633
+ PRESET_MODE: 8,
634
+ } as const;
635
+
636
+ /**
637
+ * Lock supported features bitmask
638
+ */
639
+ export const LOCK_SUPPORT = {
640
+ OPEN: 1,
641
+ } as const;
642
+
643
+ /**
644
+ * Media player supported features bitmask
645
+ */
646
+ export const MEDIA_PLAYER_SUPPORT = {
647
+ PAUSE: 1,
648
+ SEEK: 2,
649
+ VOLUME_SET: 4,
650
+ VOLUME_MUTE: 8,
651
+ PREVIOUS_TRACK: 16,
652
+ NEXT_TRACK: 32,
653
+ TURN_ON: 128,
654
+ TURN_OFF: 256,
655
+ PLAY_MEDIA: 512,
656
+ VOLUME_STEP: 1024,
657
+ SELECT_SOURCE: 2048,
658
+ STOP: 4096,
659
+ CLEAR_PLAYLIST: 8192,
660
+ PLAY: 16384,
661
+ SHUFFLE_SET: 32768,
662
+ SELECT_SOUND_MODE: 65536,
663
+ BROWSE_MEDIA: 131072,
664
+ REPEAT_SET: 262144,
665
+ GROUPING: 524288,
666
+ } as const;