Discovering Devices¶
dlight-client locates lamps on your network using a UDP broadcast probe — the same mechanism used by the dLight mobile app and the dlight-hass Home Assistant integration.
How it works¶
discover_devices() opens a UDP listener on a response port, then sends a broadcast magic packet to the discovery port. Lamps that receive it reply with a JSON datagram containing their identity information. After the discovery window closes, results are deduplicated by IP address and returned.
Usage¶
from dlightclient import discover_devices
devices = await discover_devices(
discovery_duration=3.0, # how long to listen (seconds)
response_port=9487, # port lamps reply to
discovery_port=9478, # port lamps listen on
broadcast_address="255.255.255.255",
)
All parameters are optional — the defaults work on a typical home network.
| Parameter | Default | Description |
|---|---|---|
discovery_duration |
3.0 |
Seconds to wait for responses. Increase on slow networks. |
response_port |
9487 |
UDP port this machine listens on for device replies. |
discovery_port |
9478 |
UDP port the discovery probe is sent to. |
broadcast_address |
"255.255.255.255" |
Limited broadcast; works on flat home networks. |
Returned data¶
Each entry in the returned list is a dict with these keys:
| Key | Type | Description |
|---|---|---|
ip_address |
str |
Assigned by the discovery listener — the lamp's IP. |
deviceId |
str |
Unique device identifier (pass to DLightDevice). |
deviceModel |
str |
Hardware model string. |
swVersion |
str |
Firmware version. |
hwVersion |
str |
Hardware revision. |
macAddress |
str |
MAC address. |
Only ip_address and deviceId are required to control a lamp. The rest are useful for device management UIs.
Example: quick scan¶
import asyncio
from dlightclient import discover_devices
async def scan():
found = await discover_devices(discovery_duration=5.0)
if not found:
print("No lamps found — are they on the same subnet?")
return
for d in found:
print(f" {d['deviceModel']} @ {d['ip_address']} (id={d['deviceId']})")
asyncio.run(scan())
Firewall and permissions¶
On Linux, binding a UDP socket to port 9487 may require that the port is not already in use by another process. If you get a PermissionError, check that no other instance of the client (or a Home Assistant integration) is already running a listener on that port.
Same subnet required
UDP broadcast does not cross router boundaries. Your machine and your lamps must be on the same Layer-2 segment. If you use VLANs or a guest Wi-Fi network, discovery will not find lamps on the other segment.
mDNS / Zeroconf¶
UDP broadcast discovery is the current implementation. Support for mDNS / Zeroconf (industry-standard discovery) is tracked as DL-004 on the Roadmap and will be additive — existing code using discover_devices() will not need changes.