{"_id":"@artnet-bridge/protocol-hue","name":"@artnet-bridge/protocol-hue","dist-tags":{"latest":"0.0.1"},"versions":{"0.0.1":{"name":"@artnet-bridge/protocol-hue","version":"0.0.1","type":"module","description":"Philips Hue protocol adapter for ArtNet Bridge","main":"dist/esm/index.js","scripts":{"clean":"artnet-build clean","build":"artnet-build","build-clean":"artnet-build --clean","bundle":"node scripts/copy-web-assets.js"},"engines":{"node":">=22.13.0"},"repository":{"type":"git","url":"git+https://github.com/Apollon77/artnet-bridge.git"},"author":{"name":"Ingo Fischer"},"license":"MIT","bugs":{"url":"https://github.com/Apollon77/artnet-bridge/issues"},"homepage":"https://github.com/Apollon77/artnet-bridge","dependencies":{"@artnet-bridge/protocol":"0.0.1","express":"^5.2.1","node-dtls-client":"^1.1.1"},"devDependencies":{"@types/express":"^5.0.6","@types/node":"^22.0.0"},"publishConfig":{"access":"public"},"_id":"@artnet-bridge/protocol-hue@0.0.1","gitHead":"f385fba87fe9fc24f47490ac6c0e0fbe5dff9e8c","types":"./dist/esm/index.d.ts","_nodeVersion":"22.18.0","_npmVersion":"10.9.3","dist":{"integrity":"sha512-sBDdEeON/DgLALL97JipZBDTEg/N856qFcCRW4X784ZSv6y7I+Nm3XmAyJ4T8E2ZcQTPbaD5vS6b0KoEnznsFQ==","shasum":"49cfad02370bc293223aa50596414dff09d95581","tarball":"https://registry.npmjs.org/@artnet-bridge/protocol-hue/-/protocol-hue-0.0.1.tgz","fileCount":42,"unpackedSize":192658,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIAWXVF+4gIlgFt4/8Vg+SyDf97gHKxlhg9s2dFf0QFxjAiEAgIJlKM3B818lzogQaW36Xh/D1dB40Qnj4o0dlAeTnmk="}]},"_npmUser":{"name":"apollon77","email":"github@fischer-ka.de"},"directories":{},"maintainers":[{"name":"apollon77","email":"github@fischer-ka.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/protocol-hue_0.0.1_1774812251096_0.7004876726606879"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-29T19:24:10.983Z","0.0.1":"2026-03-29T19:24:11.237Z","modified":"2026-03-29T19:24:11.423Z"},"maintainers":[{"name":"apollon77","email":"github@fischer-ka.de"}],"description":"Philips Hue protocol adapter for ArtNet Bridge","homepage":"https://github.com/Apollon77/artnet-bridge","repository":{"type":"git","url":"git+https://github.com/Apollon77/artnet-bridge.git"},"author":{"name":"Ingo Fischer"},"bugs":{"url":"https://github.com/Apollon77/artnet-bridge/issues"},"license":"MIT","readme":"# @artnet-bridge/protocol-hue\n\nPhilips Hue protocol adapter for ArtNet Bridge. Supports both realtime entertainment streaming (DTLS) and standard REST API control via the Hue CLIP v2 API.\n\n## Discovery and Pairing\n\n### Discovery\n\nBridges are discovered using two methods (tried in parallel):\n- **mDNS** -- local network multicast query for `_hue._tcp.local`\n- **Meethue cloud** -- fallback via `https://discovery.meethue.com`\n\n```typescript\nimport { discoverBridges } from \"@artnet-bridge/protocol-hue\";\n\nconst bridges = await discoverBridges();\n// [{ id: \"001788...\", host: \"192.168.1.42\", name: \"Hue Bridge\", protocol: \"hue\", metadata: { ... } }]\n```\n\n### Pairing\n\nPairing uses the Hue link-button flow. Press the physical button on the bridge, then call:\n\n```typescript\nimport { pairWithBridge } from \"@artnet-bridge/protocol-hue\";\n\nconst result = await pairWithBridge(\"192.168.1.42\", \"artnet-bridge\", \"default\");\n// result.connection = { username: \"abc...\", clientkey: \"def...\" }\n```\n\nThe `username` authenticates REST API calls. The `clientkey` is the PSK for DTLS entertainment streaming.\n\n## Two Control Modes\n\n### Entertainment Mode (Realtime)\n\nDTLS streaming for low-latency color control of individual lights.\n\n- **Protocol**: DTLS 1.2 over UDP port 2100, cipher `TLS_PSK_WITH_AES_128_GCM_SHA256`\n- **Transmission rate**: continuous at ~50Hz (20ms interval), per Hue best practices\n- **Packet format**: HueStream v2 -- 16-byte header + 36-byte entertainment config UUID + 7 bytes per channel (channel ID + RGB16 big-endian)\n- **Always transmits**: sends current state every 20ms even when values have not changed (compensates for UDP packet loss)\n- **Bridge decimation**: Hue bridge decimates to 25Hz over ZigBee\n- **Visible effect rate**: should stay below 12.5Hz; the adapter reports ~6Hz to the bridge core as the rate limit for value changes\n- **Limits**: max 10 lights per entertainment area, one active entertainment area per bridge\n\nLights in the active entertainment area are automatically excluded from REST API control and reported as `controlMode: \"realtime\"`.\n\n### Standard REST API (Limited)\n\nRate-limited HTTP calls to the Hue CLIP v2 API for lights, groups, and scenes.\n\n- Lights: individual color/state control\n- Groups (rooms, zones): brightness control via grouped_light resource\n- Scenes: activation by scene ID\n\nAll REST calls use HTTPS with self-signed certificate handling (Hue bridges use a private CA).\n\n## Entertainment Area Selection\n\nConfigure the entertainment area via `protocolConfig.entertainmentConfigId` in the bridge config:\n\n```json\n{\n  \"protocolConfig\": {\n    \"entertainmentConfigId\": \"uuid-of-entertainment-area\"\n  }\n}\n```\n\nWhen an entertainment area is active:\n- Lights assigned to that area switch to `controlMode: \"realtime\"`\n- These lights are auto-excluded from REST API control\n- All other lights remain as `controlMode: \"limited\"`\n\nEntertainment areas are configured in the Hue app. Each area can contain up to 10 lights. Only one area per bridge can be active at a time (Hue hardware limitation).\n\n## Rate Limits\n\n| Category | Max/sec | Default/sec | Notes |\n|----------|---------|-------------|-------|\n| `light` | 10 | 10 | ~100ms gap between individual light REST calls |\n| `group` | 1 | 1 | Group state changes (rooms, zones) |\n| `scene` | 1 | 1 | Scene activation (internally a group-level operation) |\n\nThese follow Hue API guidelines (~10 commands/sec to `/lights`, max 1/sec to `/groups`). The bridge core enforces the shared budget per category per bridge.\n\nUsers can lower these limits in the bridge config but not exceed the maximum:\n\n```json\n\"rateLimits\": {\n  \"light\": 5\n}\n```\n\n## Channel Modes\n\n| Mode | Channels | Layout | Use Case |\n|------|----------|--------|----------|\n| `8bit` | 3 | R, G, B (0-255) | Standard color control |\n| `8bit-dimmable` | 4 | Dim, R, G, B (0-255) | Color + separate dimmer |\n| `16bit` | 6 | R-coarse, R-fine, G-coarse, G-fine, B-coarse, B-fine | High-precision color |\n| `scene-selector` | 1 | 0 = no action, 1-255 maps to scene list | Scene triggering |\n| `brightness` | 1 | 0-255 | Group brightness control |\n\nAll values are normalized to 16-bit (0-65535) by the bridge core before reaching the adapter.\n\n## Configuration Examples\n\n### Basic Setup: Three Lights in 8-bit RGB\n\n```json\n{\n  \"id\": \"hue-studio\",\n  \"protocol\": \"hue\",\n  \"connection\": {\n    \"host\": \"192.168.1.42\",\n    \"username\": \"abc123\",\n    \"clientkey\": \"def456\"\n  },\n  \"universe\": 0,\n  \"channelMappings\": [\n    { \"targetId\": \"light-1-uuid\", \"targetType\": \"light\", \"dmxStart\": 1, \"channelMode\": \"8bit\" },\n    { \"targetId\": \"light-2-uuid\", \"targetType\": \"light\", \"dmxStart\": 4, \"channelMode\": \"8bit\" },\n    { \"targetId\": \"light-3-uuid\", \"targetType\": \"light\", \"dmxStart\": 7, \"channelMode\": \"8bit\" }\n  ]\n}\n```\n\n### Entertainment Streaming with 16-bit Color\n\n```json\n{\n  \"id\": \"hue-stage\",\n  \"protocol\": \"hue\",\n  \"connection\": {\n    \"host\": \"192.168.1.42\",\n    \"username\": \"abc123\",\n    \"clientkey\": \"def456\"\n  },\n  \"universe\": 0,\n  \"protocolConfig\": {\n    \"entertainmentConfigId\": \"ent-area-uuid\"\n  },\n  \"channelMappings\": [\n    { \"targetId\": \"light-1-uuid\", \"targetType\": \"light\", \"dmxStart\": 1, \"channelMode\": \"16bit\" },\n    { \"targetId\": \"light-2-uuid\", \"targetType\": \"light\", \"dmxStart\": 7, \"channelMode\": \"16bit\" }\n  ]\n}\n```\n\n### Mixed: Lights + Group Brightness + Scene Selector\n\n```json\n{\n  \"id\": \"hue-living-room\",\n  \"protocol\": \"hue\",\n  \"connection\": {\n    \"host\": \"192.168.1.42\",\n    \"username\": \"abc123\",\n    \"clientkey\": \"def456\"\n  },\n  \"universe\": 0,\n  \"channelMappings\": [\n    { \"targetId\": \"light-1-uuid\", \"targetType\": \"light\", \"dmxStart\": 1, \"channelMode\": \"8bit-dimmable\" },\n    { \"targetId\": \"group-1-uuid\", \"targetType\": \"group\", \"dmxStart\": 5, \"channelMode\": \"brightness\" },\n    { \"targetId\": \"scene-sel-uuid\", \"targetType\": \"scene-selector\", \"dmxStart\": 6, \"channelMode\": \"scene-selector\" }\n  ],\n  \"rateLimits\": {\n    \"light\": 8\n  }\n}\n```\n\n## Hue CLIP v2 Endpoints Used\n\n| Endpoint | Method | Purpose |\n|----------|--------|---------|\n| `/clip/v2/resource/light` | GET | List lights |\n| `/clip/v2/resource/light/{id}` | PUT | Set light state |\n| `/clip/v2/resource/room` | GET | List rooms |\n| `/clip/v2/resource/zone` | GET | List zones |\n| `/clip/v2/resource/grouped_light` | GET | List grouped lights |\n| `/clip/v2/resource/grouped_light/{id}` | PUT | Set group state |\n| `/clip/v2/resource/scene` | GET | List scenes |\n| `/clip/v2/resource/scene/{id}` | PUT | Activate scene |\n| `/clip/v2/resource/entertainment_configuration` | GET | List entertainment areas |\n| `/clip/v2/resource/entertainment_configuration/{id}` | PUT | Start/stop streaming |\n| `/api` | POST | Create app user (pairing) |\n\n## Internal Components\n\n- `HueProtocolAdapter` -- main adapter class, implements `ProtocolAdapter`\n- `HueClipClient` -- thin CLIP v2 REST client using native `fetch`\n- `HueDtlsStream` -- DTLS streaming via `node-dtls-client`, continuous 50Hz transmission\n- `HueDiscovery` -- mDNS + Meethue cloud discovery\n- `HuePairing` -- link-button pairing flow\n","readmeFilename":"README.md","_rev":"1-038a1c35e20635c257c8d3cd9f3c6364"}