# 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://: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.