hue-entertainment
Async Python client for the Philips Hue Entertainment streaming API.
It pairs with a Hue bridge, discovers entertainment areas, and streams colour frames to the
lights over DTLS 1.2 PSK using the HueStream protocol with minimal latency. It works
with both the Hue V2 ("square") bridge and the Hue Pro bridge.
The DTLS 1.2 PSK handshake, record layer and HueStream encoder are pure Python on top of
cryptography — no openssl subprocess, no C bindings, no
other DTLS dependency. Blocking socket I/O is confined to a dedicated sender thread, so it
never blocks your asyncio event loop.
It powers the Hue Entertainment plugin (the Sendspin bridge) in Music Assistant and the ambilight-hue-pro-bridge.
What it provides
- Bridge discovery — find Hue bridges on the LAN via mDNS (
discover_bridges). - Pairing — create an application key and the DTLS client key (
HueEntertainmentAPI.pair). - Areas — list a bridge's entertainment configurations with their channels and positions.
- Streaming — start/stop an entertainment stream and push per-channel colours at up to ~50 Hz.
EntertainmentSession— a high-level async facade that opens the stream on demand, runs the blocking DTLS work in an executor, enforces the bridge's single-active-stream constraint, and tears the stream down after inactivity.- Works with the V2 and Pro bridges; dependencies are
aiohttp,cryptographyandzeroconf.
What you can build with it
Anything that drives Hue lights from a fast colour source — screen / Ambilight sync, music visualisers, games, rich notifications, or your own virtual bridge — without the Hue Sync hardware.
Planned extensions
- HueStream v1 framing and the CIE xy colour space (currently HueStream v2 / RGB).
Install
pip install hue-entertainment
Requires Python 3.11+. Runtime dependencies: aiohttp, cryptography, zeroconf.
Usage
import asyncio
from hue_entertainment import EntertainmentSession, HueEntertainmentAPI, LightColorCommand
async def main() -> None:
host = "192.168.1.50"
# One-time pairing (press the bridge link button first):
api = HueEntertainmentAPI(host)
creds = await api.pair() # {"username": ..., "clientkey": ...}
await api.close()
# Stream to an entertainment area:
session = EntertainmentSession(host, creds["username"], creds["clientkey"])
areas = await session.get_entertainment_areas()
area = areas[0]
await session.start(area.id) # activates the area + opens the DTLS stream
try:
# Drive frames at your own rate (~25-50 Hz). One command per channel.
for _ in range(250):
session.send(
[LightColorCommand(channel_id=ch.channel_id, red=65535) for ch in area.channels]
)
await asyncio.sleep(1 / 50)
finally:
await session.aclose()
asyncio.run(main())
API
HueEntertainmentAPI(host, app_key=None)— low-level CLIP v2 wrapper:pair(),get_entertainment_areas(),start_entertainment(area_id),stop_entertainment(area_id),get_bridge_id(),close().HueDtlsStreamer()— low-level DTLS/HueStream streamer:connect(host, username, clientkey, area_id)(blocking — run in an executor),send_colors([...]),disconnect(),is_connected.EntertainmentSession(host, app_key, client_key, *, idle_timeout=10.0)— the recommended high-level facade: on-demandstart(area_id), non-blockingsend(...),stop()/aclose(), automatic idle teardown, and enforcement of the bridge's single-active-stream constraint. The blocking DTLS work runs in an executor for you.- Models —
EntertainmentArea,LightChannel,LightColorCommand.
LightColorCommand carries 16-bit RGB; the encoder emits the duplicated-byte HueStream v2
format and lets the bridge gamut-map per light.
Development
scripts/setup.sh
pre-commit run --all-files
pytest
License
Metadata
Release files for hue-entertainment 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| hue_entertainment-0.1.2.tar.gz | 29.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hue_entertainment-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 51.1 kB
Release files / hue_entertainment-0.1.2.tar.gz
| Download URL | hue_entertainment-0.1.2.tar.gz |
|---|---|
| Size | 29.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b292fd0fbb30493206ed4532cfdc2a80dc221c189ddd63e6dfe41a2d2a0e5eb0
|
|
BLAKE2b-256 checksum How to use checksums |
f67aae9d08cb774cbf7165e0d7c9fb246cb5b7a0f0f5d7e067c3cdfdbb7c6181
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / hue_entertainment-0.1.2-py3-none-any.whl
| Download URL | hue_entertainment-0.1.2-py3-none-any.whl |
|---|---|
| Size | 22.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8a6d916132bd2be30e15a020ec55b0eee56ae5e9483775eace43a8ebf2fb49f9
|
|
BLAKE2b-256 checksum How to use checksums |
f7a03705402bf6321e7792e1f0131d42250276b4df04e98c6b082d2707e156be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Security for hue-entertainment 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.