A Python client for the dLight smart lamp API.
Project description
python-dlight-client - Async Python Client for dLight API
This Python package provides an asynchronous (asyncio) client library for discovering and controlling dLight smart lamps over a local Wi-Fi network. It allows you to find dLight devices using UDP broadcasts and control them using TCP commands.
Table of Contents
Features
- Asynchronous: Built with
asynciofor efficient, non-blocking network operations. - Device Discovery: Find dLight devices on your local network using UDP broadcast (
discover_devices). - High-Level Device Control: An easy-to-use
DLightDeviceclass for object-oriented control of a specific lamp. - Performance Optimized:
- Persistent TCP Connections: Reuse connections for sequential commands to reduce latency (
persistent=True). - Connection Concurrency Safety: Automatic per-device locking ensures multiple concurrent tasks can share a client safely.
- Idle Timeout: Stale connections are automatically closed and refreshed after a period of inactivity (default 60s).
- State Caching & Optimistic Updates: Internal cache in
DLightDevicereduces redundant network queries and provides immediate feedback.
- Persistent TCP Connections: Reuse connections for sequential commands to reduce latency (
- Automatic Retries: Opt-in retries with exponential backoff (
max_retries,retry_backoff) for transient network failures. Protocol errors are never retried. - Optional TLS: Pass
ssl=Trueor a customssl.SSLContextto encrypt the TCP channel (CLI:--ssl,--insecure). - Developer Friendly:
- Structured Models: Use
TypedDictmodels (DeviceState,DeviceInfo, etc.) for better IDE support and type safety.
- Structured Models: Use
- State Control:
- Turn On/Off
- Set Brightness (0-100%)
- Set Color Temperature (2600K-6000K)
- Device Query:
- Get the current state (power, brightness, color).
- Get device information (model, firmware version, etc.).
- Wi-Fi Provisioning: Send Wi-Fi credentials to a device in SoftAP mode for initial setup.
- Robust Communication: Handles the dLight TCP protocol (4-byte length prefix + JSON payload) and includes timeouts.
- Custom Error Handling: Specific exceptions for network and device errors (e.g.,
DLightTimeoutError,DLightResponseError). - Command-Line Tool: A convenient CLI for quick discovery and interaction.
Prerequisites
- A dLight device connected to your local Wi-Fi network (or in SoftAP mode for initial setup).
- Python 3.9 through 3.13 (officially supported).
Installation
pip install dlight-client
Usage
You can use this package as a library in your Python projects or via the included command-line tool.
As a Library
Using the library typically involves two steps: discovering devices to get their IP address and ID, and then creating a DLightDevice instance to interact with a specific lamp.
1. Discovering Devices
First, use the discover_devices function to find lamps on your network.
import asyncio
from dlightclient import discover_devices
async def find_devices():
print("--- Discovering Devices ---")
devices = await discover_devices(discovery_duration=3.0)
for i, device_info in enumerate(devices):
ip = device_info.get('ip_address')
dev_id = device_info.get('deviceId')
print(f" Device {i+1}: ID={dev_id}, IP={ip}")
if __name__ == "__main__":
asyncio.run(find_devices())
2. Controlling a Device
Once you have the ip_address and deviceId, you can use the high-level DLightDevice class for intuitive control.
import asyncio
from dlightclient import AsyncDLightClient, DLightDevice
async def run_example():
# The client handles the underlying TCP communication
client = AsyncDLightClient()
# The device object is the high-level interface
device = DLightDevice(ip_address="192.168.1.123", device_id="DL12345", client=client)
# Simple control commands
await device.turn_on()
await device.set_brightness(75)
# State caching: get_state() returns cached value by default
state = await device.get_state()
print(f"Current Brightness (cached): {state.get('brightness')}%")
if __name__ == "__main__":
asyncio.run(run_example())
3. Performance Optimization
For applications that need to send many commands in a row, use Persistent Connections to eliminate connection setup overhead.
Persistence is enabled by the persistent=True constructor argument. The context
manager does not enable it; it only guarantees that all pooled connections are
closed on exit.
Option A: Context Manager (recommended)
from dlightclient import AsyncDLightClient, DLightDevice
async with AsyncDLightClient(persistent=True) as client:
device = DLightDevice(ip_address="192.168.1.123", device_id="DL12345", client=client)
# Both commands reuse the same TCP connection
await device.turn_on()
await device.set_brightness(50)
# All connections are closed when the block exits
Option B: Manual Lifecycle
client = AsyncDLightClient(persistent=True)
try:
... # perform operations
finally:
await client.close() # Explicitly close when finished
Changed in 1.6.0:
async with AsyncDLightClient()no longer implicitly enables persistence; passpersistent=Trueexplicitly.
For lossy Wi-Fi environments, enable retries — they apply only to transient network errors (timeouts, connection failures), never to protocol errors:
client = AsyncDLightClient(max_retries=2, retry_backoff=0.5) # waits 0.5s, then 1.0s
Using the Command-Line Tool (CLI)
The package includes a basic CLI for common operations.
# Discover all devices on the network
python -m dlightclient.cli --discover
# Interact with a specific device using a test sequence
python -m dlightclient.cli --ip 192.168.1.100 --id DL12345
API Overview
dlightclient.discovery.discover_devices: Uses UDP broadcast to find devices on the network.dlightclient.client.AsyncDLightClient: The low-level TCP client. Supportspersistent=True.dlightclient.device.DLightDevice: High-level class. Includes state caching automatically.dlightclient.exceptions: Custom exceptions hierarchy rooted inDLightError.
Architecture
For a deep dive into the library's layering, data flow, concurrency model, and wire protocol — aimed at contributors — see docs/ARCHITECTURE.md.
Development and Testing
-
Set up a virtual environment:
python -m venv .venv source .venv/bin/activate
-
Install in editable mode:
pip install -e .
-
Run tests:
python -m unittest discover tests/
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dlight_client-1.6.1.tar.gz.
File metadata
- Download URL: dlight_client-1.6.1.tar.gz
- Upload date:
- Size: 37.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eece3d0d3e517b0ae914c709a08a8b6cbd974689ad21c793e9dce231b0905d25
|
|
| MD5 |
8c28961cdd8662b6fb67b2b6eed07f36
|
|
| BLAKE2b-256 |
65ab408f79951678a991b2a4addfa03b8a3f15eae0193b9228145f05b57a3f39
|
Provenance
The following attestation bundles were made for dlight_client-1.6.1.tar.gz:
Publisher:
python-publish.yml on Irishsmurf/dlight-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dlight_client-1.6.1.tar.gz -
Subject digest:
eece3d0d3e517b0ae914c709a08a8b6cbd974689ad21c793e9dce231b0905d25 - Sigstore transparency entry: 1782559661
- Sigstore integration time:
-
Permalink:
Irishsmurf/dlight-client@359e688fec1796f02bfbd3c0caf22212409eda7c -
Branch / Tag:
refs/tags/v1.6.1 - Owner: https://github.com/Irishsmurf
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@359e688fec1796f02bfbd3c0caf22212409eda7c -
Trigger Event:
release
-
Statement type:
File details
Details for the file dlight_client-1.6.1-py3-none-any.whl.
File metadata
- Download URL: dlight_client-1.6.1-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05d75b8e591715782a4ce98d72b23768bada8d68f642e8f8967edec6a448e165
|
|
| MD5 |
abd53494ca96c9d5baa507cf81bafbc7
|
|
| BLAKE2b-256 |
ec699221c66af5e4248c6cfa0915ebbcc9d5de717d1ba2b73fb977693c5ae2b2
|
Provenance
The following attestation bundles were made for dlight_client-1.6.1-py3-none-any.whl:
Publisher:
python-publish.yml on Irishsmurf/dlight-client
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dlight_client-1.6.1-py3-none-any.whl -
Subject digest:
05d75b8e591715782a4ce98d72b23768bada8d68f642e8f8967edec6a448e165 - Sigstore transparency entry: 1782559747
- Sigstore integration time:
-
Permalink:
Irishsmurf/dlight-client@359e688fec1796f02bfbd3c0caf22212409eda7c -
Branch / Tag:
refs/tags/v1.6.1 - Owner: https://github.com/Irishsmurf
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@359e688fec1796f02bfbd3c0caf22212409eda7c -
Trigger Event:
release
-
Statement type: