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