Home Assistant custom integration for Celebright (CLC-03) holiday-lights controllers, plus a standalone reference client. Local-only, reverse-engineered from the device's WebSocket protocol — talks directly to the controller on the LAN with no vendor cloud. - select entity exposes the device's saved scenes plus an off option - firmware-v2 protocol (savedScenes); getSystemState drives availability and the active scene, scene library fetched best-effort and cached - WS connect/recv/send wrapped in asyncio timeouts so a silent device can't blow past HA's setup deadline - config flow prompts for the controller IP; no credentials involved - docs/PROTOCOL.md: full v2 WebSocket protocol and device behaviors Migrated from the private dfritz/celebright with history dropped and internal site references removed. MIT-licensed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F6B8b3iYNv6QUftK2FDfYb
218 lines
6.8 KiB
Markdown
218 lines
6.8 KiB
Markdown
# Celebright Controller
|
|
|
|
Python-based controller for Celebright holiday lights systems.
|
|
This implementation is based on reverse-engineering the network protocol from packet capture analysis.
|
|
|
|
## Project Components
|
|
|
|
This repository contains two main components:
|
|
|
|
1. **Home Assistant Integration** (`custom_components/celebright/`) — the maintained, **firmware-v2** custom component. This is the supported implementation.
|
|
2. **Standalone Python Controller** (`celebright_controller.py`) — the original **v1** reverse-engineering reference/demo. It does **not** work against firmware 2.x (the `getPresetsAndEventsPaginated`/`loadPreset` topics it uses were removed); kept for historical reference.
|
|
|
|
> **Full protocol & operations reference: [`docs/PROTOCOL.md`](docs/PROTOCOL.md)** — v2 WebSocket topics, device behaviors, deploy, and access gotchas.
|
|
|
|
## Features
|
|
|
|
### Standalone Controller
|
|
|
|
- **Discovery**: Automatically discovers Celebright controllers on the local network via UDP broadcast
|
|
- **WebSocket Communication**: Establishes WebSocket connection for real-time control
|
|
- **Scene Management**: Lists and selects available lighting scenes/presets
|
|
- **Power Control**: Turn off lights and disable schedules
|
|
|
|
### Home Assistant Integration
|
|
|
|
- **Automatic Discovery**: Finds controllers on your network automatically
|
|
- **Select Entity**: Drop-down selector for choosing presets
|
|
- **Native Integration**: Full Home Assistant device integration
|
|
- **Automation Support**: Use in automations, scripts, and scenes
|
|
|
|
## Requirements
|
|
|
|
- Python 3.7+
|
|
- `websockets` library
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
pip install -r requirements.txt
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Basic Usage
|
|
|
|
Run the main script to execute a complete demo sequence:
|
|
|
|
```bash
|
|
python3 celebright_controller.py
|
|
```
|
|
|
|
This will:
|
|
1. Discover the Celebright controller on your network
|
|
2. Establish a WebSocket connection
|
|
3. List all available scenes
|
|
4. Load a couple of example scenes
|
|
5. Turn off the system
|
|
6. Disconnect
|
|
|
|
### Using as a Library
|
|
|
|
```python
|
|
import asyncio
|
|
from celebright_controller import CelebrightController
|
|
|
|
async def control_lights():
|
|
controller = CelebrightController()
|
|
|
|
# Discover controller
|
|
device_info = controller.discover_controller()
|
|
if not device_info:
|
|
print("Controller not found")
|
|
return
|
|
|
|
# Connect
|
|
await controller.connect()
|
|
|
|
# Get available presets
|
|
presets = await controller.get_presets()
|
|
|
|
# Load a specific preset
|
|
if presets:
|
|
await controller.load_preset(presets[0]['preset_uuid'])
|
|
|
|
# Turn off
|
|
await controller.turn_off()
|
|
|
|
# Disconnect
|
|
await controller.disconnect()
|
|
|
|
asyncio.run(control_lights())
|
|
```
|
|
|
|
### Home Assistant Integration
|
|
|
|
For detailed Home Assistant integration instructions, see [custom_components/celebright/README.md](custom_components/celebright/README.md).
|
|
|
|
#### Quick Start
|
|
|
|
1. Copy the `custom_components/celebright` folder to your Home Assistant's `custom_components` directory
|
|
2. Restart Home Assistant
|
|
3. Go to Settings > Devices & Services > Add Integration
|
|
4. Search for "Celebright"
|
|
5. Follow the configuration flow
|
|
|
|
#### Deployment via Makefile
|
|
|
|
The project includes a Makefile for easy deployment to Home Assistant:
|
|
|
|
```bash
|
|
make deploy
|
|
```
|
|
|
|
This will:
|
|
- Set up the remote directory with correct permissions
|
|
- Deploy the integration to your Home Assistant instance
|
|
- Remind you to restart Home Assistant
|
|
|
|
Configure the Makefile variables for your environment:
|
|
- `REMOTE_HOST`: Your Home Assistant hostname or IP
|
|
- `REMOTE_PATH`: Path to Home Assistant's custom_components directory
|
|
- `REMOTE_USER`: SSH user for deployment
|
|
|
|
## Protocol Details
|
|
|
|
> The current **firmware-v2** protocol is documented in full in
|
|
> [`docs/PROTOCOL.md`](docs/PROTOCOL.md). The sections below describe the
|
|
> **original v1** protocol the standalone controller targets, retained for
|
|
> historical reference.
|
|
|
|
Based on packet capture analysis of `celebright-full.pcapng`:
|
|
|
|
### Discovery Process
|
|
- **Client sends**: UDP broadcast to port 49999 (discovery request with empty payload)
|
|
- **Client listens**: On port 51234 for responses
|
|
- **Controller responds**: From port 49999 to client's port 51234 with JSON payload containing:
|
|
- Model name
|
|
- Device ID
|
|
- Firmware version
|
|
- Number of LEDs
|
|
- LED configuration
|
|
|
|
### WebSocket Communication
|
|
- **Endpoint**: `ws://<device_ip>:80/ws`
|
|
- **Message Format**: JSON with `topic` and `message` fields
|
|
|
|
```json
|
|
{
|
|
"topic": "command_name",
|
|
"message": {
|
|
// command parameters
|
|
}
|
|
}
|
|
```
|
|
|
|
### Available Commands
|
|
|
|
| Topic | Description | Parameters |
|
|
|-------|-------------|------------|
|
|
| `getPresetsAndEventsPaginated` | Get list of available scenes | None |
|
|
| `loadPreset` | Load/activate a specific scene | `presetUuid`: UUID of preset |
|
|
| `setTurnOffAndDisableSchedule` | Turn off lights and disable schedule | None |
|
|
| `getSystemState` | Get current system state | None |
|
|
|
|
## Example Output
|
|
|
|
```
|
|
============================================================
|
|
STEP 1: DISCOVERY
|
|
============================================================
|
|
[Discovery] Listening for Celebright controller on UDP port 51234...
|
|
[Discovery] Found controller at 192.168.1.50
|
|
[Discovery] Model: CLC-03
|
|
[Discovery] Device ID: 123456789
|
|
[Discovery] Firmware: 1.41
|
|
[Discovery] Number of LEDs: 296
|
|
|
|
============================================================
|
|
STEP 2: WEBSOCKET CONNECTION
|
|
============================================================
|
|
[Connect] Connecting to ws://192.168.1.50:80/ws...
|
|
[Connect] WebSocket connection established
|
|
|
|
============================================================
|
|
STEP 3: LIST AVAILABLE SCENES
|
|
============================================================
|
|
[Presets] Requesting preset list...
|
|
[Receive] Response topic: presetsPage
|
|
[Presets] Found 12 presets:
|
|
1. Halloween Twinkle - Orange, Purple and Green twinkle
|
|
UUID: 3956e504-aafa-4f1c-8ad7-b00fb2381baa
|
|
2. Warm White Solid - Warm White lights
|
|
UUID: 6d2bdc6e-b015-4903-b8e5-5f7fc28c156a
|
|
...
|
|
```
|
|
|
|
## Network Requirements
|
|
|
|
- The controller must be on the same local network
|
|
- UDP port 49999 must be accessible for sending discovery broadcasts
|
|
- UDP port 51234 must be accessible for receiving discovery responses
|
|
- TCP port 80 must be accessible for WebSocket communication
|
|
|
|
## Limitations
|
|
|
|
- The discovery process requires the ability to send UDP broadcasts on the local network
|
|
- Broadcast discovery may not work across network segments or VLANs without proper routing
|
|
- If broadcast discovery fails, you may need to specify the controller IP directly (feature could be added)
|
|
- The script currently only handles the basic protocol commands observed in the packet capture
|
|
|
|
## License
|
|
|
|
MIT — see [LICENSE](LICENSE).
|
|
|
|
This is an unofficial, reverse-engineered implementation based on local network
|
|
traffic analysis of the vendor device. It is not affiliated with or endorsed by
|
|
Celebright. Use at your own risk.
|