Haunt
Android app that uses WiFi Round-Trip Time (RTT) ranging to fingerprint your phone's position and activate the corresponding Philips Hue light — no floor plans, no coordinate systems, no backend.
How it works
Three Google WiFi pucks each return a distance reading in meters. The combination of all three — a distance-triple — is unique to a physical location. During calibration you record a triple for each room. At runtime, the app finds the nearest stored triple and switches the light for that room.
See docs/wifi-rtt-hue-brief.md for the full design brief including accuracy expectations, gotchas, and development order.
Hardware required
- 3× Google WiFi pucks (2016 squat-cylinder model) — support IEEE 802.11mc FTM on 5 GHz
- Philips Hue Bridge v2 (square), on the same LAN
- Android phone: Pixel 2 or newer, Android 9+
Setup
1. Hue credentials
Press the button on your Hue Bridge, then within 30 seconds:
curl -X POST http://<bridge-ip>/api \
-H "Content-Type: application/json" \
-d '{"devicetype":"haunt#android"}'
# Save the username from the response
curl http://<bridge-ip>/api/<username>/lights
# Note the integer ID for each light you want to control
2. Find puck BSSIDs
Run the app in debug mode — it lists every RTT-capable AP with its BSSID. Walk up to each puck; it will auto-pin to the map when you're within 0.5 m. Rename the pinned points (e.g. "Router kitchen") so you can identify which BSSID belongs to which puck.
3. Open in Android Studio
Requires Android Studio Ladybug or later. On first open, let Gradle sync finish and generate the wrapper JAR, then run on a physical device (RTT does not work in the emulator).
App icon
The launcher icon is generated from location.png in the repo root. After replacing that file, regenerate all mipmap sizes and the adaptive-icon foreground with:
gradle :app:generateIcons
To change the background color, edit the bgColor variable at the top of the generateIcons task in app/build.gradle.kts. The task is incremental — Gradle skips it if location.png hasn't changed.
Attribution
location.png is from the Outline collection by icongeek26 on Flaticon.
Orientation mode
The map has a built-in compass mode. Tap ⊙ Orient in the toolbar to enable it. The map then rotates to keep the phone's forward direction at the top, and a red N indicator appears at the edge showing where north is.
Calibration: face your known north, hold the phone pointing that way, then drag the N circle to the top of the screen. The offset is saved and persists across restarts.
Haunt mode
Tap Haunt to enable haunt mode. While active, when you walk close to a registered Hue light (within ~1 m), that light blinks on and off slowly. When you move away or turn haunt mode off, the light returns to the state it was in before blinking started.
Development status
| Layer | Status | Description |
|---|---|---|
| 1 | ✅ | Project scaffold, permissions, RTT availability check |
| 2 | ✅ | RTT ranging, debug map, add/rename/delete points, history trail |
| 3 | ✅ | Hue Bridge discovery, pairing, light/group listing and blinking |
| 4 | ✅ | Haunt mode — proximity detection, blink loop, state restoration |
| 5 | ✅ | Compass orientation mode — live map rotation, N indicator, calibration |
| 6 | ✅ | LAN device scanner — ARP + mDNS, pin network devices to map |
| 7 | — | ZoneMatcher — automatic light switching without haunt button |
| 8 | — | Background service — keep ranging alive when app is backgrounded |
| 9 | — | Tuning — average N readings, debounce K zone changes |
Package
net.fuzzyworld.haunt