UNPKG

homebridge-philips-hue-sync-box

Version:
377 lines (314 loc) 24.3 kB
<p align="center"> <img src="https://github.com/homebridge/branding/raw/latest/logos/homebridge-wordmark-logo-vertical.png" width="150"> </p> <h1 align="center">Homebridge Philips Hue Sync Box</h1> <p align="center">Bring your Philips Hue Sync Box into Apple HomeKit.</p> <p align="center"> [![npm version](https://badgen.net/npm/v/homebridge-philips-hue-sync-box?color=purple&icon=npm&label)](https://www.npmjs.com/package/homebridge-philips-hue-sync-box) [![npm beta version](https://badgen.net/npm/v/homebridge-philips-hue-sync-box/beta?color=purple&icon=npm&label=beta)](https://www.npmjs.com/package/homebridge-philips-hue-sync-box) [![npm downloads](https://badgen.net/npm/dw/homebridge-philips-hue-sync-box?color=purple&icon=npm&label)](https://www.npmjs.com/package/homebridge-philips-hue-sync-box) [![GitHub Stars](https://badgen.net/github/stars/jabrown93/homebridge-philips-hue-sync-box?color=cyan&icon=github)](https://github.com/jabrown93/homebridge-philips-hue-sync-box) [![Build](https://img.shields.io/github/actions/workflow/status/jabrown93/homebridge-philips-hue-sync-box/build.yaml?label=build)](https://github.com/jabrown93/homebridge-philips-hue-sync-box/actions/workflows/build.yaml) [![CodeQL](https://img.shields.io/github/actions/workflow/status/jabrown93/homebridge-philips-hue-sync-box/codeql.yaml?label=CodeQL)](https://github.com/jabrown93/homebridge-philips-hue-sync-box/actions/workflows/codeql.yaml) [![Release](https://img.shields.io/github/v/release/jabrown93/homebridge-philips-hue-sync-box)](https://github.com/jabrown93/homebridge-philips-hue-sync-box/releases) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) </p> A [Homebridge](https://homebridge.io) plugin that exposes the [Philips Hue Sync Box](https://www.philips-hue.com/en-us/p/hue-play-hdmi-sync-box/8719514440996) to Apple HomeKit, so you can turn syncing on/off, switch inputs, change modes, and automate it alongside the rest of your smart home. ## Features - **Base accessory** — expose the Sync Box as a lightbulb (on/off + brightness) or a plain switch (on/off). - **Power switch** — an optional, separate switch that toggles the box between passthrough and powersave. - **TV accessories** (opt-in, one per behavior) — each appears in the Apple TV remote widget and iOS Control Center: - **HDMI TV** — switch inputs. - **Mode TV** — switch between `video`, `music`, and `game`. - **Intensity TV** — switch between `subtle`, `moderate`, `high`, and `intense`. - **Entertainment TV** — switch the active Hue entertainment area. - Each TV accessory optionally exposes its own integrated lightbulb for brightness control. - **HTTP API** — an optional local API for scripting and HomeKit Shortcuts automations. - **Multiple Sync Boxes** — run one plugin instance per box, each with its own accessories. > [!IMPORTANT] > TV accessories are published as _external_ accessories and must be added to HomeKit manually — Homebridge logs the pairing PIN (the same one used for the main bridge). ## Table of Contents - [Installation](#installation) - [Requirements](#requirements) - [Install the Plugin](#install-the-plugin) - [Get a Sync Box Access Token](#get-a-sync-box-access-token) - [Running Multiple Sync Boxes](#running-multiple-sync-boxes) - [Configuration](#configuration) - [HTTP API](#http-api) - [GET /state](#get-state) - [POST /state](#post-state) - [Development](#development) - [Getting Help](#getting-help) - [Acknowledgments](#acknowledgments) ## Installation ### Requirements - Homebridge `^1.8.0` or `^2.0.0-beta.0` - Node.js `^22.12.0` or `^24.11.0` - A Philips Hue Sync Box on the same network as Homebridge ### Install the Plugin **Using Homebridge UI (recommended)** 1. Open the [Homebridge UI](https://github.com/homebridge/homebridge/wiki/Install-Homebridge-on-macOS#complete-login-to-the-homebridge-ui). 2. Go to the **Plugins** tab, search for `homebridge-philips-hue-sync-box`, and install it. 3. Get a Sync Box access token as described [below](#get-a-sync-box-access-token). 4. Configure the plugin from the Homebridge Config UI. **Manual** 1. Install with `hb-service add homebridge-philips-hue-sync-box`, or `npm i -g homebridge-philips-hue-sync-box` if you're not using `hb-service`. 2. Get a Sync Box access token as described [below](#get-a-sync-box-access-token). 3. Add the platform to Homebridge's `config.json`, see [Configuration](#configuration). ### Get a Sync Box Access Token The plugin authenticates with the Sync Box using a token you generate once via its local API: 1. Make sure the Sync Box is powered on and synchronization is stopped. 2. Send an HTTP `POST` to `https://<SYNC-BOX-IP>/api/v1/registrations` with a JSON body of `{ "appName": "homebridge", "instanceName": "homebridge" }`. 3. The first response will be `{ "code": 16, "message": "Invalid State" }` — this is expected. 4. Within 5 seconds, press and hold the button on the Sync Box until the LED turns green, then release it immediately. It will switch back to white. 5. Within 5 seconds of the LED turning green, send the exact same `POST` request again. 6. The response now contains an `accessToken` string — save it for your plugin configuration. One way to do this from a terminal: ```shell curl -k -H "Content-Type: application/json" \ -X POST -d '{"appName": "homebridge", "instanceName": "homebridge"}' \ https://<SYNC-BOX-IP>/api/v1/registrations ``` You can also use a tool like [Postman](https://www.postman.com/): set the method to `POST`, the URL to `https://<SYNC-BOX-IP>/api/v1/registrations`, and the body to raw JSON containing `{ "appName": "homebridge", "instanceName": "homebridge" }`. If you hit a certificate error, disable SSL certificate verification in Postman's settings. Once you have a token, you can validate it with: ```shell curl -k -H "Authorization: Bearer <ACCESS-TOKEN>" https://<SYNC-BOX-IP>/api/v1/ ``` See the [official Hue Sync Box API documentation](https://developers.meethue.com/develop/hue-entertainment/hue-hdmi-sync-box-api/#Getting%20Started) for more detail (a free developer account is required). > [!NOTE] > This plugin has no control over how the Sync Box issues or validates tokens. Please don't open issues about "Invalid Token" errors — they will be closed without action. ### Running Multiple Sync Boxes Each Sync Box needs its own plugin instance, added as a separate entry under `platforms` in `config.json`, each with a unique `uuidSeed`: ```json5 { // rest of config platforms: [ { platform: 'PhilipsHueSyncBoxPlatform', name: 'LivingRoomPhilipsHueSyncBoxPlatform', syncBoxIpAddress: '<SYNC-BOX-1-IP-ADDRESS>', syncBoxApiAccessToken: '<SYNC-BOX-1-ACCESS-TOKEN>', uuidSeed: 'LivingRoom', // rest of config }, { platform: 'PhilipsHueSyncBoxPlatform', name: 'BedroomPhilipsHueSyncBoxPlatform', syncBoxIpAddress: '<SYNC-BOX-2-IP-ADDRESS>', syncBoxApiAccessToken: '<SYNC-BOX-2-ACCESS-TOKEN>', uuidSeed: 'Bedroom', // rest of config }, ], } ``` - `uuidSeed` must be unique per Sync Box; it may be left empty (`""`) for at most one instance. - `name` should also be unique per instance — it makes the logs easier to follow. > [!WARNING] > Changing `uuidSeed` on an existing setup removes and recreates every accessory for that instance. HomeKit treats them as brand new, so you'll need to re-add them (including any automations or room assignments). Only set it if you're running more than one Sync Box. ## Configuration | Name | Description | Type | Default | Required | Allowed Values | | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------- | -------- | --------------------------------------------- | | `syncBoxIpAddress` | IP address of your Philips Hue Sync Box. | string | | Yes | | | `syncBoxApiAccessToken` | Access token obtained during [registration](#get-a-sync-box-access-token). | string | | Yes | | | `defaultOnMode` | Mode used when switching the Sync Box on via HomeKit. | string | `video` | No | `video`, `music`, `game`, `lastSyncMode` | | `defaultOffMode` | Mode used when switching the Sync Box off via HomeKit. | string | `passthrough` | No | `powersave`, `passthrough` | | `baseAccessory` | Type of the primary Sync Box accessory. `none` exposes no base accessory. | string | `lightbulb` | No | `lightbulb`, `switch`, `none` | | `powerSwitchAccessory` | Adds a separate switch that toggles passthrough (on) vs. powersave (off), independent of `baseAccessory`. | boolean | `false` | No | | | `tvAccessory` | Enables a TV accessory for switching HDMI inputs. | boolean | `false` | No | | | `tvAccessoryConfiguredName` | Custom name for the HDMI TV accessory. | string | | No | | | `tvAccessoryType` | Icon shown for the HDMI TV accessory in the Home app. | string | `tv` | No | `tv`, `settopbox`, `tvstick`, `audioreceiver` | | `tvAccessoryLightbulb` | Adds an integrated lightbulb to the HDMI TV accessory. | boolean | `false` | No | | | `modeTvAccessory` | Enables a TV accessory for switching modes (`video`, `music`, `game`). | boolean | `false` | No | | | `modeTvAccessoryConfiguredName` | Custom name for the Mode TV accessory. | string | | No | | | `modeTvAccessoryType` | Icon shown for the Mode TV accessory in the Home app. | string | `tv` | No | `tv`, `settopbox`, `tvstick`, `audioreceiver` | | `modeTvAccessoryLightbulb` | Adds an integrated lightbulb to the Mode TV accessory. | boolean | `false` | No | | | `intensityTvAccessory` | Enables a TV accessory for switching intensity (`subtle`, `moderate`, `high`, `intense`). | boolean | `false` | No | | | `intensityTvAccessoryConfiguredName` | Custom name for the Intensity TV accessory. | string | | No | | | `intensityTvAccessoryType` | Icon shown for the Intensity TV accessory in the Home app. | string | `tv` | No | `tv`, `settopbox`, `tvstick`, `audioreceiver` | | `intensityTvAccessoryLightbulb` | Adds an integrated lightbulb to the Intensity TV accessory. | boolean | `false` | No | | | `entertainmentTvAccessory` | Enables a TV accessory for switching the active Hue entertainment area. | boolean | `false` | No | | | `entertainmentTvAccessoryConfiguredName` | Custom name for the Entertainment TV accessory. | string | | No | | | `entertainmentTvAccessoryType` | Icon shown for the Entertainment TV accessory in the Home app. | string | `tv` | No | `tv`, `settopbox`, `tvstick`, `audioreceiver` | | `entertainmentTvAccessoryLightbulb` | Adds an integrated lightbulb to the Entertainment TV accessory. | boolean | `false` | No | | | `treatPassthroughAsOffForTv` | When enabled, TV accessories show as off in passthrough mode instead of on. | boolean | `false` | No | | | `updateIntervalInSeconds` | Polling interval, in seconds, for reading Sync Box state. | integer | `5` | No | | | `uuidSeed` | Unique identifier for this instance when running [multiple Sync Boxes](#running-multiple-sync-boxes). Leave empty for a single Sync Box. | string | | No | | | `apiServerEnabled` | Enables the [HTTP API](#http-api). | boolean | `false` | No | | | `apiServerPort` | Port the HTTP API listens on. Change this if the port is already in use. | integer | `40220` | No | | | `apiServerToken` | Token required in the `Authorization` header of every API request. Must be at least 32 characters long. Generate one with e.g. `openssl rand -hex 32` &mdash; do not reuse the example value below. Required if the API is enabled. | string | | No | | <details> <summary>Full example config.json</summary> ```json { "platforms": [ { "platform": "PhilipsHueSyncBoxPlatform", "syncBoxIpAddress": "<SYNC-BOX-IP-ADDRESS>", "syncBoxApiAccessToken": "<ACCESS-TOKEN>", "defaultOnMode": "video", "defaultOffMode": "passthrough", "baseAccessory": "lightbulb", "powerSwitchAccessory": false, "tvAccessory": false, "tvAccessoryConfiguredName": "Sync Box Input", "tvAccessoryType": "tv", "tvAccessoryLightbulb": false, "modeTvAccessory": false, "modeTvAccessoryConfiguredName": "Sync Box Mode", "modeTvAccessoryType": "tv", "modeTvAccessoryLightbulb": false, "intensityTvAccessory": false, "intensityTvAccessoryConfiguredName": "Sync Box Intensity", "intensityTvAccessoryType": "tv", "intensityTvAccessoryLightbulb": false, "entertainmentTvAccessory": false, "entertainmentTvAccessoryConfiguredName": "Sync Box Area", "entertainmentTvAccessoryType": "tv", "entertainmentTvAccessoryLightbulb": false, "treatPassthroughAsOffForTv": false, "updateIntervalInSeconds": 5, "uuidSeed": "livingroom", "apiServerEnabled": false, "apiServerPort": 40220, "apiServerToken": "<A-LONG-RANDOM-SECRET-AT-LEAST-32-CHARS>" } ] } ``` </details> Each TV accessory also supports the iOS remote widget: | Remote control | Action | | --------------- | ----------------- | | Up / Down | Change brightness | | Left / Right | Change intensity | | Select (center) | Toggle mode | | Info button | Toggle HDMI input | | Play / Pause | Toggle on/off | ## HTTP API When `apiServerEnabled` is `true`, the plugin exposes a small local HTTP API for automating the Sync Box outside of HomeKit — handy for HomeKit Shortcuts, which can call arbitrary HTTP endpoints from an automation. ``` http://<YOUR-HOST-IP-ADDRESS>:<apiServerPort> ``` Every request must include the configured token in the `Authorization` header: ``` Authorization: <YOUR-TOKEN> ``` ### GET /state Returns the current state of the Sync Box as JSON: ```json { "hue": { "bridgeUniqueId": "ID1", "bridgeIpAddress": "192.168.1.2", "groupId": "1", "groups": { "1": { "name": "Living Room TV area", "numLights": 1, "active": true, "owner": "HueSyncBox (ID2)" }, "2": { "name": "Bedroom TV area", "numLights": 2, "active": false } }, "connectionState": "streaming" }, "execution": { "mode": "video", "syncActive": true, "hdmiActive": true, "hdmiSource": "input4", "hueTarget": "1", "brightness": 200, "lastSyncMode": "video", "video": { "intensity": "moderate", "backgroundLighting": true }, "game": { "intensity": "intense", "backgroundLighting": false }, "music": { "intensity": "high", "palette": "melancholicEnergetic" }, "preset": null } } ``` ### POST /state Sets Sync Box state. The body accepts any subset of the following: ```json5 { hue: { bridgeUniqueId: 'ID1', bridgeIpAddress: '192.168.1.2', groupId: '1', groups: { '12345678-be8e-4866-adce-ff3800aca123': { name: 'Living Room TV area', numLights: 1, active: true, owner: 'HueSyncBox (ID2)', }, '56169ef5-be8e-4866-adce-ff3800aca35e': { name: 'Bedroom TV area', numLights: 2, active: false, }, }, connectionState: 'streaming', }, execution: { mode: 'video', syncActive: true, hdmiActive: true, hdmiSource: 'input4', // hueTarget must be a valid ID from hue.groups. Any other value causes an error. hueTarget: '12345678-be8e-4866-adce-ff3800aca123', brightness: 200, lastSyncMode: 'video', video: { intensity: 'moderate', backgroundLighting: true, }, game: { intensity: 'intense', backgroundLighting: false, }, music: { intensity: 'high', palette: 'melancholicEnergetic', }, preset: null, }, } ``` ## Development This plugin is written in TypeScript and targets ES2022 modules. See [`CLAUDE.md`](./CLAUDE.md) for a deeper architecture overview. ```shell npm install # install dependencies npm run build # compile src/ -> dist/ npm link # link the plugin to your global Homebridge install npm run watch # rebuild and restart Homebridge on changes npm test # run the unit test suite ``` `npm run watch` runs `homebridge -U ./test/hbConfig -I -D` against the sample config in [`test/hbConfig`](./test/hbConfig). Before running it for the first time, copy `test/hbConfig/config-template.json` to `test/hbConfig/config.json` and fill in your Sync Box details (the `setup-config` script does this automatically if the file doesn't exist yet). Other useful checks: ```shell npm run typecheck # type-check without emitting files npm run lint # lint TypeScript sources npm run format # format with Prettier ``` ## Getting Help - Check the [Homebridge basic troubleshooting guide](https://github.com/homebridge/homebridge/wiki/Basic-Troubleshooting). - Still stuck? Open an [issue](https://github.com/jabrown93/homebridge-philips-hue-sync-box/issues/new/choose) with as much detail as the template asks for. - Have a feature idea? Open a [feature request](https://github.com/jabrown93/homebridge-philips-hue-sync-box/issues/new?template=feature-request.md). - Want to contribute code or docs? See [CONTRIBUTING.md](./CONTRIBUTING.md). ## Acknowledgments This plugin was originally developed by [Lukas Rögner](https://github.com/lukasroegner).