lifx-emulator 1.0.0__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/__init__.py +31 -0
- lifx_emulator/__main__.py +607 -0
- lifx_emulator/api.py +1825 -0
- lifx_emulator/async_storage.py +308 -0
- lifx_emulator/constants.py +33 -0
- lifx_emulator/device.py +750 -0
- lifx_emulator/device_states.py +114 -0
- lifx_emulator/factories.py +380 -0
- lifx_emulator/handlers/__init__.py +39 -0
- lifx_emulator/handlers/base.py +49 -0
- lifx_emulator/handlers/device_handlers.py +340 -0
- lifx_emulator/handlers/light_handlers.py +372 -0
- lifx_emulator/handlers/multizone_handlers.py +249 -0
- lifx_emulator/handlers/registry.py +110 -0
- lifx_emulator/handlers/tile_handlers.py +309 -0
- lifx_emulator/observers.py +139 -0
- lifx_emulator/products/__init__.py +28 -0
- lifx_emulator/products/generator.py +771 -0
- lifx_emulator/products/registry.py +1446 -0
- lifx_emulator/products/specs.py +242 -0
- lifx_emulator/products/specs.yml +327 -0
- lifx_emulator/protocol/__init__.py +1 -0
- lifx_emulator/protocol/base.py +334 -0
- lifx_emulator/protocol/const.py +8 -0
- lifx_emulator/protocol/generator.py +1371 -0
- lifx_emulator/protocol/header.py +159 -0
- lifx_emulator/protocol/packets.py +1351 -0
- lifx_emulator/protocol/protocol_types.py +844 -0
- lifx_emulator/protocol/serializer.py +379 -0
- lifx_emulator/scenario_manager.py +402 -0
- lifx_emulator/scenario_persistence.py +206 -0
- lifx_emulator/server.py +482 -0
- lifx_emulator/state_restorer.py +259 -0
- lifx_emulator/state_serializer.py +130 -0
- lifx_emulator/storage_protocol.py +100 -0
- lifx_emulator-1.0.0.dist-info/METADATA +445 -0
- lifx_emulator-1.0.0.dist-info/RECORD +40 -0
- lifx_emulator-1.0.0.dist-info/WHEEL +4 -0
- lifx_emulator-1.0.0.dist-info/entry_points.txt +2 -0
- lifx_emulator-1.0.0.dist-info/licenses/LICENSE +35 -0
|
@@ -0,0 +1,445 @@
|
|
|
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
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
lifx_emulator/__init__.py,sha256=WzD3GRp_QFlYF9IexitPxuTVyOUDNv2ZApKhfRP0UGA,818
|
|
2
|
+
lifx_emulator/__main__.py,sha256=gfx_SW0Vywlvt68KmozYuZMRWiTow0rgPmeiVHoTfHg,22437
|
|
3
|
+
lifx_emulator/api.py,sha256=AVtaLYIjTtYJ-FL19Ny9WyvCOJHqfPmP5Tb1B_Gs20M,66810
|
|
4
|
+
lifx_emulator/async_storage.py,sha256=-J4s_4Cxika_EDlFjBegKAaM8sY78wbTDWnttWH4Eik,10504
|
|
5
|
+
lifx_emulator/constants.py,sha256=DFZkUsdewE-x_3MgO28tMGkjUCWPeYc3xLj_EXViGOw,1032
|
|
6
|
+
lifx_emulator/device.py,sha256=qaTNgeyvg1S-g1rC91NnQpvDe4p1razMNVDTlv0vKMI,24109
|
|
7
|
+
lifx_emulator/device_states.py,sha256=3juEk1PpBySOwB3XpvH4UqKAPek5ZNCbvepJ3Y97Sck,2855
|
|
8
|
+
lifx_emulator/factories.py,sha256=vLsGFuP8E_9bbdo2Sry3G6Ax6qSl5QfpXsRfXE3SfBU,13017
|
|
9
|
+
lifx_emulator/observers.py,sha256=-KnUgFcKdhlNo7CNVstP-u0wU2W0JAGg055ZPV15Sj0,3874
|
|
10
|
+
lifx_emulator/scenario_manager.py,sha256=xv2NwdZjDcF83MTt7JjKgDvua6zx6SkGQT1P4156-RU,14154
|
|
11
|
+
lifx_emulator/scenario_persistence.py,sha256=oytK5W2si1N-O31jBACHhGQyo5IrINlqfWE0K2bZq_8,7394
|
|
12
|
+
lifx_emulator/server.py,sha256=Puw5OG1hVauv_EReu9Kp5i6S7q78H_6AT-X0zcx1kEs,16953
|
|
13
|
+
lifx_emulator/state_restorer.py,sha256=isgCsmcjxc4aQrTXoIYr_FoIU4H5Swg7GNaoh_-X7zU,9793
|
|
14
|
+
lifx_emulator/state_serializer.py,sha256=O4Cp3bbGkd4eZf5jzb0MKzWDTgiNhrSGgypmMWaB4dg,5097
|
|
15
|
+
lifx_emulator/storage_protocol.py,sha256=j5wC4gI-2DtPgmY4kM3mKDI6OYpmiNpGulzdJnZnqYY,2929
|
|
16
|
+
lifx_emulator/handlers/__init__.py,sha256=3Hj1hRo3yL3E7GKwG9TaYh33ymk_N3bRiQ8nvqSQULA,1306
|
|
17
|
+
lifx_emulator/handlers/base.py,sha256=Kn_OoVOQPlJOkl-xiHRYsoNKsS054sxk7sZ8rI9NvXQ,1653
|
|
18
|
+
lifx_emulator/handlers/device_handlers.py,sha256=MDUanFFDT9RWBcWtEZ3sXeGmoYjFW50T4zVIkkK2iB4,10239
|
|
19
|
+
lifx_emulator/handlers/light_handlers.py,sha256=ycwOAD6skmBLVUlyeg5kBprHDlrllP-_0JRzQrDGFos,11778
|
|
20
|
+
lifx_emulator/handlers/multizone_handlers.py,sha256=949FEt1Ilhp-LCxxY0xfHxYJccGNy_xnNhO14ePENaw,7913
|
|
21
|
+
lifx_emulator/handlers/registry.py,sha256=s1ht4PmPhXhAcwu1hoY4yW39wy3SPJBMY-9Uxd0FWuE,3292
|
|
22
|
+
lifx_emulator/handlers/tile_handlers.py,sha256=jzguqNr_aZheuqd4mikfQlkRcVeqs3HAEAseFSlkBlE,10038
|
|
23
|
+
lifx_emulator/products/__init__.py,sha256=qcNop_kRYFF3zSjNemzQEgu3jPrIxfyQyLv9GsnaLEI,627
|
|
24
|
+
lifx_emulator/products/generator.py,sha256=N8dNDTX9eoDtB3Nb02zHnLyooUR396GdjWGI4_I-Dls,25742
|
|
25
|
+
lifx_emulator/products/registry.py,sha256=zNF3Nzzaj3Rlrs_YdI-KpDGCj3jA_zpoqFmcaD3_LJo,44526
|
|
26
|
+
lifx_emulator/products/specs.py,sha256=2bpgr2z2Ugb_0IBl9LY8LGotB031Bim8zizwvtviFZ0,7186
|
|
27
|
+
lifx_emulator/products/specs.yml,sha256=uxzdKFREAHphk8XSPiCHvQE2vwoPfT2m1xy-zC4ZIl4,8552
|
|
28
|
+
lifx_emulator/protocol/__init__.py,sha256=-wjC-wBcb7fxi5I-mJr2Ad8K2YRflJFdLLdobfD-W1Q,56
|
|
29
|
+
lifx_emulator/protocol/base.py,sha256=OH2fLGJCAFYCgaxkKB3-pLclRaCIMIQtLtlgS_Qe4Ko,12090
|
|
30
|
+
lifx_emulator/protocol/const.py,sha256=ilhv-KcQpHtKh2MDCaIbMLQAsxKO_uTaxyR63v1W8cc,226
|
|
31
|
+
lifx_emulator/protocol/generator.py,sha256=KuNuWUUNikBRudcnBNIFcJ_2h2zliceVmyxfyyHIpXc,48980
|
|
32
|
+
lifx_emulator/protocol/header.py,sha256=RXMJ5YZG1jyxl4Mz46ZGJBYX41Jdp7J95BHuY-scYC0,5499
|
|
33
|
+
lifx_emulator/protocol/packets.py,sha256=_xYYPuu6WfBpg1LwYVdzQdytFwTyMqpZRadmDdwZXWk,41567
|
|
34
|
+
lifx_emulator/protocol/protocol_types.py,sha256=2Mccm9717EuTXQYaW44W_yReI4EtnlPp3-WEVASgdGY,24820
|
|
35
|
+
lifx_emulator/protocol/serializer.py,sha256=2bZz7TddxaMRO4_6LujRGCS1w7GxD4E3rRk3r-hpEIE,10738
|
|
36
|
+
lifx_emulator-1.0.0.dist-info/METADATA,sha256=6ULy_R-nnswf1Oa3bKMfgIZePm6ZrHrOil7rUjdWx4I,13190
|
|
37
|
+
lifx_emulator-1.0.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
38
|
+
lifx_emulator-1.0.0.dist-info/entry_points.txt,sha256=R9C_K_tTgt6yXEmhzH4r2Yx2Tu1rLlnYzeG4RFUVzSc,62
|
|
39
|
+
lifx_emulator-1.0.0.dist-info/licenses/LICENSE,sha256=eBz48GRA3gSiWn3rYZAz2Ewp35snnhV9cSqkVBq7g3k,1832
|
|
40
|
+
lifx_emulator-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Copyright (c) 2025 Avi Miller <me@dje.li>
|
|
2
|
+
|
|
3
|
+
The Universal Permissive License (UPL), Version 1.0
|
|
4
|
+
|
|
5
|
+
Subject to the condition set forth below, permission is hereby granted to any
|
|
6
|
+
person obtaining a copy of this software, associated documentation and/or data
|
|
7
|
+
(collectively the "Software"), free of charge and under any and all copyright
|
|
8
|
+
rights in the Software, and any and all patent rights owned or freely
|
|
9
|
+
licensable by each licensor hereunder covering either (i) the unmodified
|
|
10
|
+
Software as contributed to or provided by such licensor, or (ii) the Larger
|
|
11
|
+
Works (as defined below), to deal in both
|
|
12
|
+
|
|
13
|
+
(a) the Software, and
|
|
14
|
+
(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
|
|
15
|
+
one is included with the Software (each a "Larger Work" to which the Software
|
|
16
|
+
is contributed by such licensors),
|
|
17
|
+
|
|
18
|
+
without restriction, including without limitation the rights to copy, create
|
|
19
|
+
derivative works of, display, perform, and distribute the Software and make,
|
|
20
|
+
use, sell, offer for sale, import, export, have made, and have sold the
|
|
21
|
+
Software and the Larger Work(s), and to sublicense the foregoing rights on
|
|
22
|
+
either these or other terms.
|
|
23
|
+
|
|
24
|
+
This license is subject to the following condition:
|
|
25
|
+
The above copyright notice and either this complete permission notice or at
|
|
26
|
+
a minimum a reference to the UPL must be included in all copies or
|
|
27
|
+
substantial portions of the Software.
|
|
28
|
+
|
|
29
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
30
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
31
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
32
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
33
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
34
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
35
|
+
SOFTWARE.
|