lifx-emulator 2.3.1__py3-none-any.whl → 3.0.1__py3-none-any.whl

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 (68) hide show
  1. lifx_emulator-3.0.1.dist-info/METADATA +102 -0
  2. lifx_emulator-3.0.1.dist-info/RECORD +18 -0
  3. lifx_emulator-3.0.1.dist-info/entry_points.txt +2 -0
  4. lifx_emulator_app/__init__.py +10 -0
  5. {lifx_emulator → lifx_emulator_app}/__main__.py +13 -5
  6. {lifx_emulator → lifx_emulator_app}/api/__init__.py +1 -1
  7. {lifx_emulator → lifx_emulator_app}/api/app.py +3 -3
  8. {lifx_emulator → lifx_emulator_app}/api/mappers/__init__.py +1 -1
  9. {lifx_emulator → lifx_emulator_app}/api/mappers/device_mapper.py +1 -1
  10. {lifx_emulator → lifx_emulator_app}/api/models.py +1 -2
  11. lifx_emulator_app/api/routers/__init__.py +11 -0
  12. {lifx_emulator → lifx_emulator_app}/api/routers/devices.py +2 -2
  13. {lifx_emulator → lifx_emulator_app}/api/routers/monitoring.py +1 -1
  14. {lifx_emulator → lifx_emulator_app}/api/routers/scenarios.py +1 -1
  15. lifx_emulator_app/api/services/__init__.py +8 -0
  16. {lifx_emulator → lifx_emulator_app}/api/services/device_service.py +3 -2
  17. lifx_emulator/__init__.py +0 -31
  18. lifx_emulator/api/routers/__init__.py +0 -11
  19. lifx_emulator/api/services/__init__.py +0 -8
  20. lifx_emulator/constants.py +0 -33
  21. lifx_emulator/devices/__init__.py +0 -37
  22. lifx_emulator/devices/device.py +0 -339
  23. lifx_emulator/devices/manager.py +0 -256
  24. lifx_emulator/devices/observers.py +0 -139
  25. lifx_emulator/devices/persistence.py +0 -308
  26. lifx_emulator/devices/state_restorer.py +0 -259
  27. lifx_emulator/devices/state_serializer.py +0 -157
  28. lifx_emulator/devices/states.py +0 -377
  29. lifx_emulator/factories/__init__.py +0 -37
  30. lifx_emulator/factories/builder.py +0 -373
  31. lifx_emulator/factories/default_config.py +0 -158
  32. lifx_emulator/factories/factory.py +0 -221
  33. lifx_emulator/factories/firmware_config.py +0 -77
  34. lifx_emulator/factories/serial_generator.py +0 -82
  35. lifx_emulator/handlers/__init__.py +0 -39
  36. lifx_emulator/handlers/base.py +0 -49
  37. lifx_emulator/handlers/device_handlers.py +0 -322
  38. lifx_emulator/handlers/light_handlers.py +0 -503
  39. lifx_emulator/handlers/multizone_handlers.py +0 -249
  40. lifx_emulator/handlers/registry.py +0 -110
  41. lifx_emulator/handlers/tile_handlers.py +0 -488
  42. lifx_emulator/products/__init__.py +0 -28
  43. lifx_emulator/products/generator.py +0 -1037
  44. lifx_emulator/products/registry.py +0 -1496
  45. lifx_emulator/products/specs.py +0 -284
  46. lifx_emulator/products/specs.yml +0 -352
  47. lifx_emulator/protocol/__init__.py +0 -1
  48. lifx_emulator/protocol/base.py +0 -446
  49. lifx_emulator/protocol/const.py +0 -8
  50. lifx_emulator/protocol/generator.py +0 -1384
  51. lifx_emulator/protocol/header.py +0 -159
  52. lifx_emulator/protocol/packets.py +0 -1351
  53. lifx_emulator/protocol/protocol_types.py +0 -817
  54. lifx_emulator/protocol/serializer.py +0 -379
  55. lifx_emulator/repositories/__init__.py +0 -22
  56. lifx_emulator/repositories/device_repository.py +0 -155
  57. lifx_emulator/repositories/storage_backend.py +0 -107
  58. lifx_emulator/scenarios/__init__.py +0 -22
  59. lifx_emulator/scenarios/manager.py +0 -322
  60. lifx_emulator/scenarios/models.py +0 -112
  61. lifx_emulator/scenarios/persistence.py +0 -241
  62. lifx_emulator/server.py +0 -464
  63. lifx_emulator-2.3.1.dist-info/METADATA +0 -107
  64. lifx_emulator-2.3.1.dist-info/RECORD +0 -62
  65. lifx_emulator-2.3.1.dist-info/entry_points.txt +0 -2
  66. lifx_emulator-2.3.1.dist-info/licenses/LICENSE +0 -35
  67. {lifx_emulator-2.3.1.dist-info → lifx_emulator-3.0.1.dist-info}/WHEEL +0 -0
  68. {lifx_emulator → lifx_emulator_app}/api/templates/dashboard.html +0 -0
@@ -1,1496 +0,0 @@
1
- """LIFX product definitions and capability detection.
2
-
3
- DO NOT EDIT THIS FILE MANUALLY.
4
- Generated from https://github.com/LIFX/products/blob/master/products.json
5
- by products/generator.py
6
-
7
- This module provides pre-generated product information for efficient runtime lookups.
8
- """
9
-
10
- from __future__ import annotations
11
-
12
- from dataclasses import dataclass
13
- from enum import IntEnum
14
- from functools import cached_property
15
-
16
-
17
- class ProductCapability(IntEnum):
18
- """Product capability flags."""
19
-
20
- COLOR = 1
21
- INFRARED = 2
22
- MULTIZONE = 4
23
- CHAIN = 8
24
- MATRIX = 16
25
- RELAYS = 32
26
- BUTTONS = 64
27
- HEV = 128
28
- EXTENDED_MULTIZONE = 256
29
-
30
-
31
- @dataclass
32
- class TemperatureRange:
33
- """Color temperature range in Kelvin."""
34
-
35
- min: int
36
- max: int
37
-
38
-
39
- @dataclass
40
- class ProductInfo:
41
- """Information about a LIFX product.
42
-
43
- Attributes:
44
- pid: Product ID
45
- name: Product name
46
- vendor: Vendor ID (always 1 for LIFX)
47
- capabilities: Bitfield of ProductCapability flags
48
- temperature_range: Min/max color temperature in Kelvin
49
- min_ext_mz_firmware: Minimum firmware version for extended multizone
50
- """
51
-
52
- pid: int
53
- name: str
54
- vendor: int
55
- capabilities: int
56
- temperature_range: TemperatureRange | None
57
- min_ext_mz_firmware: int | None
58
-
59
- def has_capability(self, capability: ProductCapability) -> bool:
60
- """Check if product has a specific capability.
61
-
62
- Args:
63
- capability: Capability to check
64
-
65
- Returns:
66
- True if product has the capability
67
- """
68
- return bool(self.capabilities & capability)
69
-
70
- @property
71
- def has_color(self) -> bool:
72
- """Check if product supports color."""
73
- return self.has_capability(ProductCapability.COLOR)
74
-
75
- @property
76
- def has_infrared(self) -> bool:
77
- """Check if product supports infrared."""
78
- return self.has_capability(ProductCapability.INFRARED)
79
-
80
- @property
81
- def has_multizone(self) -> bool:
82
- """Check if product supports multizone."""
83
- return self.has_capability(ProductCapability.MULTIZONE)
84
-
85
- @property
86
- def has_chain(self) -> bool:
87
- """Check if product supports chaining."""
88
- return self.has_capability(ProductCapability.CHAIN)
89
-
90
- @property
91
- def has_matrix(self) -> bool:
92
- """Check if product supports matrix (2D grid)."""
93
- return self.has_capability(ProductCapability.MATRIX)
94
-
95
- @property
96
- def has_relays(self) -> bool:
97
- """Check if product has relays."""
98
- return self.has_capability(ProductCapability.RELAYS)
99
-
100
- @property
101
- def has_buttons(self) -> bool:
102
- """Check if product has buttons."""
103
- return self.has_capability(ProductCapability.BUTTONS)
104
-
105
- @property
106
- def has_hev(self) -> bool:
107
- """Check if product supports HEV."""
108
- return self.has_capability(ProductCapability.HEV)
109
-
110
- @property
111
- def has_extended_multizone(self) -> bool:
112
- """Check if product supports extended multizone."""
113
- return self.has_capability(ProductCapability.EXTENDED_MULTIZONE)
114
-
115
- def supports_extended_multizone(self, firmware_version: int | None = None) -> bool:
116
- """Check if extended multizone is supported for given firmware version.
117
-
118
- Args:
119
- firmware_version: Firmware version to check (optional)
120
-
121
- Returns:
122
- True if extended multizone is supported
123
- """
124
- if not self.has_extended_multizone:
125
- return False
126
- if self.min_ext_mz_firmware is None:
127
- return True
128
- if firmware_version is None:
129
- return True
130
- return firmware_version >= self.min_ext_mz_firmware
131
-
132
- @cached_property
133
- def caps(self) -> str:
134
- """Format product capabilities as a human-readable string.
135
-
136
- Returns:
137
- Comma-separated capability string (e.g., "full color, infrared, multizone")
138
- """
139
- caps = []
140
-
141
- # Determine base light type
142
- if self.has_relays:
143
- # Devices with relays are switches, not lights
144
- caps.append("switch")
145
- elif self.has_color:
146
- caps.append("full color")
147
- else:
148
- # Check temperature range to determine white light type
149
- if self.temperature_range:
150
- if self.temperature_range.min != self.temperature_range.max:
151
- caps.append("color temperature")
152
- else:
153
- caps.append("brightness only")
154
- else:
155
- # No temperature range info, assume basic brightness
156
- caps.append("brightness only")
157
-
158
- # Add additional capabilities
159
- if self.has_infrared:
160
- caps.append("infrared")
161
- # Extended multizone is backwards compatible with multizone,
162
- # so only show multizone if extended multizone is not present
163
- if self.has_extended_multizone:
164
- caps.append("extended-multizone")
165
- elif self.has_multizone:
166
- caps.append("multizone")
167
- if self.has_matrix:
168
- caps.append("matrix")
169
- if self.has_hev:
170
- caps.append("HEV")
171
- if self.has_chain:
172
- caps.append("chain")
173
- if self.has_buttons and not self.has_relays:
174
- # Only show buttons if not already identified as switch
175
- caps.append("buttons")
176
-
177
- return ", ".join(caps) if caps else "unknown"
178
-
179
-
180
- # Pre-generated product definitions
181
- PRODUCTS: dict[int, ProductInfo] = {
182
- 1: ProductInfo(
183
- pid=1,
184
- name="LIFX Original 1000",
185
- vendor=1,
186
- capabilities=ProductCapability.COLOR,
187
- temperature_range=TemperatureRange(min=2500, max=9000),
188
- min_ext_mz_firmware=None,
189
- ),
190
- 3: ProductInfo(
191
- pid=3,
192
- name="LIFX Color 650",
193
- vendor=1,
194
- capabilities=ProductCapability.COLOR,
195
- temperature_range=TemperatureRange(min=2500, max=9000),
196
- min_ext_mz_firmware=None,
197
- ),
198
- 10: ProductInfo(
199
- pid=10,
200
- name="LIFX White 800 (Low Voltage)",
201
- vendor=1,
202
- capabilities=0,
203
- temperature_range=TemperatureRange(min=2700, max=6500),
204
- min_ext_mz_firmware=None,
205
- ),
206
- 11: ProductInfo(
207
- pid=11,
208
- name="LIFX White 800 (High Voltage)",
209
- vendor=1,
210
- capabilities=0,
211
- temperature_range=TemperatureRange(min=2700, max=6500),
212
- min_ext_mz_firmware=None,
213
- ),
214
- 15: ProductInfo(
215
- pid=15,
216
- name="LIFX Color 1000",
217
- vendor=1,
218
- capabilities=ProductCapability.COLOR,
219
- temperature_range=TemperatureRange(min=2500, max=9000),
220
- min_ext_mz_firmware=None,
221
- ),
222
- 18: ProductInfo(
223
- pid=18,
224
- name="LIFX White 900 BR30 (Low Voltage)",
225
- vendor=1,
226
- capabilities=0,
227
- temperature_range=TemperatureRange(min=2500, max=9000),
228
- min_ext_mz_firmware=None,
229
- ),
230
- 19: ProductInfo(
231
- pid=19,
232
- name="LIFX White 900 BR30 (High Voltage)",
233
- vendor=1,
234
- capabilities=0,
235
- temperature_range=TemperatureRange(min=2500, max=9000),
236
- min_ext_mz_firmware=None,
237
- ),
238
- 20: ProductInfo(
239
- pid=20,
240
- name="LIFX Color 1000 BR30",
241
- vendor=1,
242
- capabilities=ProductCapability.COLOR,
243
- temperature_range=TemperatureRange(min=2500, max=9000),
244
- min_ext_mz_firmware=None,
245
- ),
246
- 22: ProductInfo(
247
- pid=22,
248
- name="LIFX Color 1000",
249
- vendor=1,
250
- capabilities=ProductCapability.COLOR,
251
- temperature_range=TemperatureRange(min=2500, max=9000),
252
- min_ext_mz_firmware=None,
253
- ),
254
- 27: ProductInfo(
255
- pid=27,
256
- name="LIFX A19",
257
- vendor=1,
258
- capabilities=ProductCapability.COLOR,
259
- temperature_range=TemperatureRange(min=2500, max=9000),
260
- min_ext_mz_firmware=None,
261
- ),
262
- 28: ProductInfo(
263
- pid=28,
264
- name="LIFX BR30",
265
- vendor=1,
266
- capabilities=ProductCapability.COLOR,
267
- temperature_range=TemperatureRange(min=2500, max=9000),
268
- min_ext_mz_firmware=None,
269
- ),
270
- 29: ProductInfo(
271
- pid=29,
272
- name="LIFX A19 Night Vision",
273
- vendor=1,
274
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
275
- temperature_range=TemperatureRange(min=2500, max=9000),
276
- min_ext_mz_firmware=None,
277
- ),
278
- 30: ProductInfo(
279
- pid=30,
280
- name="LIFX BR30 Night Vision",
281
- vendor=1,
282
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
283
- temperature_range=TemperatureRange(min=2500, max=9000),
284
- min_ext_mz_firmware=None,
285
- ),
286
- 31: ProductInfo(
287
- pid=31,
288
- name="LIFX Z",
289
- vendor=1,
290
- capabilities=ProductCapability.COLOR | ProductCapability.MULTIZONE,
291
- temperature_range=TemperatureRange(min=2500, max=9000),
292
- min_ext_mz_firmware=None,
293
- ),
294
- 32: ProductInfo(
295
- pid=32,
296
- name="LIFX Z",
297
- vendor=1,
298
- capabilities=ProductCapability.COLOR
299
- | ProductCapability.MULTIZONE
300
- | ProductCapability.EXTENDED_MULTIZONE,
301
- temperature_range=TemperatureRange(min=2500, max=9000),
302
- min_ext_mz_firmware=131149,
303
- ),
304
- 36: ProductInfo(
305
- pid=36,
306
- name="LIFX Downlight",
307
- vendor=1,
308
- capabilities=ProductCapability.COLOR,
309
- temperature_range=TemperatureRange(min=2500, max=9000),
310
- min_ext_mz_firmware=None,
311
- ),
312
- 37: ProductInfo(
313
- pid=37,
314
- name="LIFX Downlight",
315
- vendor=1,
316
- capabilities=ProductCapability.COLOR,
317
- temperature_range=TemperatureRange(min=2500, max=9000),
318
- min_ext_mz_firmware=None,
319
- ),
320
- 38: ProductInfo(
321
- pid=38,
322
- name="LIFX Beam",
323
- vendor=1,
324
- capabilities=ProductCapability.COLOR
325
- | ProductCapability.MULTIZONE
326
- | ProductCapability.EXTENDED_MULTIZONE,
327
- temperature_range=TemperatureRange(min=2500, max=9000),
328
- min_ext_mz_firmware=131149,
329
- ),
330
- 39: ProductInfo(
331
- pid=39,
332
- name="LIFX Downlight White to Warm",
333
- vendor=1,
334
- capabilities=0,
335
- temperature_range=TemperatureRange(min=2500, max=9000),
336
- min_ext_mz_firmware=None,
337
- ),
338
- 40: ProductInfo(
339
- pid=40,
340
- name="LIFX Downlight",
341
- vendor=1,
342
- capabilities=ProductCapability.COLOR,
343
- temperature_range=TemperatureRange(min=2500, max=9000),
344
- min_ext_mz_firmware=None,
345
- ),
346
- 43: ProductInfo(
347
- pid=43,
348
- name="LIFX A19",
349
- vendor=1,
350
- capabilities=ProductCapability.COLOR,
351
- temperature_range=TemperatureRange(min=2500, max=9000),
352
- min_ext_mz_firmware=None,
353
- ),
354
- 44: ProductInfo(
355
- pid=44,
356
- name="LIFX BR30",
357
- vendor=1,
358
- capabilities=ProductCapability.COLOR,
359
- temperature_range=TemperatureRange(min=2500, max=9000),
360
- min_ext_mz_firmware=None,
361
- ),
362
- 45: ProductInfo(
363
- pid=45,
364
- name="LIFX A19 Night Vision",
365
- vendor=1,
366
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
367
- temperature_range=TemperatureRange(min=2500, max=9000),
368
- min_ext_mz_firmware=None,
369
- ),
370
- 46: ProductInfo(
371
- pid=46,
372
- name="LIFX BR30 Night Vision",
373
- vendor=1,
374
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
375
- temperature_range=TemperatureRange(min=2500, max=9000),
376
- min_ext_mz_firmware=None,
377
- ),
378
- 49: ProductInfo(
379
- pid=49,
380
- name="LIFX Mini Color",
381
- vendor=1,
382
- capabilities=ProductCapability.COLOR,
383
- temperature_range=TemperatureRange(min=1500, max=9000),
384
- min_ext_mz_firmware=None,
385
- ),
386
- 50: ProductInfo(
387
- pid=50,
388
- name="LIFX Mini White to Warm",
389
- vendor=1,
390
- capabilities=0,
391
- temperature_range=TemperatureRange(min=1500, max=6500),
392
- min_ext_mz_firmware=None,
393
- ),
394
- 51: ProductInfo(
395
- pid=51,
396
- name="LIFX Mini White",
397
- vendor=1,
398
- capabilities=0,
399
- temperature_range=TemperatureRange(min=2700, max=2700),
400
- min_ext_mz_firmware=None,
401
- ),
402
- 52: ProductInfo(
403
- pid=52,
404
- name="LIFX GU10",
405
- vendor=1,
406
- capabilities=ProductCapability.COLOR,
407
- temperature_range=TemperatureRange(min=1500, max=9000),
408
- min_ext_mz_firmware=None,
409
- ),
410
- 53: ProductInfo(
411
- pid=53,
412
- name="LIFX GU10",
413
- vendor=1,
414
- capabilities=ProductCapability.COLOR,
415
- temperature_range=TemperatureRange(min=1500, max=9000),
416
- min_ext_mz_firmware=None,
417
- ),
418
- 55: ProductInfo(
419
- pid=55,
420
- name="LIFX Tile",
421
- vendor=1,
422
- capabilities=ProductCapability.COLOR
423
- | ProductCapability.CHAIN
424
- | ProductCapability.MATRIX,
425
- temperature_range=TemperatureRange(min=2500, max=9000),
426
- min_ext_mz_firmware=None,
427
- ),
428
- 57: ProductInfo(
429
- pid=57,
430
- name="LIFX Candle",
431
- vendor=1,
432
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
433
- temperature_range=TemperatureRange(min=1500, max=9000),
434
- min_ext_mz_firmware=None,
435
- ),
436
- 59: ProductInfo(
437
- pid=59,
438
- name="LIFX Mini Color",
439
- vendor=1,
440
- capabilities=ProductCapability.COLOR,
441
- temperature_range=TemperatureRange(min=1500, max=9000),
442
- min_ext_mz_firmware=None,
443
- ),
444
- 60: ProductInfo(
445
- pid=60,
446
- name="LIFX Mini White to Warm",
447
- vendor=1,
448
- capabilities=0,
449
- temperature_range=TemperatureRange(min=1500, max=6500),
450
- min_ext_mz_firmware=None,
451
- ),
452
- 61: ProductInfo(
453
- pid=61,
454
- name="LIFX Mini White",
455
- vendor=1,
456
- capabilities=0,
457
- temperature_range=TemperatureRange(min=2700, max=2700),
458
- min_ext_mz_firmware=None,
459
- ),
460
- 62: ProductInfo(
461
- pid=62,
462
- name="LIFX A19",
463
- vendor=1,
464
- capabilities=ProductCapability.COLOR,
465
- temperature_range=TemperatureRange(min=1500, max=9000),
466
- min_ext_mz_firmware=None,
467
- ),
468
- 63: ProductInfo(
469
- pid=63,
470
- name="LIFX BR30",
471
- vendor=1,
472
- capabilities=ProductCapability.COLOR,
473
- temperature_range=TemperatureRange(min=1500, max=9000),
474
- min_ext_mz_firmware=None,
475
- ),
476
- 64: ProductInfo(
477
- pid=64,
478
- name="LIFX A19 Night Vision",
479
- vendor=1,
480
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
481
- temperature_range=TemperatureRange(min=1500, max=9000),
482
- min_ext_mz_firmware=None,
483
- ),
484
- 65: ProductInfo(
485
- pid=65,
486
- name="LIFX BR30 Night Vision",
487
- vendor=1,
488
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
489
- temperature_range=TemperatureRange(min=1500, max=9000),
490
- min_ext_mz_firmware=None,
491
- ),
492
- 66: ProductInfo(
493
- pid=66,
494
- name="LIFX Mini White",
495
- vendor=1,
496
- capabilities=0,
497
- temperature_range=TemperatureRange(min=2700, max=2700),
498
- min_ext_mz_firmware=None,
499
- ),
500
- 68: ProductInfo(
501
- pid=68,
502
- name="LIFX Candle",
503
- vendor=1,
504
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
505
- temperature_range=TemperatureRange(min=1500, max=9000),
506
- min_ext_mz_firmware=None,
507
- ),
508
- 81: ProductInfo(
509
- pid=81,
510
- name="LIFX Candle White to Warm",
511
- vendor=1,
512
- capabilities=0,
513
- temperature_range=TemperatureRange(min=2200, max=6500),
514
- min_ext_mz_firmware=None,
515
- ),
516
- 82: ProductInfo(
517
- pid=82,
518
- name="LIFX Filament Clear",
519
- vendor=1,
520
- capabilities=0,
521
- temperature_range=TemperatureRange(min=2100, max=2100),
522
- min_ext_mz_firmware=None,
523
- ),
524
- 85: ProductInfo(
525
- pid=85,
526
- name="LIFX Filament Amber",
527
- vendor=1,
528
- capabilities=0,
529
- temperature_range=TemperatureRange(min=2000, max=2000),
530
- min_ext_mz_firmware=None,
531
- ),
532
- 87: ProductInfo(
533
- pid=87,
534
- name="LIFX Mini White",
535
- vendor=1,
536
- capabilities=0,
537
- temperature_range=TemperatureRange(min=2700, max=2700),
538
- min_ext_mz_firmware=None,
539
- ),
540
- 88: ProductInfo(
541
- pid=88,
542
- name="LIFX Mini White",
543
- vendor=1,
544
- capabilities=0,
545
- temperature_range=TemperatureRange(min=2700, max=2700),
546
- min_ext_mz_firmware=None,
547
- ),
548
- 90: ProductInfo(
549
- pid=90,
550
- name="LIFX Clean",
551
- vendor=1,
552
- capabilities=ProductCapability.COLOR | ProductCapability.HEV,
553
- temperature_range=TemperatureRange(min=1500, max=9000),
554
- min_ext_mz_firmware=None,
555
- ),
556
- 91: ProductInfo(
557
- pid=91,
558
- name="LIFX Color",
559
- vendor=1,
560
- capabilities=ProductCapability.COLOR,
561
- temperature_range=TemperatureRange(min=1500, max=9000),
562
- min_ext_mz_firmware=None,
563
- ),
564
- 92: ProductInfo(
565
- pid=92,
566
- name="LIFX Color",
567
- vendor=1,
568
- capabilities=ProductCapability.COLOR,
569
- temperature_range=TemperatureRange(min=1500, max=9000),
570
- min_ext_mz_firmware=None,
571
- ),
572
- 93: ProductInfo(
573
- pid=93,
574
- name="LIFX A19 US",
575
- vendor=1,
576
- capabilities=ProductCapability.COLOR,
577
- temperature_range=TemperatureRange(min=1500, max=9000),
578
- min_ext_mz_firmware=None,
579
- ),
580
- 94: ProductInfo(
581
- pid=94,
582
- name="LIFX BR30",
583
- vendor=1,
584
- capabilities=ProductCapability.COLOR,
585
- temperature_range=TemperatureRange(min=1500, max=9000),
586
- min_ext_mz_firmware=None,
587
- ),
588
- 96: ProductInfo(
589
- pid=96,
590
- name="LIFX Candle White to Warm",
591
- vendor=1,
592
- capabilities=0,
593
- temperature_range=TemperatureRange(min=2200, max=6500),
594
- min_ext_mz_firmware=None,
595
- ),
596
- 97: ProductInfo(
597
- pid=97,
598
- name="LIFX A19",
599
- vendor=1,
600
- capabilities=ProductCapability.COLOR,
601
- temperature_range=TemperatureRange(min=1500, max=9000),
602
- min_ext_mz_firmware=None,
603
- ),
604
- 98: ProductInfo(
605
- pid=98,
606
- name="LIFX BR30",
607
- vendor=1,
608
- capabilities=ProductCapability.COLOR,
609
- temperature_range=TemperatureRange(min=1500, max=9000),
610
- min_ext_mz_firmware=None,
611
- ),
612
- 99: ProductInfo(
613
- pid=99,
614
- name="LIFX Clean",
615
- vendor=1,
616
- capabilities=ProductCapability.COLOR | ProductCapability.HEV,
617
- temperature_range=TemperatureRange(min=1500, max=9000),
618
- min_ext_mz_firmware=None,
619
- ),
620
- 100: ProductInfo(
621
- pid=100,
622
- name="LIFX Filament Clear",
623
- vendor=1,
624
- capabilities=0,
625
- temperature_range=TemperatureRange(min=2100, max=2100),
626
- min_ext_mz_firmware=None,
627
- ),
628
- 101: ProductInfo(
629
- pid=101,
630
- name="LIFX Filament Amber",
631
- vendor=1,
632
- capabilities=0,
633
- temperature_range=TemperatureRange(min=2000, max=2000),
634
- min_ext_mz_firmware=None,
635
- ),
636
- 109: ProductInfo(
637
- pid=109,
638
- name="LIFX A19 Night Vision",
639
- vendor=1,
640
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
641
- temperature_range=TemperatureRange(min=1500, max=9000),
642
- min_ext_mz_firmware=None,
643
- ),
644
- 110: ProductInfo(
645
- pid=110,
646
- name="LIFX BR30 Night Vision",
647
- vendor=1,
648
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
649
- temperature_range=TemperatureRange(min=1500, max=9000),
650
- min_ext_mz_firmware=None,
651
- ),
652
- 111: ProductInfo(
653
- pid=111,
654
- name="LIFX A19 Night Vision",
655
- vendor=1,
656
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
657
- temperature_range=TemperatureRange(min=1500, max=9000),
658
- min_ext_mz_firmware=None,
659
- ),
660
- 112: ProductInfo(
661
- pid=112,
662
- name="LIFX BR30 Night Vision Intl",
663
- vendor=1,
664
- capabilities=ProductCapability.COLOR | ProductCapability.INFRARED,
665
- temperature_range=TemperatureRange(min=1500, max=9000),
666
- min_ext_mz_firmware=None,
667
- ),
668
- 113: ProductInfo(
669
- pid=113,
670
- name="LIFX Mini WW US",
671
- vendor=1,
672
- capabilities=0,
673
- temperature_range=TemperatureRange(min=1500, max=9000),
674
- min_ext_mz_firmware=None,
675
- ),
676
- 114: ProductInfo(
677
- pid=114,
678
- name="LIFX Mini WW Intl",
679
- vendor=1,
680
- capabilities=0,
681
- temperature_range=TemperatureRange(min=1500, max=9000),
682
- min_ext_mz_firmware=None,
683
- ),
684
- 117: ProductInfo(
685
- pid=117,
686
- name="LIFX Z US",
687
- vendor=1,
688
- capabilities=ProductCapability.COLOR
689
- | ProductCapability.MULTIZONE
690
- | ProductCapability.EXTENDED_MULTIZONE,
691
- temperature_range=TemperatureRange(min=1500, max=9000),
692
- min_ext_mz_firmware=None,
693
- ),
694
- 118: ProductInfo(
695
- pid=118,
696
- name="LIFX Z Intl",
697
- vendor=1,
698
- capabilities=ProductCapability.COLOR
699
- | ProductCapability.MULTIZONE
700
- | ProductCapability.EXTENDED_MULTIZONE,
701
- temperature_range=TemperatureRange(min=1500, max=9000),
702
- min_ext_mz_firmware=None,
703
- ),
704
- 119: ProductInfo(
705
- pid=119,
706
- name="LIFX Beam US",
707
- vendor=1,
708
- capabilities=ProductCapability.COLOR
709
- | ProductCapability.MULTIZONE
710
- | ProductCapability.EXTENDED_MULTIZONE,
711
- temperature_range=TemperatureRange(min=1500, max=9000),
712
- min_ext_mz_firmware=None,
713
- ),
714
- 120: ProductInfo(
715
- pid=120,
716
- name="LIFX Beam Intl",
717
- vendor=1,
718
- capabilities=ProductCapability.COLOR
719
- | ProductCapability.MULTIZONE
720
- | ProductCapability.EXTENDED_MULTIZONE,
721
- temperature_range=TemperatureRange(min=1500, max=9000),
722
- min_ext_mz_firmware=None,
723
- ),
724
- 121: ProductInfo(
725
- pid=121,
726
- name="LIFX Downlight Intl",
727
- vendor=1,
728
- capabilities=ProductCapability.COLOR,
729
- temperature_range=TemperatureRange(min=1500, max=9000),
730
- min_ext_mz_firmware=None,
731
- ),
732
- 122: ProductInfo(
733
- pid=122,
734
- name="LIFX Downlight US",
735
- vendor=1,
736
- capabilities=ProductCapability.COLOR,
737
- temperature_range=TemperatureRange(min=1500, max=9000),
738
- min_ext_mz_firmware=None,
739
- ),
740
- 123: ProductInfo(
741
- pid=123,
742
- name="LIFX Color US",
743
- vendor=1,
744
- capabilities=ProductCapability.COLOR,
745
- temperature_range=TemperatureRange(min=1500, max=9000),
746
- min_ext_mz_firmware=None,
747
- ),
748
- 124: ProductInfo(
749
- pid=124,
750
- name="LIFX Colour Intl",
751
- vendor=1,
752
- capabilities=ProductCapability.COLOR,
753
- temperature_range=TemperatureRange(min=1500, max=9000),
754
- min_ext_mz_firmware=None,
755
- ),
756
- 125: ProductInfo(
757
- pid=125,
758
- name="LIFX White to Warm US",
759
- vendor=1,
760
- capabilities=0,
761
- temperature_range=TemperatureRange(min=1500, max=9000),
762
- min_ext_mz_firmware=None,
763
- ),
764
- 126: ProductInfo(
765
- pid=126,
766
- name="LIFX White to Warm Intl",
767
- vendor=1,
768
- capabilities=0,
769
- temperature_range=TemperatureRange(min=1500, max=9000),
770
- min_ext_mz_firmware=None,
771
- ),
772
- 127: ProductInfo(
773
- pid=127,
774
- name="LIFX White US",
775
- vendor=1,
776
- capabilities=0,
777
- temperature_range=TemperatureRange(min=2700, max=2700),
778
- min_ext_mz_firmware=None,
779
- ),
780
- 128: ProductInfo(
781
- pid=128,
782
- name="LIFX White Intl",
783
- vendor=1,
784
- capabilities=0,
785
- temperature_range=TemperatureRange(min=2700, max=2700),
786
- min_ext_mz_firmware=None,
787
- ),
788
- 129: ProductInfo(
789
- pid=129,
790
- name="LIFX Color US",
791
- vendor=1,
792
- capabilities=ProductCapability.COLOR,
793
- temperature_range=TemperatureRange(min=1500, max=9000),
794
- min_ext_mz_firmware=None,
795
- ),
796
- 130: ProductInfo(
797
- pid=130,
798
- name="LIFX Colour Intl",
799
- vendor=1,
800
- capabilities=ProductCapability.COLOR,
801
- temperature_range=TemperatureRange(min=1500, max=9000),
802
- min_ext_mz_firmware=None,
803
- ),
804
- 131: ProductInfo(
805
- pid=131,
806
- name="LIFX White To Warm US",
807
- vendor=1,
808
- capabilities=0,
809
- temperature_range=TemperatureRange(min=1500, max=9000),
810
- min_ext_mz_firmware=None,
811
- ),
812
- 132: ProductInfo(
813
- pid=132,
814
- name="LIFX White To Warm Intl",
815
- vendor=1,
816
- capabilities=0,
817
- temperature_range=TemperatureRange(min=1500, max=9000),
818
- min_ext_mz_firmware=None,
819
- ),
820
- 133: ProductInfo(
821
- pid=133,
822
- name="LIFX White US",
823
- vendor=1,
824
- capabilities=0,
825
- temperature_range=TemperatureRange(min=2700, max=2700),
826
- min_ext_mz_firmware=None,
827
- ),
828
- 134: ProductInfo(
829
- pid=134,
830
- name="LIFX White Intl",
831
- vendor=1,
832
- capabilities=0,
833
- temperature_range=TemperatureRange(min=2700, max=2700),
834
- min_ext_mz_firmware=None,
835
- ),
836
- 135: ProductInfo(
837
- pid=135,
838
- name="LIFX GU10 Color US",
839
- vendor=1,
840
- capabilities=ProductCapability.COLOR,
841
- temperature_range=TemperatureRange(min=1500, max=9000),
842
- min_ext_mz_firmware=None,
843
- ),
844
- 136: ProductInfo(
845
- pid=136,
846
- name="LIFX GU10 Colour Intl",
847
- vendor=1,
848
- capabilities=ProductCapability.COLOR,
849
- temperature_range=TemperatureRange(min=1500, max=9000),
850
- min_ext_mz_firmware=None,
851
- ),
852
- 137: ProductInfo(
853
- pid=137,
854
- name="LIFX Candle Color US",
855
- vendor=1,
856
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
857
- temperature_range=TemperatureRange(min=1500, max=9000),
858
- min_ext_mz_firmware=None,
859
- ),
860
- 138: ProductInfo(
861
- pid=138,
862
- name="LIFX Candle Colour Intl",
863
- vendor=1,
864
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
865
- temperature_range=TemperatureRange(min=1500, max=9000),
866
- min_ext_mz_firmware=None,
867
- ),
868
- 141: ProductInfo(
869
- pid=141,
870
- name="LIFX Neon US",
871
- vendor=1,
872
- capabilities=ProductCapability.COLOR
873
- | ProductCapability.MULTIZONE
874
- | ProductCapability.EXTENDED_MULTIZONE,
875
- temperature_range=TemperatureRange(min=1500, max=9000),
876
- min_ext_mz_firmware=None,
877
- ),
878
- 142: ProductInfo(
879
- pid=142,
880
- name="LIFX Neon Intl",
881
- vendor=1,
882
- capabilities=ProductCapability.COLOR
883
- | ProductCapability.MULTIZONE
884
- | ProductCapability.EXTENDED_MULTIZONE,
885
- temperature_range=TemperatureRange(min=1500, max=9000),
886
- min_ext_mz_firmware=None,
887
- ),
888
- 143: ProductInfo(
889
- pid=143,
890
- name="LIFX String US",
891
- vendor=1,
892
- capabilities=ProductCapability.COLOR
893
- | ProductCapability.MULTIZONE
894
- | ProductCapability.EXTENDED_MULTIZONE,
895
- temperature_range=TemperatureRange(min=1500, max=9000),
896
- min_ext_mz_firmware=None,
897
- ),
898
- 144: ProductInfo(
899
- pid=144,
900
- name="LIFX String Intl",
901
- vendor=1,
902
- capabilities=ProductCapability.COLOR
903
- | ProductCapability.MULTIZONE
904
- | ProductCapability.EXTENDED_MULTIZONE,
905
- temperature_range=TemperatureRange(min=1500, max=9000),
906
- min_ext_mz_firmware=None,
907
- ),
908
- 161: ProductInfo(
909
- pid=161,
910
- name="LIFX Outdoor Neon US",
911
- vendor=1,
912
- capabilities=ProductCapability.COLOR
913
- | ProductCapability.MULTIZONE
914
- | ProductCapability.EXTENDED_MULTIZONE,
915
- temperature_range=TemperatureRange(min=1500, max=9000),
916
- min_ext_mz_firmware=None,
917
- ),
918
- 162: ProductInfo(
919
- pid=162,
920
- name="LIFX Outdoor Neon Intl",
921
- vendor=1,
922
- capabilities=ProductCapability.COLOR
923
- | ProductCapability.MULTIZONE
924
- | ProductCapability.EXTENDED_MULTIZONE,
925
- temperature_range=TemperatureRange(min=1500, max=9000),
926
- min_ext_mz_firmware=None,
927
- ),
928
- 163: ProductInfo(
929
- pid=163,
930
- name="LIFX A19 US",
931
- vendor=1,
932
- capabilities=ProductCapability.COLOR,
933
- temperature_range=TemperatureRange(min=1500, max=9000),
934
- min_ext_mz_firmware=None,
935
- ),
936
- 164: ProductInfo(
937
- pid=164,
938
- name="LIFX BR30 US",
939
- vendor=1,
940
- capabilities=ProductCapability.COLOR,
941
- temperature_range=TemperatureRange(min=1500, max=9000),
942
- min_ext_mz_firmware=None,
943
- ),
944
- 165: ProductInfo(
945
- pid=165,
946
- name="LIFX A19 Intl",
947
- vendor=1,
948
- capabilities=ProductCapability.COLOR,
949
- temperature_range=TemperatureRange(min=1500, max=9000),
950
- min_ext_mz_firmware=None,
951
- ),
952
- 166: ProductInfo(
953
- pid=166,
954
- name="LIFX BR30 Intl",
955
- vendor=1,
956
- capabilities=ProductCapability.COLOR,
957
- temperature_range=TemperatureRange(min=1500, max=9000),
958
- min_ext_mz_firmware=None,
959
- ),
960
- 167: ProductInfo(
961
- pid=167,
962
- name="LIFX Downlight",
963
- vendor=1,
964
- capabilities=ProductCapability.COLOR,
965
- temperature_range=TemperatureRange(min=1500, max=9000),
966
- min_ext_mz_firmware=None,
967
- ),
968
- 168: ProductInfo(
969
- pid=168,
970
- name="LIFX Downlight",
971
- vendor=1,
972
- capabilities=ProductCapability.COLOR,
973
- temperature_range=TemperatureRange(min=1500, max=9000),
974
- min_ext_mz_firmware=None,
975
- ),
976
- 169: ProductInfo(
977
- pid=169,
978
- name="LIFX A21 1600lm US",
979
- vendor=1,
980
- capabilities=ProductCapability.COLOR,
981
- temperature_range=TemperatureRange(min=1500, max=9000),
982
- min_ext_mz_firmware=None,
983
- ),
984
- 170: ProductInfo(
985
- pid=170,
986
- name="LIFX A21 1600lm Intl",
987
- vendor=1,
988
- capabilities=ProductCapability.COLOR,
989
- temperature_range=TemperatureRange(min=1500, max=9000),
990
- min_ext_mz_firmware=None,
991
- ),
992
- 171: ProductInfo(
993
- pid=171,
994
- name="LIFX Round Spot US",
995
- vendor=1,
996
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
997
- temperature_range=TemperatureRange(min=1500, max=9000),
998
- min_ext_mz_firmware=None,
999
- ),
1000
- 173: ProductInfo(
1001
- pid=173,
1002
- name="LIFX Round Path US",
1003
- vendor=1,
1004
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1005
- temperature_range=TemperatureRange(min=1500, max=9000),
1006
- min_ext_mz_firmware=None,
1007
- ),
1008
- 174: ProductInfo(
1009
- pid=174,
1010
- name="LIFX Square Path US",
1011
- vendor=1,
1012
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1013
- temperature_range=TemperatureRange(min=1500, max=9000),
1014
- min_ext_mz_firmware=None,
1015
- ),
1016
- 175: ProductInfo(
1017
- pid=175,
1018
- name="LIFX PAR38 US",
1019
- vendor=1,
1020
- capabilities=ProductCapability.COLOR,
1021
- temperature_range=TemperatureRange(min=1500, max=9000),
1022
- min_ext_mz_firmware=None,
1023
- ),
1024
- 176: ProductInfo(
1025
- pid=176,
1026
- name="LIFX Ceiling US",
1027
- vendor=1,
1028
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1029
- temperature_range=TemperatureRange(min=1500, max=9000),
1030
- min_ext_mz_firmware=None,
1031
- ),
1032
- 177: ProductInfo(
1033
- pid=177,
1034
- name="LIFX Ceiling Intl",
1035
- vendor=1,
1036
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1037
- temperature_range=TemperatureRange(min=1500, max=9000),
1038
- min_ext_mz_firmware=None,
1039
- ),
1040
- 178: ProductInfo(
1041
- pid=178,
1042
- name="LIFX Downlight US",
1043
- vendor=1,
1044
- capabilities=ProductCapability.COLOR,
1045
- temperature_range=TemperatureRange(min=1500, max=9000),
1046
- min_ext_mz_firmware=None,
1047
- ),
1048
- 179: ProductInfo(
1049
- pid=179,
1050
- name="LIFX Downlight US",
1051
- vendor=1,
1052
- capabilities=ProductCapability.COLOR,
1053
- temperature_range=TemperatureRange(min=1500, max=9000),
1054
- min_ext_mz_firmware=None,
1055
- ),
1056
- 180: ProductInfo(
1057
- pid=180,
1058
- name="LIFX Downlight US",
1059
- vendor=1,
1060
- capabilities=ProductCapability.COLOR,
1061
- temperature_range=TemperatureRange(min=1500, max=9000),
1062
- min_ext_mz_firmware=None,
1063
- ),
1064
- 181: ProductInfo(
1065
- pid=181,
1066
- name="LIFX Color US",
1067
- vendor=1,
1068
- capabilities=ProductCapability.COLOR,
1069
- temperature_range=TemperatureRange(min=1500, max=9000),
1070
- min_ext_mz_firmware=None,
1071
- ),
1072
- 182: ProductInfo(
1073
- pid=182,
1074
- name="LIFX Colour Intl",
1075
- vendor=1,
1076
- capabilities=ProductCapability.COLOR,
1077
- temperature_range=TemperatureRange(min=1500, max=9000),
1078
- min_ext_mz_firmware=None,
1079
- ),
1080
- 185: ProductInfo(
1081
- pid=185,
1082
- name="LIFX Candle Color US",
1083
- vendor=1,
1084
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1085
- temperature_range=TemperatureRange(min=1500, max=9000),
1086
- min_ext_mz_firmware=None,
1087
- ),
1088
- 186: ProductInfo(
1089
- pid=186,
1090
- name="LIFX Candle Colour Intl",
1091
- vendor=1,
1092
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1093
- temperature_range=TemperatureRange(min=1500, max=9000),
1094
- min_ext_mz_firmware=None,
1095
- ),
1096
- 187: ProductInfo(
1097
- pid=187,
1098
- name="LIFX Candle Color US",
1099
- vendor=1,
1100
- capabilities=ProductCapability.COLOR,
1101
- temperature_range=TemperatureRange(min=1500, max=9000),
1102
- min_ext_mz_firmware=None,
1103
- ),
1104
- 188: ProductInfo(
1105
- pid=188,
1106
- name="LIFX Candle Colour Intl",
1107
- vendor=1,
1108
- capabilities=ProductCapability.COLOR,
1109
- temperature_range=TemperatureRange(min=1500, max=9000),
1110
- min_ext_mz_firmware=None,
1111
- ),
1112
- 201: ProductInfo(
1113
- pid=201,
1114
- name='LIFX Ceiling 13x26" US',
1115
- vendor=1,
1116
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1117
- temperature_range=TemperatureRange(min=1500, max=9000),
1118
- min_ext_mz_firmware=None,
1119
- ),
1120
- 202: ProductInfo(
1121
- pid=202,
1122
- name='LIFX Ceiling 13x26" Intl',
1123
- vendor=1,
1124
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1125
- temperature_range=TemperatureRange(min=1500, max=9000),
1126
- min_ext_mz_firmware=None,
1127
- ),
1128
- 203: ProductInfo(
1129
- pid=203,
1130
- name="LIFX String US",
1131
- vendor=1,
1132
- capabilities=ProductCapability.COLOR
1133
- | ProductCapability.MULTIZONE
1134
- | ProductCapability.EXTENDED_MULTIZONE,
1135
- temperature_range=TemperatureRange(min=1500, max=9000),
1136
- min_ext_mz_firmware=None,
1137
- ),
1138
- 204: ProductInfo(
1139
- pid=204,
1140
- name="LIFX String Intl",
1141
- vendor=1,
1142
- capabilities=ProductCapability.COLOR
1143
- | ProductCapability.MULTIZONE
1144
- | ProductCapability.EXTENDED_MULTIZONE,
1145
- temperature_range=TemperatureRange(min=1500, max=9000),
1146
- min_ext_mz_firmware=None,
1147
- ),
1148
- 205: ProductInfo(
1149
- pid=205,
1150
- name="LIFX Indoor Neon US",
1151
- vendor=1,
1152
- capabilities=ProductCapability.COLOR
1153
- | ProductCapability.MULTIZONE
1154
- | ProductCapability.EXTENDED_MULTIZONE,
1155
- temperature_range=TemperatureRange(min=1500, max=9000),
1156
- min_ext_mz_firmware=None,
1157
- ),
1158
- 206: ProductInfo(
1159
- pid=206,
1160
- name="LIFX Indoor Neon Intl",
1161
- vendor=1,
1162
- capabilities=ProductCapability.COLOR
1163
- | ProductCapability.MULTIZONE
1164
- | ProductCapability.EXTENDED_MULTIZONE,
1165
- temperature_range=TemperatureRange(min=1500, max=9000),
1166
- min_ext_mz_firmware=None,
1167
- ),
1168
- 213: ProductInfo(
1169
- pid=213,
1170
- name="LIFX Permanent Outdoor US",
1171
- vendor=1,
1172
- capabilities=ProductCapability.COLOR
1173
- | ProductCapability.MULTIZONE
1174
- | ProductCapability.EXTENDED_MULTIZONE,
1175
- temperature_range=TemperatureRange(min=1500, max=9000),
1176
- min_ext_mz_firmware=None,
1177
- ),
1178
- 214: ProductInfo(
1179
- pid=214,
1180
- name="LIFX Permanent Outdoor Intl",
1181
- vendor=1,
1182
- capabilities=ProductCapability.COLOR
1183
- | ProductCapability.MULTIZONE
1184
- | ProductCapability.EXTENDED_MULTIZONE,
1185
- temperature_range=TemperatureRange(min=1500, max=9000),
1186
- min_ext_mz_firmware=None,
1187
- ),
1188
- 215: ProductInfo(
1189
- pid=215,
1190
- name="LIFX Candle Color US",
1191
- vendor=1,
1192
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1193
- temperature_range=TemperatureRange(min=1500, max=9000),
1194
- min_ext_mz_firmware=None,
1195
- ),
1196
- 216: ProductInfo(
1197
- pid=216,
1198
- name="LIFX Candle Colour Intl",
1199
- vendor=1,
1200
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1201
- temperature_range=TemperatureRange(min=1500, max=9000),
1202
- min_ext_mz_firmware=None,
1203
- ),
1204
- 217: ProductInfo(
1205
- pid=217,
1206
- name="LIFX Tube US",
1207
- vendor=1,
1208
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1209
- temperature_range=TemperatureRange(min=1500, max=9000),
1210
- min_ext_mz_firmware=None,
1211
- ),
1212
- 218: ProductInfo(
1213
- pid=218,
1214
- name="LIFX Tube Intl",
1215
- vendor=1,
1216
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1217
- temperature_range=TemperatureRange(min=1500, max=9000),
1218
- min_ext_mz_firmware=None,
1219
- ),
1220
- 219: ProductInfo(
1221
- pid=219,
1222
- name="LIFX Luna US",
1223
- vendor=1,
1224
- capabilities=ProductCapability.COLOR
1225
- | ProductCapability.MATRIX
1226
- | ProductCapability.BUTTONS,
1227
- temperature_range=TemperatureRange(min=1500, max=9000),
1228
- min_ext_mz_firmware=None,
1229
- ),
1230
- 220: ProductInfo(
1231
- pid=220,
1232
- name="LIFX Luna Intl",
1233
- vendor=1,
1234
- capabilities=ProductCapability.COLOR
1235
- | ProductCapability.MATRIX
1236
- | ProductCapability.BUTTONS,
1237
- temperature_range=TemperatureRange(min=1500, max=9000),
1238
- min_ext_mz_firmware=None,
1239
- ),
1240
- 221: ProductInfo(
1241
- pid=221,
1242
- name="LIFX Round Spot Intl",
1243
- vendor=1,
1244
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1245
- temperature_range=TemperatureRange(min=1500, max=9000),
1246
- min_ext_mz_firmware=None,
1247
- ),
1248
- 222: ProductInfo(
1249
- pid=222,
1250
- name="LIFX Round Path Intl",
1251
- vendor=1,
1252
- capabilities=ProductCapability.COLOR | ProductCapability.MATRIX,
1253
- temperature_range=TemperatureRange(min=1500, max=9000),
1254
- min_ext_mz_firmware=None,
1255
- ),
1256
- 223: ProductInfo(
1257
- pid=223,
1258
- name="LIFX Downlight US",
1259
- vendor=1,
1260
- capabilities=ProductCapability.COLOR,
1261
- temperature_range=TemperatureRange(min=1500, max=9000),
1262
- min_ext_mz_firmware=None,
1263
- ),
1264
- 224: ProductInfo(
1265
- pid=224,
1266
- name="LIFX Downlight Intl",
1267
- vendor=1,
1268
- capabilities=ProductCapability.COLOR,
1269
- temperature_range=TemperatureRange(min=1500, max=9000),
1270
- min_ext_mz_firmware=None,
1271
- ),
1272
- 225: ProductInfo(
1273
- pid=225,
1274
- name="LIFX PAR38 INTL",
1275
- vendor=1,
1276
- capabilities=ProductCapability.COLOR,
1277
- temperature_range=TemperatureRange(min=1500, max=9000),
1278
- min_ext_mz_firmware=None,
1279
- ),
1280
- }
1281
-
1282
-
1283
- class ProductRegistry:
1284
- """Registry of LIFX products and their capabilities."""
1285
-
1286
- def __init__(self) -> None:
1287
- """Initialize product registry with pre-generated data."""
1288
- self._products = PRODUCTS.copy() # Copy to allow test overrides
1289
- self._loaded = True # Always loaded in generated registry
1290
-
1291
- def load_from_dict(self, data: dict | list) -> None:
1292
- """Load products from parsed JSON data (for testing).
1293
-
1294
- Args:
1295
- data: Parsed products.json dictionary or array
1296
- """
1297
- from typing import Any
1298
-
1299
- # Clear existing products
1300
- self._products.clear()
1301
-
1302
- # Handle both array and object formats
1303
- all_vendors = []
1304
- if isinstance(data, list):
1305
- all_vendors = data
1306
- else:
1307
- all_vendors = [data]
1308
-
1309
- # Process each vendor
1310
- for vendor_data in all_vendors:
1311
- vendor_id = vendor_data.get("vid", 1)
1312
- defaults = vendor_data.get("defaults", {})
1313
- default_features = defaults.get("features", {})
1314
-
1315
- # Parse each product
1316
- for product in vendor_data.get("products", []):
1317
- pid = product["pid"]
1318
- name = product["name"]
1319
-
1320
- # Merge features with defaults
1321
- prod_features = product.get("features", {})
1322
- features: dict[str, Any] = {**default_features, **prod_features}
1323
-
1324
- # Skip switch products (devices with relays) - these are not lights
1325
- if features.get("relays"):
1326
- continue
1327
-
1328
- # Build capabilities bitfield
1329
- capabilities = 0
1330
- if features.get("color"):
1331
- capabilities |= ProductCapability.COLOR
1332
- if features.get("infrared"):
1333
- capabilities |= ProductCapability.INFRARED
1334
- if features.get("multizone"):
1335
- capabilities |= ProductCapability.MULTIZONE
1336
- if features.get("chain"):
1337
- capabilities |= ProductCapability.CHAIN
1338
- if features.get("matrix"):
1339
- capabilities |= ProductCapability.MATRIX
1340
- if features.get("relays"):
1341
- capabilities |= ProductCapability.RELAYS
1342
- if features.get("buttons"):
1343
- capabilities |= ProductCapability.BUTTONS
1344
- if features.get("hev"):
1345
- capabilities |= ProductCapability.HEV
1346
-
1347
- # Check for extended multizone capability
1348
- min_ext_mz_firmware = None
1349
-
1350
- # First check if it's a native feature (no firmware requirement)
1351
- if features.get("extended_multizone"):
1352
- capabilities |= ProductCapability.EXTENDED_MULTIZONE
1353
- else:
1354
- # Check if it's available as an upgrade (requires minimum firmware)
1355
- for upgrade in product.get("upgrades", []):
1356
- if upgrade.get("features", {}).get("extended_multizone"):
1357
- capabilities |= ProductCapability.EXTENDED_MULTIZONE
1358
- # Parse firmware version (major.minor format)
1359
- major = upgrade.get("major", 0)
1360
- minor = upgrade.get("minor", 0)
1361
- min_ext_mz_firmware = (major << 16) | minor
1362
- break
1363
-
1364
- # Parse temperature range
1365
- temp_range = None
1366
- if "temperature_range" in features:
1367
- temp_list = features["temperature_range"]
1368
- if len(temp_list) >= 2:
1369
- temp_range = TemperatureRange(
1370
- min=temp_list[0], max=temp_list[1]
1371
- )
1372
-
1373
- product_info = ProductInfo(
1374
- pid=pid,
1375
- name=name,
1376
- vendor=vendor_id,
1377
- capabilities=capabilities,
1378
- temperature_range=temp_range,
1379
- min_ext_mz_firmware=min_ext_mz_firmware,
1380
- )
1381
-
1382
- self._products[pid] = product_info
1383
-
1384
- self._loaded = True
1385
-
1386
- @property
1387
- def is_loaded(self) -> bool:
1388
- """Check if registry has been loaded."""
1389
- return self._loaded
1390
-
1391
- def get_product(self, pid: int) -> ProductInfo | None:
1392
- """Get product info by product ID.
1393
-
1394
- Args:
1395
- pid: Product ID
1396
-
1397
- Returns:
1398
- ProductInfo if found, None otherwise
1399
- """
1400
- return self._products.get(pid)
1401
-
1402
- def get_device_class_name(
1403
- self, pid: int, firmware_version: int | None = None
1404
- ) -> str:
1405
- """Get appropriate device class name for a product.
1406
-
1407
- Args:
1408
- pid: Product ID
1409
- firmware_version: Firmware version (optional)
1410
-
1411
- Returns:
1412
- Device class name: "TileDevice", "MultiZoneLight", "HevLight",
1413
- "InfraredLight", "Light", or "Device"
1414
- """
1415
- product = self.get_product(pid)
1416
- if product is None:
1417
- # Unknown product - default to Light if we don't know
1418
- return "Light"
1419
-
1420
- # Matrix devices (Tiles, Candles) → TileDevice
1421
- if product.has_matrix:
1422
- return "TileDevice"
1423
-
1424
- # MultiZone devices (Strips, Beams) → MultiZoneLight
1425
- if product.has_multizone:
1426
- return "MultiZoneLight"
1427
-
1428
- # HEV lights → HevLight
1429
- if product.has_hev:
1430
- return "HevLight"
1431
-
1432
- # Infrared lights → InfraredLight
1433
- if product.has_infrared:
1434
- return "InfraredLight"
1435
-
1436
- # Color lights → Light
1437
- if product.has_color:
1438
- return "Light"
1439
-
1440
- # Devices with relays (switches/relays) → Device
1441
- if product.has_relays:
1442
- return "Device"
1443
-
1444
- # Devices with buttons but no color (switches) → Device
1445
- if product.has_buttons:
1446
- return "Device"
1447
-
1448
- # Everything else (basic lights, white-to-warm lights) → Light
1449
- # These have no special capabilities but still support Light protocol
1450
- return "Light"
1451
-
1452
- def __len__(self) -> int:
1453
- """Get number of products in registry."""
1454
- return len(self._products)
1455
-
1456
- def __contains__(self, pid: int) -> bool:
1457
- """Check if product ID exists in registry."""
1458
- return pid in self._products
1459
-
1460
-
1461
- # Global registry instance
1462
- _registry = ProductRegistry()
1463
-
1464
-
1465
- def get_registry() -> ProductRegistry:
1466
- """Get the global product registry.
1467
-
1468
- Returns:
1469
- Global ProductRegistry instance
1470
- """
1471
- return _registry
1472
-
1473
-
1474
- def get_product(pid: int) -> ProductInfo | None:
1475
- """Get product info by product ID.
1476
-
1477
- Args:
1478
- pid: Product ID
1479
-
1480
- Returns:
1481
- ProductInfo if found, None otherwise
1482
- """
1483
- return _registry.get_product(pid)
1484
-
1485
-
1486
- def get_device_class_name(pid: int, firmware_version: int | None = None) -> str:
1487
- """Get appropriate device class name for a product.
1488
-
1489
- Args:
1490
- pid: Product ID
1491
- firmware_version: Firmware version (optional)
1492
-
1493
- Returns:
1494
- Device class name: "TileDevice", "MultiZoneLight", "Light", or "Device"
1495
- """
1496
- return _registry.get_device_class_name(pid, firmware_version)