Factory Functions¶
Factory functions provide the easiest way to create emulated LIFX devices with sensible defaults.
Overview¶
All factory functions return an EmulatedLifxDevice instance configured for a specific product type. They automatically load product-specific defaults (like zone counts and tile dimensions) from the product registry.
Device factory for creating emulated LIFX devices.
This package provides a clean, testable API for creating LIFX devices using: - Builder pattern for flexible device construction - Separate services for serial generation, color config, firmware config - Product registry integration for accurate device specifications
| FUNCTION | DESCRIPTION |
|---|---|
create_color_light |
Create a regular color light (LIFX Color). |
create_color_temperature_light |
Create a color temperature light (LIFX Mini White to Warm). |
create_infrared_light |
Create an infrared-enabled light (LIFX A19 Night Vision). |
create_hev_light |
Create an HEV-enabled light (LIFX Clean). |
create_multizone_light |
Create a multizone light (LIFX Beam) |
create_tile_device |
Create a tile device (LIFX Tile) |
create_device |
Create a device for any LIFX product using the product registry. |
Functions¶
create_color_light
¶
create_color_light(
serial: str | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create a regular color light (LIFX Color).
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial (auto-generated if not provided)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager for testing
TYPE:
|
advertised_services
|
Optional list of (service_id, port) tuples emitted as one StateService reply each, in order, in response to GetService. Defaults to a single UDP reply on the device's port. |
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EmulatedLifxDevice
|
EmulatedLifxDevice configured as a LIFX Color light |
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_color_temperature_light
¶
create_color_temperature_light(
serial: str | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create a color temperature light (LIFX Mini White to Warm).
Variable color temperature, no RGB.
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial (auto-generated if not provided)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager for testing
TYPE:
|
advertised_services
|
Optional list of (service_id, port) tuples emitted as one StateService reply each, in order, in response to GetService. Defaults to a single UDP reply on the device's port. |
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EmulatedLifxDevice
|
EmulatedLifxDevice configured as a LIFX Mini White to Warm light |
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_infrared_light
¶
create_infrared_light(
serial: str | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create an infrared-enabled light (LIFX A19 Night Vision).
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial (auto-generated if not provided)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager for testing
TYPE:
|
advertised_services
|
Optional list of (service_id, port) tuples emitted as one StateService reply each, in order, in response to GetService. Defaults to a single UDP reply on the device's port. |
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EmulatedLifxDevice
|
EmulatedLifxDevice configured as a LIFX A19 Night Vision light |
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_hev_light
¶
create_hev_light(
serial: str | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create an HEV-enabled light (LIFX Clean).
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial (auto-generated if not provided)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager for testing
TYPE:
|
advertised_services
|
Optional list of (service_id, port) tuples emitted as one StateService reply each, in order, in response to GetService. Defaults to a single UDP reply on the device's port. |
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EmulatedLifxDevice
|
EmulatedLifxDevice configured as a LIFX Clean light |
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_multizone_light
¶
create_multizone_light(
serial: str | None = None,
zone_count: int | None = None,
extended_multizone: bool = True,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create a multizone light (LIFX Beam)
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial
TYPE:
|
zone_count
|
Optional zone count (uses product default if not specified)
TYPE:
|
extended_multizone
|
enables support for extended multizone requests
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager
TYPE:
|
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_tile_device
¶
create_tile_device(
serial: str | None = None,
tile_count: int | None = None,
tile_width: int | None = None,
tile_height: int | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create a tile device (LIFX Tile)
| PARAMETER | DESCRIPTION |
|---|---|
serial
|
Optional serial
TYPE:
|
tile_count
|
Optional tile count (uses product default)
TYPE:
|
tile_width
|
Optional tile width in zones (uses product default)
TYPE:
|
tile_height
|
Optional tile height in zones (uses product default)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor) |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager
TYPE:
|
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. LIFX Tile (product 55) has a terminal firmware ceiling of 3.50, below the Thread floor of 4.200, so connectivity="thread" always raises ValueError for this factory.
TYPE:
|
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
create_device
¶
create_device(
product_id: int,
serial: str | None = None,
zone_count: int | None = None,
extended_multizone: bool | None = None,
tile_count: int | None = None,
tile_width: int | None = None,
tile_height: int | None = None,
firmware_version: tuple[int, int] | None = None,
storage: DevicePersistenceAsyncFile | None = None,
scenario_manager: HierarchicalScenarioManager | None = None,
advertised_services: list[tuple[int, int]] | None = None,
connectivity: Connectivity | str | None = None,
) -> EmulatedLifxDevice
Create a device for any LIFX product using the product registry.
This function uses the DeviceBuilder pattern to construct devices with clean separation of concerns and testable components.
| PARAMETER | DESCRIPTION |
|---|---|
product_id
|
Product ID from the LIFX product registry
TYPE:
|
serial
|
Optional serial (auto-generated if not provided)
TYPE:
|
zone_count
|
Number of zones for multizone devices (auto-determined)
TYPE:
|
extended_multizone
|
Enable extended multizone requests
TYPE:
|
tile_count
|
Number of tiles for matrix devices (default: 5)
TYPE:
|
tile_width
|
Width of each tile in zones (default: 8)
TYPE:
|
tile_height
|
Height of each tile in zones (default: 8)
TYPE:
|
firmware_version
|
Optional firmware version tuple (major, minor). If not specified, uses 3.70 for extended_multizone or 2.60 otherwise |
storage
|
Optional storage for persistence
TYPE:
|
scenario_manager
|
Optional scenario manager for testing
TYPE:
|
advertised_services
|
Optional list of (service_id, port) tuples emitted as one StateService reply each, in order, in response to GetService. service_id is a raw uint8 (0-255) and may be outside the DeviceService enum. Defaults to a single UDP reply on the device's port. |
connectivity
|
Optional connectivity ("wifi", "thread", or a Connectivity member). None means unspecified and resolves to WiFi. An explicit string that is not "wifi" or "thread" raises ValueError.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EmulatedLifxDevice
|
EmulatedLifxDevice configured for the specified product |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If product_id is not found in registry |
Examples:
>>> # Create LIFX A19 (PID 27)
>>> device = create_device(27)
>>> # Create LIFX Z strip (PID 32) with 24 zones
>>> strip = create_device(32, zone_count=24)
>>> # Create LIFX Tile (PID 55) with 10 tiles
>>> tiles = create_device(55, tile_count=10)
Source code in packages/lifx-emulator-core/src/lifx_emulator/factories/factory.py
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 | |
Usage Examples¶
Color Light¶
Create a standard RGB color light (LIFX A19):
from lifx_emulator import create_color_light
# Auto-generated serial
device = create_color_light()
# Custom serial
device = create_color_light("d073d5000001")
# Access state
print(f"Label: {device.state.label}")
print(f"Product: {device.state.product}") # 27 (LIFX A19)
print(f"Has color: {device.state.has_color}") # True
Color Temperature Light¶
Create a white light with variable color temperature:
from lifx_emulator import create_color_temperature_light
device = create_color_temperature_light("d073d5000001")
print(f"Has color: {device.state.has_color}") # False
print(f"Product: {device.state.product}") # 50 (LIFX Mini White to Warm)
Infrared Light¶
Create a light with infrared capability:
from lifx_emulator import create_infrared_light
device = create_infrared_light("d073d5000002")
print(f"Has infrared: {device.state.has_infrared}") # True
print(f"Product: {device.state.product}") # 29 (LIFX A19 Night Vision)
print(f"IR brightness: {device.state.infrared_brightness}") # 16384 (25%)
HEV Light¶
Create a light with HEV cleaning capability:
from lifx_emulator import create_hev_light
device = create_hev_light("d073d5000003")
print(f"Has HEV: {device.state.has_hev}") # True
print(f"Product: {device.state.product}") # 90 (LIFX Clean)
print(f"HEV cycle duration: {device.state.hev_cycle_duration_s}") # 7200 (2 hours)
Multizone Light¶
Create a linear multizone device (strip or beam):
from lifx_emulator import create_multizone_light
# Standard LIFX Z with default 16 zones
strip = create_multizone_light("d073d8000001")
# Custom zone count
strip_custom = create_multizone_light("d073d8000002", zone_count=24)
# Extended multizone (LIFX Beam) with default 80 zones
beam = create_multizone_light("d073d8000003", extended_multizone=True)
# Custom extended multizone
beam_custom = create_multizone_light(
"d073d8000004",
zone_count=60,
extended_multizone=True
)
print(f"Strip zones: {strip.state.zone_count}") # 16
print(f"Beam zones: {beam.state.zone_count}") # 80
print(f"Strip product: {strip.state.product}") # 32 (LIFX Z)
print(f"Beam product: {beam.state.product}") # 38 (LIFX Beam)
Tile Device¶
Create a matrix tile device:
from lifx_emulator import create_tile_device
# Default configuration (5 tiles of 8x8)
tiles = create_tile_device("d073d9000001")
# Custom tile count
tiles_custom = create_tile_device("d073d9000002", tile_count=10)
# Custom tile dimensions (e.g., 16x8 with >64 zones per tile)
large_tile = create_tile_device(
"d073d9000003",
tile_count=1,
tile_width=16,
tile_height=8
)
print(f"Tile count: {tiles.state.tile_count}") # 5
print(f"Tile width: {tiles.state.tile_width}") # 8
print(f"Tile height: {tiles.state.tile_height}") # 8
print(f"Product: {tiles.state.product}") # 55 (LIFX Tile)
# Tiles with >64 zones require multiple Get64 requests (16x8 = 128 zones)
print(f"Large tile zones: {large_tile.state.tile_width * large_tile.state.tile_height}") # 128
Generic Device Creation¶
Create any device by product ID:
from lifx_emulator.factories import create_device
# LIFX A19 (product ID 27)
a19 = create_device(27, serial="d073d5000001")
# LIFX Z (product ID 32) with custom zones
z_strip = create_device(32, serial="d073d8000001", zone_count=24)
# LIFX Tile (product ID 55) with custom configuration
tiles = create_device(
55,
serial="d073d9000001",
tile_count=10,
tile_width=8,
tile_height=8
)
# LIFX Candle (product ID 57) - loads 5x6 dimensions from product defaults
candle = create_device(57, serial="d073d9000002")
print(f"Candle size: {candle.state.tile_width}x{candle.state.tile_height}") # 5x6
Serial Format¶
Serials must be 12 hex characters (6 bytes):
# Valid formats
device = create_color_light("d073d5000001") # Serial with LIFX prefix ("d073d5")
device = create_color_light("cafe00abcdef") # Serial with custom prefix
device = create_color_light() # Auto-generate serial
# Invalid (will raise error)
device = create_color_light("123") # Too short
device = create_color_light("xyz") # Not hex
Auto-generated serials use prefixes based on device type:
d073d5- Regular lightsd073d6- Infrared lightsd073d7- HEV lightsd073d8- Multizone strips/beamsd073d9- Matrix tiles
Product Defaults¶
When parameters like zone_count or tile_count are not specified, the factory functions automatically load defaults from the product registry's specs system:
# Uses product default (16 zones for LIFX Z)
strip = create_multizone_light("d073d8000001")
# Uses product default (80 zones for LIFX Beam)
beam = create_multizone_light("d073d8000002", extended_multizone=True)
# Uses product default (5 tiles for LIFX Tile)
tiles = create_tile_device("d073d9000001")
# Uses product default (5x6 for LIFX Candle)
candle = create_device(57, serial="d073d9000002")
See Product Registry for all product definitions and defaults.
Device State Access¶
After creation, access device state:
device = create_color_light("d073d5000001")
# Device identity
print(device.state.serial) # "d073d5000001"
print(device.state.label) # "A19 d073d5"
print(device.state.vendor) # 1 (LIFX)
print(device.state.product) # 27 (LIFX A19)
# Device capabilities
print(device.state.has_color) # True
print(device.state.has_infrared) # False
print(device.state.has_multizone) # False
print(device.state.has_matrix) # False
print(device.state.has_hev) # False
# Light state
print(device.state.power_level) # 65535 (on)
print(device.state.color) # LightHsbk(...)
print(device.state.port) # 56700 (default)
# Firmware version
print(device.state.version_major) # 2
print(device.state.version_minor) # 80
Multiple Devices¶
Create multiple devices for testing:
from lifx_emulator import (
create_color_light,
create_multizone_light,
create_tile_device,
EmulatedLifxServer,
)
# Create a diverse set of devices
devices = [
create_color_light("d073d5000001"),
create_color_light("d073d5000002"),
create_multizone_light("d073d8000001", zone_count=16),
create_multizone_light("d073d8000002", zone_count=82, extended_multizone=True),
create_tile_device("d073d9000001", tile_count=5),
]
# Start server with all devices
server = EmulatedLifxServer(devices, "127.0.0.1", 56700)
await server.start()
Advanced Options¶
Persistent Storage¶
Devices can automatically persist state across restarts:
from lifx_emulator import create_color_light
from lifx_emulator.async_storage import AsyncDeviceStorage
# Create storage (uses ~/.lifx-emulator by default)
storage = AsyncDeviceStorage()
# Create device with storage enabled
device = create_color_light("d073d5000001", storage=storage)
# State changes are automatically saved asynchronously
device.state.label = "My Light"
# On next run, state is automatically restored from disk
Test Scenarios¶
Inject test scenarios (packet loss, delays, etc.) for error testing:
from lifx_emulator import create_color_light
from lifx_emulator.scenarios.manager import HierarchicalScenarioManager, ScenarioConfig
# Create scenario manager
manager = HierarchicalScenarioManager()
# Create device with scenario support
device = create_color_light("d073d5000001", scenario_manager=manager)
# Configure scenarios for testing error handling
manager.set_device_scenario(
device.state.serial,
ScenarioConfig(
drop_packets={101: 0.3}, # Drop 30% of GetColor packets
response_delays={102: 0.5}, # Add 500ms delay to SetColor
)
)
Custom Firmware Versions¶
Override firmware version for compatibility testing:
from lifx_emulator import create_color_light
# Simulate older firmware
old_device = create_color_light(
"d073d5000001",
firmware_version=(2, 60)
)
# Simulate newer firmware
new_device = create_color_light(
"d073d5000002",
firmware_version=(3, 90)
)
Next Steps¶
- Server API - Running the emulator server
- Device API - Device and state details
- Product Registry - All available products
- Basic Tutorial - Complete usage examples