This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Homebridge plugin for the Philips Hue Sync Box. It exposes the Sync Box to Apple HomeKit as various accessory types (lightbulbs, switches, TVs) and provides an optional HTTP API for automation. The plugin is written in TypeScript and uses ES2024 modules.
npm install # Install dependencies
npm run build # Compile TypeScript (src/ -> dist/)
npm run clean # Remove dist/ folder
npm link # Link plugin to global Homebridgenpm run typecheck # Type-check without emitting files
npm run lint # Lint TypeScript files
npm run lint:fix # Lint and auto-fix issues
npm run prettier # Check code formatting
npm run format # Format code with Prettiernpm run watch # Auto-compile and restart Homebridge on changes
# Uses test/hbConfig/ for config
# Runs: homebridge -U ./test/hbConfig -I -DBefore using npm run watch, ensure test/hbConfig/config.json exists. If not, copy from test/hbConfig/config-template.json.
npm run release # Build and run semantic-releasesrc/index.ts: Registers theHueSyncBoxPlatformwith Homebridge
src/platform.ts: MainHueSyncBoxPlatformclass implementingDynamicPlatformPlugin- Discovers and creates accessories based on config
- Manages accessory lifecycle (registration, restoration, removal)
- Polls Sync Box state on interval (default 5 seconds)
- Handles both regular platform accessories (lightbulb, switch) and external accessories (TVs)
src/lib/client.ts:SyncBoxClientclass- Communicates with Philips Hue Sync Box HTTPS API
- Uses async-lock to prevent concurrent requests
- Includes retry logic (3 retries with exponential backoff)
- Pins TLS connections to Philips's Sync Box CA (
src/lib/hsb-ca-cert.ts); hostname/CN verification is skipped since each box's cert CN is its device id, not its IP (seecreateSyncBoxAgent()) - Methods:
getState(),updateExecution(),updateHue()
src/state.ts: TypeScript interfaces for Sync Box API responsesState: Complete device stateExecution: Sync mode, brightness, HDMI source, intensityHue: Connected Hue bridge and entertainment groupsHdmi: HDMI input/output informationDevice: Device metadata and firmware info
All accessories extend SyncBoxDevice base class (src/accessories/base.ts):
src/accessories/lightbulb.ts: Exposes as HomeKit lightbulb (on/off, brightness)src/accessories/switch.ts: Exposes as HomeKit switch (on/off only)src/accessories/baseTv.ts: Abstract base for TV accessoriessrc/accessories/tv.ts: HDMI input switchingsrc/accessories/modeTv.ts: Mode switching (video/music/game)src/accessories/intensityTv.ts: Intensity switching (subtle/moderate/high/intense)src/accessories/entertainmentTv.ts: Entertainment area switching
TV Accessories:
- Published as external accessories (must be manually added to HomeKit)
- Support iOS remote widget controls
- Can have integrated lightbulb service for brightness control
- Category can be configured (tv, settopbox, tvstick, audioreceiver)
src/api-server.ts: Optional HTTP API for automation- GET
/state: Retrieve current Sync Box state - POST
/state: Update Sync Box state - Requires Authorization header with configured token
- Enabled via
apiServerEnabledconfig (default: false, port: 40220)
- GET
src/config.ts: TypeScript interface for plugin configurationconfig.schema.json: JSON schema for Homebridge Config UI
src/lib/constants.ts: Shared constants for accessory types and modes
Each Sync Box instance requires a unique uuidSeed value. Changing this value causes accessories to be recreated (not recommended unless needed). Leave empty for a single Sync Box.
- On modes:
video,music,game,lastSyncMode(configurable viadefaultOnMode) - Off modes:
passthrough,powersave(configurable viadefaultOffMode)
The platform polls the Sync Box every updateIntervalInSeconds (default: 5) to sync HomeKit state with device state. Updates are pushed to all registered accessories.
UUIDs are generated using api.hap.uuid.generate(kind + uuidSeed) where kind is the accessory type constant. This ensures stable UUIDs across restarts.
- Create new class extending
SyncBoxDeviceinsrc/accessories/ - Implement required abstract methods (
getServiceType(),update()) - Add constant for accessory type in
src/lib/constants.ts - Add config options to
config.tsandconfig.schema.json - Update
platform.ts:- Add device creation in
discoverAccessories() - Add case in
createDevice()switch statement
- Add device creation in
Use this.platform.client.updateExecution() or this.platform.client.updateHue() from accessories. The client handles locking, retries, and error logging.
Override handlePowerCharacteristicSet() or add new characteristic handlers. Always check current value to avoid unnecessary API calls.
- This is an ES2024 module project - use
.jsextensions in import statements - The plugin uses strict TypeScript mode (except
noImplicitAny: false) - Sync Box API uses certificates signed by Philips's Sync Box CA - the chain is validated but hostname verification is skipped (see
SyncBoxClient) - API requests are serialized via async-lock to prevent conflicts
- TV accessories are external and require manual HomeKit pairing
- The platform uses Homebridge's dynamic platform API for accessory management
- Pre-commit hooks run linting and formatting via husky and lint-staged