lifx-emulator 1.0.0__py3-none-any.whl → 1.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.
- lifx_emulator/api.py +17 -1
- lifx_emulator/server.py +6 -0
- lifx_emulator-1.0.1.dist-info/METADATA +107 -0
- {lifx_emulator-1.0.0.dist-info → lifx_emulator-1.0.1.dist-info}/RECORD +7 -7
- lifx_emulator-1.0.0.dist-info/METADATA +0 -445
- {lifx_emulator-1.0.0.dist-info → lifx_emulator-1.0.1.dist-info}/WHEEL +0 -0
- {lifx_emulator-1.0.0.dist-info → lifx_emulator-1.0.1.dist-info}/entry_points.txt +0 -0
- {lifx_emulator-1.0.0.dist-info → lifx_emulator-1.0.1.dist-info}/licenses/LICENSE +0 -0
lifx_emulator/api.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
|
|
8
8
|
from fastapi import FastAPI, HTTPException
|
|
9
9
|
from fastapi.responses import HTMLResponse
|
|
10
|
-
from pydantic import BaseModel, Field
|
|
10
|
+
from pydantic import BaseModel, Field, field_validator
|
|
11
11
|
|
|
12
12
|
if TYPE_CHECKING:
|
|
13
13
|
from lifx_emulator.server import EmulatedLifxServer
|
|
@@ -133,6 +133,22 @@ class ScenarioConfigModel(BaseModel):
|
|
|
133
133
|
False, description="Send unhandled message responses for unknown packet types"
|
|
134
134
|
)
|
|
135
135
|
|
|
136
|
+
@field_validator("drop_packets", mode="before")
|
|
137
|
+
@classmethod
|
|
138
|
+
def convert_drop_packets_keys(cls, v):
|
|
139
|
+
"""Convert string keys to integers for drop_packets."""
|
|
140
|
+
if isinstance(v, dict):
|
|
141
|
+
return {int(k): float(val) for k, val in v.items()}
|
|
142
|
+
return v
|
|
143
|
+
|
|
144
|
+
@field_validator("response_delays", mode="before")
|
|
145
|
+
@classmethod
|
|
146
|
+
def convert_response_delays_keys(cls, v):
|
|
147
|
+
"""Convert string keys to integers for response_delays."""
|
|
148
|
+
if isinstance(v, dict):
|
|
149
|
+
return {int(k): float(val) for k, val in v.items()}
|
|
150
|
+
return v
|
|
151
|
+
|
|
136
152
|
|
|
137
153
|
class ScenarioResponse(BaseModel):
|
|
138
154
|
"""Response model for scenario operations."""
|
lifx_emulator/server.py
CHANGED
|
@@ -117,6 +117,12 @@ class EmulatedLifxServer:
|
|
|
117
117
|
# Scenario manager (shared across all devices for runtime updates)
|
|
118
118
|
self.scenario_manager = scenario_manager or HierarchicalScenarioManager()
|
|
119
119
|
|
|
120
|
+
# Share scenario manager with all initial devices
|
|
121
|
+
for device in devices:
|
|
122
|
+
if isinstance(device.scenario_manager, HierarchicalScenarioManager):
|
|
123
|
+
device.scenario_manager = self.scenario_manager
|
|
124
|
+
device.invalidate_scenario_cache()
|
|
125
|
+
|
|
120
126
|
# Activity observer - defaults to ActivityLogger if track_activity=True
|
|
121
127
|
if activity_observer is not None:
|
|
122
128
|
self.activity_observer = activity_observer
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: lifx-emulator
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: LIFX Emulator for testing LIFX LAN protocol libraries
|
|
5
|
+
Author-email: Avi Miller <me@dje.li>
|
|
6
|
+
Maintainer-email: Avi Miller <me@dje.li>
|
|
7
|
+
License-Expression: UPL-1.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Framework :: AsyncIO
|
|
10
|
+
Classifier: Framework :: Pytest
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Natural Language :: English
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: cyclopts>=4.2.0
|
|
23
|
+
Requires-Dist: fastapi>=0.115.0
|
|
24
|
+
Requires-Dist: pyyaml>=6.0.3
|
|
25
|
+
Requires-Dist: rich>=14.2.0
|
|
26
|
+
Requires-Dist: uvicorn>=0.34.0
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# LIFX Emulator
|
|
30
|
+
|
|
31
|
+
> A comprehensive LIFX device emulator for testing LIFX LAN protocol libraries
|
|
32
|
+
|
|
33
|
+
[](https://codecov.io/gh/Djelibeybi/lifx-emulator)
|
|
34
|
+
[](https://github.com/Djelibeybi/lifx-emulator/actions/workflows/ci.yml)
|
|
35
|
+
[](https://Djelibeybi.github.io/lifx-emulator/)
|
|
36
|
+
|
|
37
|
+
[](https://github.com/Djelibeybi/lifx-emulator/releases)
|
|
38
|
+
[](https://pypi.org/project/lifx-emulator/)
|
|
39
|
+
[](LICENSE)
|
|
40
|
+
[](https://www.python.org)
|
|
41
|
+
## Overview
|
|
42
|
+
|
|
43
|
+
LIFX Emulator implements the complete binary UDP protocol from [lan.developer.lifx.com](https://lan.developer.lifx.com) by providing virtual LIFX devices for testing without physical hardware. The emulator includes a basic web interface and OpenAPI-compliant REST API for device and scenario management at runtime.
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- **Complete Protocol Support**: 44+ packet types from the LIFX LAN protocol
|
|
48
|
+
- **Multiple Device Types**: Color lights, infrared, HEV, multizone strips, matrix tiles
|
|
49
|
+
- **REST API and Web Interface**: Monitor and manage your virtual devices during testing
|
|
50
|
+
- **Testing Scenarios**: Built-in support for packet loss, delays, malformed responses
|
|
51
|
+
- **Easy Integration**: Simple Python API and comprehensive CLI
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
- **[Installation Guide](https://djelibeybi.github.io/lifx-emulator/getting-started/installation/)** - Get started
|
|
57
|
+
- **[Quick Start](https://djelibeybi.github.io/lifx-emulator/getting-started/quickstart/)** - Your first emulated device
|
|
58
|
+
- **[User Guide](https://djelibeybi.github.io/lifx-emulator/guide/overview/)** - Product specifications and testing scenarios
|
|
59
|
+
- **[Advanced Topics](https://djelibeybi.github.io/lifx-emulator/advanced/device-management-api/)** - REST API and persistent storage
|
|
60
|
+
- **[CLI Reference](https://djelibeybi.github.io/lifx-emulator/getting-started/cli/)** - All CLI options
|
|
61
|
+
- **[Device Types](https://djelibeybi.github.io/lifx-emulator/guide/device-types/)** - Supported devices
|
|
62
|
+
- **[API Reference](https://djelibeybi.github.io/lifx-emulator/api/)** - Complete API docs
|
|
63
|
+
- **[Architecture](https://djelibeybi.github.io/lifx-emulator/architecture/overview/)** - How it works
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## Use Cases
|
|
67
|
+
|
|
68
|
+
- **Library Testing**: Test your LIFX library without physical devices
|
|
69
|
+
- **CI/CD Integration**: Run automated tests in pipelines
|
|
70
|
+
- **Protocol Development**: Experiment with LIFX protocol features
|
|
71
|
+
- **Error Simulation**: Test error handling with configurable scenarios
|
|
72
|
+
- **Performance Testing**: Test concurrent device handling
|
|
73
|
+
|
|
74
|
+
## Development
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Clone repository
|
|
78
|
+
git clone https://github.com/Djelibeybi/lifx-emulator.git
|
|
79
|
+
cd lifx-emulator
|
|
80
|
+
|
|
81
|
+
# Install with uv (recommended)
|
|
82
|
+
uv sync
|
|
83
|
+
|
|
84
|
+
# Or with pip
|
|
85
|
+
pip install -e ".[dev]"
|
|
86
|
+
|
|
87
|
+
# Run tests
|
|
88
|
+
uv run pytest
|
|
89
|
+
|
|
90
|
+
# Run linter
|
|
91
|
+
uv run ruff check .
|
|
92
|
+
|
|
93
|
+
# Build docs
|
|
94
|
+
uv run mkdocs serve
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## License
|
|
99
|
+
|
|
100
|
+
[UPL-1.0](LICENSE)
|
|
101
|
+
|
|
102
|
+
## Links
|
|
103
|
+
|
|
104
|
+
- **Documentation**: https://djelibeybi.github.io/lifx-emulator
|
|
105
|
+
- **GitHub**: https://github.com/Djelibeybi/lifx-emulator
|
|
106
|
+
- **PyPI**: https://pypi.org/project/lifx-emulator/
|
|
107
|
+
- **LIFX Protocol**: https://lan.developer.lifx.com
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
lifx_emulator/__init__.py,sha256=WzD3GRp_QFlYF9IexitPxuTVyOUDNv2ZApKhfRP0UGA,818
|
|
2
2
|
lifx_emulator/__main__.py,sha256=gfx_SW0Vywlvt68KmozYuZMRWiTow0rgPmeiVHoTfHg,22437
|
|
3
|
-
lifx_emulator/api.py,sha256=
|
|
3
|
+
lifx_emulator/api.py,sha256=ATVLtPNh-9TySn_orFV03vJvZ20D5VZyuVQPgvzUuFg,67416
|
|
4
4
|
lifx_emulator/async_storage.py,sha256=-J4s_4Cxika_EDlFjBegKAaM8sY78wbTDWnttWH4Eik,10504
|
|
5
5
|
lifx_emulator/constants.py,sha256=DFZkUsdewE-x_3MgO28tMGkjUCWPeYc3xLj_EXViGOw,1032
|
|
6
6
|
lifx_emulator/device.py,sha256=qaTNgeyvg1S-g1rC91NnQpvDe4p1razMNVDTlv0vKMI,24109
|
|
@@ -9,7 +9,7 @@ lifx_emulator/factories.py,sha256=vLsGFuP8E_9bbdo2Sry3G6Ax6qSl5QfpXsRfXE3SfBU,13
|
|
|
9
9
|
lifx_emulator/observers.py,sha256=-KnUgFcKdhlNo7CNVstP-u0wU2W0JAGg055ZPV15Sj0,3874
|
|
10
10
|
lifx_emulator/scenario_manager.py,sha256=xv2NwdZjDcF83MTt7JjKgDvua6zx6SkGQT1P4156-RU,14154
|
|
11
11
|
lifx_emulator/scenario_persistence.py,sha256=oytK5W2si1N-O31jBACHhGQyo5IrINlqfWE0K2bZq_8,7394
|
|
12
|
-
lifx_emulator/server.py,sha256=
|
|
12
|
+
lifx_emulator/server.py,sha256=mWkssl42Z_5m78DAn5_-DRACLGvymSbouTE4j8dVAXA,17239
|
|
13
13
|
lifx_emulator/state_restorer.py,sha256=isgCsmcjxc4aQrTXoIYr_FoIU4H5Swg7GNaoh_-X7zU,9793
|
|
14
14
|
lifx_emulator/state_serializer.py,sha256=O4Cp3bbGkd4eZf5jzb0MKzWDTgiNhrSGgypmMWaB4dg,5097
|
|
15
15
|
lifx_emulator/storage_protocol.py,sha256=j5wC4gI-2DtPgmY4kM3mKDI6OYpmiNpGulzdJnZnqYY,2929
|
|
@@ -33,8 +33,8 @@ lifx_emulator/protocol/header.py,sha256=RXMJ5YZG1jyxl4Mz46ZGJBYX41Jdp7J95BHuY-sc
|
|
|
33
33
|
lifx_emulator/protocol/packets.py,sha256=_xYYPuu6WfBpg1LwYVdzQdytFwTyMqpZRadmDdwZXWk,41567
|
|
34
34
|
lifx_emulator/protocol/protocol_types.py,sha256=2Mccm9717EuTXQYaW44W_yReI4EtnlPp3-WEVASgdGY,24820
|
|
35
35
|
lifx_emulator/protocol/serializer.py,sha256=2bZz7TddxaMRO4_6LujRGCS1w7GxD4E3rRk3r-hpEIE,10738
|
|
36
|
-
lifx_emulator-1.0.
|
|
37
|
-
lifx_emulator-1.0.
|
|
38
|
-
lifx_emulator-1.0.
|
|
39
|
-
lifx_emulator-1.0.
|
|
40
|
-
lifx_emulator-1.0.
|
|
36
|
+
lifx_emulator-1.0.1.dist-info/METADATA,sha256=nF8KzCbCNFR6O0CvE_S9-VD5pAuTQLJBxDpwXVk9Dqk,4549
|
|
37
|
+
lifx_emulator-1.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
lifx_emulator-1.0.1.dist-info/entry_points.txt,sha256=R9C_K_tTgt6yXEmhzH4r2Yx2Tu1rLlnYzeG4RFUVzSc,62
|
|
39
|
+
lifx_emulator-1.0.1.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
|
|
40
|
+
lifx_emulator-1.0.1.dist-info/RECORD,,
|
|
@@ -1,445 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: lifx-emulator
|
|
3
|
-
Version: 1.0.0
|
|
4
|
-
Summary: LIFX Emulator for testing LIFX LAN protocol libraries
|
|
5
|
-
Author-email: Avi Miller <me@dje.li>
|
|
6
|
-
Maintainer-email: Avi Miller <me@dje.li>
|
|
7
|
-
License-Expression: UPL-1.0
|
|
8
|
-
License-File: LICENSE
|
|
9
|
-
Classifier: Framework :: AsyncIO
|
|
10
|
-
Classifier: Framework :: Pytest
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Natural Language :: English
|
|
13
|
-
Classifier: Operating System :: OS Independent
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
-
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
-
Classifier: Typing :: Typed
|
|
21
|
-
Requires-Python: >=3.11
|
|
22
|
-
Requires-Dist: cyclopts>=4.2.0
|
|
23
|
-
Requires-Dist: fastapi>=0.115.0
|
|
24
|
-
Requires-Dist: pyyaml>=6.0.3
|
|
25
|
-
Requires-Dist: rich>=14.2.0
|
|
26
|
-
Requires-Dist: uvicorn>=0.34.0
|
|
27
|
-
Description-Content-Type: text/markdown
|
|
28
|
-
|
|
29
|
-
# LIFX Emulator
|
|
30
|
-
|
|
31
|
-
> A comprehensive LIFX device emulator for testing LIFX LAN protocol libraries
|
|
32
|
-
|
|
33
|
-
[](LICENSE)
|
|
34
|
-
[](https://www.python.org/downloads/)
|
|
35
|
-
|
|
36
|
-
## Overview
|
|
37
|
-
|
|
38
|
-
LIFX Emulator implements the complete binary UDP protocol from [lan.developer.lifx.com](https://lan.developer.lifx.com), providing virtual LIFX devices for testing without physical hardware.
|
|
39
|
-
|
|
40
|
-
## Features
|
|
41
|
-
|
|
42
|
-
- **Complete Protocol Support**: 44+ packet types from the LIFX LAN protocol
|
|
43
|
-
- **Multiple Device Types**: Color lights, infrared, HEV, multizone strips, matrix tiles
|
|
44
|
-
- **Product Registry**: 40+ official LIFX product definitions with accurate defaults
|
|
45
|
-
- **Testing Scenarios**: Built-in support for packet loss, delays, malformed responses
|
|
46
|
-
- **Easy Integration**: Simple Python API and comprehensive CLI
|
|
47
|
-
- **Zero Dependencies**: Pure Python with only PyYAML for configuration
|
|
48
|
-
|
|
49
|
-
## Quick Start
|
|
50
|
-
|
|
51
|
-
### Installation
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
pip install lifx-emulator
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### CLI Usage
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
# Start with default configuration (1 color light)
|
|
61
|
-
lifx-emulator
|
|
62
|
-
|
|
63
|
-
# Create multiple device types with verbose logging
|
|
64
|
-
lifx-emulator --color 2 --multizone 1 --tile 1 --verbose
|
|
65
|
-
|
|
66
|
-
# Use specific products from registry
|
|
67
|
-
lifx-emulator --product 27 --product 32 --product 55
|
|
68
|
-
|
|
69
|
-
# List all available products
|
|
70
|
-
lifx-emulator list-products
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Python API
|
|
74
|
-
|
|
75
|
-
```python
|
|
76
|
-
import asyncio
|
|
77
|
-
from lifx_emulator import EmulatedLifxServer, create_color_light
|
|
78
|
-
|
|
79
|
-
async def main():
|
|
80
|
-
# Create emulated device
|
|
81
|
-
device = create_color_light("d073d5000001")
|
|
82
|
-
|
|
83
|
-
# Start server
|
|
84
|
-
async with EmulatedLifxServer([device], "127.0.0.1", 56700) as server:
|
|
85
|
-
print(f"Server running with device: {device.state.label}")
|
|
86
|
-
await asyncio.Event().wait()
|
|
87
|
-
|
|
88
|
-
asyncio.run(main())
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Integration Testing
|
|
92
|
-
|
|
93
|
-
```python
|
|
94
|
-
import pytest
|
|
95
|
-
from lifx_emulator import EmulatedLifxServer, create_color_light
|
|
96
|
-
from your_lifx_library import LifxClient
|
|
97
|
-
|
|
98
|
-
@pytest.mark.asyncio
|
|
99
|
-
async def test_discover_devices():
|
|
100
|
-
# Create emulated device
|
|
101
|
-
device = create_color_light("d073d5000001")
|
|
102
|
-
|
|
103
|
-
# Start emulator
|
|
104
|
-
async with EmulatedLifxServer([device], "127.0.0.1", 56700):
|
|
105
|
-
# Test your library
|
|
106
|
-
client = LifxClient()
|
|
107
|
-
await client.discover(port=56700)
|
|
108
|
-
|
|
109
|
-
assert len(client.devices) == 1
|
|
110
|
-
assert client.devices[0].mac == "d073d5000001"
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Supported Device Types
|
|
114
|
-
|
|
115
|
-
| Device Type | Factory Function | Example Product |
|
|
116
|
-
|------------|------------------|-----------------|
|
|
117
|
-
| Color Lights | `create_color_light()` | LIFX A19 |
|
|
118
|
-
| Color Temperature | `create_color_temperature_light()` | LIFX Mini White to Warm |
|
|
119
|
-
| Infrared | `create_infrared_light()` | LIFX A19 Night Vision |
|
|
120
|
-
| HEV | `create_hev_light()` | LIFX Clean |
|
|
121
|
-
| Multizone | `create_multizone_light()` | LIFX Z, LIFX Beam |
|
|
122
|
-
| Matrix Tiles | `create_tile_device()` | LIFX Tile |
|
|
123
|
-
|
|
124
|
-
[See all 40+ supported products →](https://lifx-emulator.readthedocs.io/en/latest/guide/device-types/)
|
|
125
|
-
|
|
126
|
-
## Documentation
|
|
127
|
-
|
|
128
|
-
- **[Installation Guide](https://lifx-emulator.readthedocs.io/en/latest/getting-started/installation/)** - Get started
|
|
129
|
-
- **[Quick Start](https://lifx-emulator.readthedocs.io/en/latest/getting-started/quickstart/)** - Your first emulated device
|
|
130
|
-
- **[CLI Reference](https://lifx-emulator.readthedocs.io/en/latest/getting-started/cli/)** - All CLI options
|
|
131
|
-
- **[Device Types](https://lifx-emulator.readthedocs.io/en/latest/guide/device-types/)** - Supported devices
|
|
132
|
-
- **[API Reference](https://lifx-emulator.readthedocs.io/en/latest/api/)** - Complete API docs
|
|
133
|
-
- **[Architecture](https://lifx-emulator.readthedocs.io/en/latest/architecture/overview/)** - How it works
|
|
134
|
-
|
|
135
|
-
## CLI Examples
|
|
136
|
-
|
|
137
|
-
### Basic Usage
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
# Single color light on default port 56700
|
|
141
|
-
lifx-emulator
|
|
142
|
-
|
|
143
|
-
# Multiple devices with verbose logging
|
|
144
|
-
lifx-emulator --color 2 --multizone 1 --tile 1 --verbose
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Advanced Usage
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
# Extended multizone (LIFX Beam) with custom zone count
|
|
151
|
-
lifx-emulator --multizone 1 --multizone-extended --multizone-zones 60
|
|
152
|
-
|
|
153
|
-
# Specific products by ID
|
|
154
|
-
lifx-emulator --product 27 --product 32 --product 55
|
|
155
|
-
|
|
156
|
-
# Custom port and localhost only
|
|
157
|
-
lifx-emulator --bind 127.0.0.1 --port 56701
|
|
158
|
-
|
|
159
|
-
# Filter products list
|
|
160
|
-
lifx-emulator list-products --filter-type multizone
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
## Python API Examples
|
|
164
|
-
|
|
165
|
-
### Multiple Device Types
|
|
166
|
-
|
|
167
|
-
```python
|
|
168
|
-
from lifx_emulator import (
|
|
169
|
-
EmulatedLifxServer,
|
|
170
|
-
create_color_light,
|
|
171
|
-
create_multizone_light,
|
|
172
|
-
create_tile_device,
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
devices = [
|
|
176
|
-
create_color_light("d073d5000001"),
|
|
177
|
-
create_multizone_light("d073d8000001", zone_count=16),
|
|
178
|
-
create_tile_device("d073d9000001", tile_count=5),
|
|
179
|
-
]
|
|
180
|
-
|
|
181
|
-
async with EmulatedLifxServer(devices, "127.0.0.1", 56700) as server:
|
|
182
|
-
# All devices are discoverable and controllable
|
|
183
|
-
print(f"Emulating {len(devices)} devices")
|
|
184
|
-
await asyncio.Event().wait()
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
### Testing Scenarios
|
|
188
|
-
|
|
189
|
-
```python
|
|
190
|
-
# Configure error scenarios for testing
|
|
191
|
-
device = create_color_light("d073d5000001")
|
|
192
|
-
device.scenarios = {
|
|
193
|
-
'drop_packets': [101], # Drop LightGet packets
|
|
194
|
-
'response_delays': {102: 0.5}, # Delay SetColor by 500ms
|
|
195
|
-
'malformed_packets': [107], # Truncate StateLight
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async with EmulatedLifxServer([device], "127.0.0.1", 56700) as server:
|
|
199
|
-
# Test your library's error handling
|
|
200
|
-
pass
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
## Use Cases
|
|
204
|
-
|
|
205
|
-
- **Library Testing**: Test your LIFX library without physical devices
|
|
206
|
-
- **CI/CD Integration**: Run automated tests in pipelines
|
|
207
|
-
- **Protocol Development**: Experiment with LIFX protocol features
|
|
208
|
-
- **Error Simulation**: Test error handling with configurable scenarios
|
|
209
|
-
- **Performance Testing**: Test concurrent device handling
|
|
210
|
-
|
|
211
|
-
## Requirements
|
|
212
|
-
|
|
213
|
-
- Python 3.13+
|
|
214
|
-
- PyYAML (automatically installed)
|
|
215
|
-
|
|
216
|
-
## Performance
|
|
217
|
-
|
|
218
|
-
The emulator includes comprehensive performance optimization with **51% average throughput improvement**:
|
|
219
|
-
|
|
220
|
-
- Complete benchmarking and profiling suite
|
|
221
|
-
- Detailed optimization analysis and recommendations
|
|
222
|
-
- Before/after performance comparison
|
|
223
|
-
|
|
224
|
-
**Key Results:**
|
|
225
|
-
- **Packet Processing**: +51% (35K → 53K pkt/s)
|
|
226
|
-
- **Serialization**: +77% (27K → 48K pkt/s)
|
|
227
|
-
- **Latency**: -35% to -44% reduction
|
|
228
|
-
|
|
229
|
-
See the [Performance Documentation](docs/performance/index.md) for details.
|
|
230
|
-
|
|
231
|
-
### Run Performance Benchmarks
|
|
232
|
-
|
|
233
|
-
```bash
|
|
234
|
-
uv run python tools/performance/benchmark.py
|
|
235
|
-
uv run python tools/performance/profiler.py
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
## Development
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
# Clone repository
|
|
242
|
-
git clone https://github.com/Djelibeybi/lifx-emulator.git
|
|
243
|
-
cd lifx-emulator
|
|
244
|
-
|
|
245
|
-
# Install with uv (recommended)
|
|
246
|
-
uv sync
|
|
247
|
-
|
|
248
|
-
# Or with pip
|
|
249
|
-
pip install -e ".[dev]"
|
|
250
|
-
|
|
251
|
-
# Run tests
|
|
252
|
-
uv run pytest
|
|
253
|
-
|
|
254
|
-
# Run linter
|
|
255
|
-
uv run ruff check .
|
|
256
|
-
|
|
257
|
-
# Build docs
|
|
258
|
-
uv run mkdocs serve
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### Documentation Tools
|
|
262
|
-
|
|
263
|
-
The emulator includes automated tools for documentation generation, validation, and quality checking:
|
|
264
|
-
|
|
265
|
-
#### 1. API Reference Generator (`generate_api_reference.py`)
|
|
266
|
-
|
|
267
|
-
Auto-generates API reference documentation from Python source code with docstrings, type hints, and inheritance diagrams.
|
|
268
|
-
|
|
269
|
-
```bash
|
|
270
|
-
# Generate API reference for a module
|
|
271
|
-
python tools/docs/generate_api_reference.py src/lifx_emulator/device.py > docs/api/device.md
|
|
272
|
-
|
|
273
|
-
# With output file
|
|
274
|
-
python tools/docs/generate_api_reference.py src/lifx_emulator/storage.py --output docs/api/storage.md
|
|
275
|
-
```
|
|
276
|
-
|
|
277
|
-
#### 2. Diagram Generator (`generate_diagrams.py`)
|
|
278
|
-
|
|
279
|
-
Auto-generates architecture diagrams from code analysis (component, packet flow, state machine, handler flow).
|
|
280
|
-
|
|
281
|
-
```bash
|
|
282
|
-
# Generate all diagrams
|
|
283
|
-
python tools/docs/generate_diagrams.py --type all --output docs/architecture/diagrams/
|
|
284
|
-
|
|
285
|
-
# Generate specific diagram type
|
|
286
|
-
python tools/docs/generate_diagrams.py --type component
|
|
287
|
-
python tools/docs/generate_diagrams.py --type packet-flow
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
#### 3. Example Validator (`validate_examples.py`)
|
|
291
|
-
|
|
292
|
-
Validates that code examples in documentation actually work by extracting and compiling Python code blocks.
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
# Validate all examples in docs/
|
|
296
|
-
python tools/docs/validate_examples.py docs/
|
|
297
|
-
|
|
298
|
-
# Validate with verbose output
|
|
299
|
-
python tools/docs/validate_examples.py docs/tutorials/ --verbose
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
#### 4. Coverage Reporter (`coverage_report.py`)
|
|
303
|
-
|
|
304
|
-
Tracks documentation coverage across the codebase and enforces minimum coverage thresholds.
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
# Generate coverage report
|
|
308
|
-
python tools/docs/coverage_report.py
|
|
309
|
-
|
|
310
|
-
# Require minimum coverage
|
|
311
|
-
python tools/docs/coverage_report.py --min-coverage 80
|
|
312
|
-
|
|
313
|
-
# Generate HTML report
|
|
314
|
-
python tools/docs/coverage_report.py --html --output coverage.html
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
#### 5. Terminology Checker (`check_terminology.py`)
|
|
318
|
-
|
|
319
|
-
Validates consistent terminology usage across documentation against defined glossary.
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
# Check terminology
|
|
323
|
-
python tools/docs/check_terminology.py docs/
|
|
324
|
-
|
|
325
|
-
# Auto-fix violations
|
|
326
|
-
python tools/docs/check_terminology.py docs/ --fix
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
#### Documentation Workflow
|
|
330
|
-
|
|
331
|
-
When writing documentation:
|
|
332
|
-
|
|
333
|
-
1. **Write content** with code examples
|
|
334
|
-
2. **Run validation locally:**
|
|
335
|
-
```bash
|
|
336
|
-
# Check terminology
|
|
337
|
-
python tools/docs/check_terminology.py docs/ --fix
|
|
338
|
-
|
|
339
|
-
# Validate examples
|
|
340
|
-
python tools/docs/validate_examples.py docs/ --verbose
|
|
341
|
-
|
|
342
|
-
# Check coverage
|
|
343
|
-
python tools/docs/coverage_report.py
|
|
344
|
-
```
|
|
345
|
-
|
|
346
|
-
3. **Auto-generate API reference:**
|
|
347
|
-
```bash
|
|
348
|
-
python tools/docs/generate_api_reference.py src/lifx_emulator/device.py --output docs/api/device.md
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
4. **Generate diagrams:**
|
|
352
|
-
```bash
|
|
353
|
-
python tools/docs/generate_diagrams.py --type all --output docs/architecture/diagrams/
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
5. **Commit changes** - CI will validate everything
|
|
357
|
-
|
|
358
|
-
The `.github/workflows/docs.yml` workflow runs all validation tools on pull requests and pushes to main.
|
|
359
|
-
|
|
360
|
-
See [Documentation Tools](docs/development/documentation-tools.md) for detailed documentation tool usage and troubleshooting.
|
|
361
|
-
|
|
362
|
-
## Product Registry
|
|
363
|
-
|
|
364
|
-
The emulator includes an auto-generated registry of all official LIFX products with accurate defaults:
|
|
365
|
-
|
|
366
|
-
```python
|
|
367
|
-
from lifx_emulator.products.registry import get_product, get_registry
|
|
368
|
-
|
|
369
|
-
# Get specific product
|
|
370
|
-
product = get_product(27) # LIFX A19
|
|
371
|
-
print(f"{product.name}: {product.pid}")
|
|
372
|
-
print(f"Capabilities: color={product.has_color}, multizone={product.has_multizone}")
|
|
373
|
-
|
|
374
|
-
# List all products
|
|
375
|
-
registry = get_registry()
|
|
376
|
-
for pid, product in registry.products.items():
|
|
377
|
-
print(f"PID {pid}: {product.name}")
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
## Testing Scenarios
|
|
381
|
-
|
|
382
|
-
Configure devices to simulate real-world issues:
|
|
383
|
-
|
|
384
|
-
```python
|
|
385
|
-
device.scenarios = {
|
|
386
|
-
# Packet dropping (simulate packet loss)
|
|
387
|
-
'drop_packets': [101, 102],
|
|
388
|
-
|
|
389
|
-
# Response delays (simulate latency)
|
|
390
|
-
'response_delays': {102: 0.5, 107: 1.0},
|
|
391
|
-
|
|
392
|
-
# Malformed packets (test error handling)
|
|
393
|
-
'malformed_packets': [107],
|
|
394
|
-
|
|
395
|
-
# Invalid field values (test validation)
|
|
396
|
-
'invalid_field_values': {22: True},
|
|
397
|
-
|
|
398
|
-
# Partial responses (test timeout handling)
|
|
399
|
-
'partial_responses': [506],
|
|
400
|
-
}
|
|
401
|
-
```
|
|
402
|
-
|
|
403
|
-
## Architecture
|
|
404
|
-
|
|
405
|
-
```
|
|
406
|
-
┌─────────────────┐
|
|
407
|
-
│ LIFX Client │
|
|
408
|
-
│ Library │
|
|
409
|
-
└────────┬────────┘
|
|
410
|
-
│ UDP Packets
|
|
411
|
-
▼
|
|
412
|
-
┌─────────────────┐
|
|
413
|
-
│ EmulatedLifx │
|
|
414
|
-
│ Server │
|
|
415
|
-
└────────┬────────┘
|
|
416
|
-
│ Route by MAC
|
|
417
|
-
▼
|
|
418
|
-
┌─────────────────┐ ┌──────────────┐
|
|
419
|
-
│ EmulatedLifx │────▶│ DeviceState │
|
|
420
|
-
│ Device │ │ (Stateful) │
|
|
421
|
-
└────────┬────────┘ └──────────────┘
|
|
422
|
-
│
|
|
423
|
-
▼
|
|
424
|
-
┌─────────────────┐
|
|
425
|
-
│ Protocol Layer │
|
|
426
|
-
│ (44+ packets) │
|
|
427
|
-
└─────────────────┘
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
[Learn more about the architecture →](https://lifx-emulator.readthedocs.io/en/latest/architecture/overview/)
|
|
431
|
-
|
|
432
|
-
## Contributing
|
|
433
|
-
|
|
434
|
-
Contributions are welcome! Please see our [Contributing Guide](https://lifx-emulator.readthedocs.io/en/latest/development/contributing/) for details.
|
|
435
|
-
|
|
436
|
-
## License
|
|
437
|
-
|
|
438
|
-
[UPL-1.0](LICENSE)
|
|
439
|
-
|
|
440
|
-
## Links
|
|
441
|
-
|
|
442
|
-
- **Documentation**: https://lifx-emulator.readthedocs.io
|
|
443
|
-
- **GitHub**: https://github.com/Djelibeybi/lifx-emulator
|
|
444
|
-
- **PyPI**: https://pypi.org/project/lifx-emulator/
|
|
445
|
-
- **LIFX Protocol**: https://lan.developer.lifx.com
|
|
File without changes
|
|
File without changes
|
|
File without changes
|