Skip to content

Add Philips Hue control tool example (examples/hue)#122

Open
bishwap wants to merge 1 commit into
lightphone:mainfrom
bishwap:devin/1784847347-hue-tool
Open

Add Philips Hue control tool example (examples/hue)#122
bishwap wants to merge 1 commit into
lightphone:mainfrom
bishwap:devin/1784847347-hue-tool

Conversation

@bishwap

@bishwap bishwap commented Jul 23, 2026

Copy link
Copy Markdown

Summary

Adds a new consumer Hue control tool as examples/hue — a Light Phone 3 tool that connects to a Philips Hue bridge on the local network and turns lights off (the primary action), on, or toggles them individually. It's written entirely in the tool module using SDK primitives, mirroring the existing examples/weather structure. No SDK/public-API changes and no new third-party dependencies — Ktor/OkHttp/Kotlinx Serialization/DataStore are already exposed transitively by :sdk:client.

The three parts worth calling out (the rest is straightforward from the code):

1. Bridge HTTPS trust (HueBridgeTls). The bridge is reached by LAN IP over HTTPS. Android (minSdk 33) blocks cleartext and the SDK-generated manifest gives no place to add a network-security config, so instead of HTTP we pin trust to Philips/Signify's published Hue root CAs and relax only hostname verification (the LAN IP never matches the cert's baked-in name; chain-pinning is the real trust boundary). Two Ktor clients are used:

cloudClient  = HttpClient(OkHttp) { }                 // platform trust — discovery.meethue.com
bridgeClient = HttpClient(OkHttp) { engine {          // trust pinned to Hue root CAs
    preconfigured = OkHttpClient(sslSocketFactory(hueCAs), hostnameVerifier { _,_ -> true }) } }

2. Hue v1 local API + link-button pairing (HueApi). Pairing POST /api returns [{"error":{"type":101}}] until the physical link button is pressed; that specific code becomes a "press the button, then tap Pair" retry prompt. State changes use PUT /lights/{id}/state and, for ALL OFF, the special all-lights group PUT /groups/0/action.

3. State machine (HueViewModel).

Loading -> Discovering -> BridgePicker | ManualIp -> Pairing -> Lights

Bridge IP + app key persist via DataStore (HuePreferences); an unauthorized response auto-forgets the bridge and returns to discovery.

Files

  • examples/hue/{build.gradle.kts, lighttool.toml} + settings.gradle.kts registration
  • HueModels, HueApi, HueBridgeTls, HuePreferences, HueViewModel, HueHomeScreen

Verification

./gradlew :examples:hue:check passes — lint, tests, and the SDK's own plugin validation (allowed-dependency / banned-API checks). KSP generates LightSdkRegistry with HueHomeScreen as the @InitialScreen.

Note: CONTRIBUTING.md asks that community contributions reference an existing GitHub issue — happy to open/link one if you'd like.

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant