Home Control — Complete User & Design Guide
Product: Home Control (LutronControl hub)
Current software version: see Settings tab / APP_VERSION in lutron_lights.py (this guide ships with hub 1.21.0+)
Hub machine: Pete’s iMac (Petes-iMac.local / LAN IP typically 192.168.1.249)
Web UI ports: HTTP 8787 · HTTPS 8443 (mic on phones)
Mac AV agent port: 8788 (local agent for opening links on the iMac)
Open this guide from the app footer: Guide → /guide
Raw markdown file: /USER_GUIDE.md on the hub disk: ~/LutronControl/USER_GUIDE.md
Table of contents
Global chrome (header, dock, footer, overlays)
Device identity (“This Mac” / “This iPhone”)
Tab: Video (Easy Watch, Search, TVs, confirmation)
Duplicates & overlapping controls
1. What this app is
Home Control is a whole-home web remote that runs on the iMac hub and is opened from phones, tablets, and computers on the home network (and optional Tailscale/remote URL).
It controls (when hardware is online and configured):
| Domain | Hardware / service | Engine / notes |
|---|---|---|
| Lights | Lutron RadioRA 2 processor | lutron_engine.py — may show Lights paused if processor offline |
| Music | Sonos, Google Cast, Autonomic/Mirage, free radio, YouTube→Sonos | sonos_engine, cast_engine, autonomic_engine, music_engine, cast_engine YT proxy |
| Video | Apple TVs (per room), Fire Stick (ADB), Find & Watch, Easy Watch | av_engine, firestick_engine, find_watch_engine, sports_tonight |
| Cameras | Nest (if linked) | nest_engine |
| Voice | Browser mic + optional Alexa/cast stations | voice_assistant, HTTPS cert for mic |
| House map | Rooms in rooms_config.json | Kitchen, Living Room, Den/Office, Dining, Master Suite, Basement, Exterior, Roof Deck, Patio, 3rd Floor, Joseph’s Room, Arianna’s Room |
Boundaries (product rules):
- No new streaming accounts created by the hub
- No piracy — legal deep links, free-with-ads, and owned services only
- YouTube TV is owned/used when configured
- Passwords may live in
secrets.env(reference); never commit secrets
2. How to open it (every URL)
| URL | Purpose |
|---|---|
http://192.168.1.249:8787/ | LAN main app |
http://Petes-iMac.local:8787/ | mDNS name on home Wi‑Fi |
http://127.0.0.1:8787/ | On the iMac itself (hub browser) |
https://192.168.1.249:8443/ | LAN HTTPS (mic on phones after cert) |
…/setup-https | One-time phone certificate install flow |
…/guide | This guide (HTML) |
…/USER_GUIDE.md | Raw markdown of this guide |
…/watch or …/view-on-mac | Companion “View on Mac” page for TV remote + open same title |
…/simple | Simplified entry (if enabled) |
…/manifest.json | PWA-ish web app manifest |
| Remote / Tailscale URL | From home_config.json → remote_url / preferred_home_url when configured |
Hard-refresh after hub updates: desktop Cmd+Shift+R, iPhone Safari reload after force-quit or clear cache if version badge doesn’t move.
Confirm build: bottom Systems panel shows Version; API GET /api/ping returns "version": "…".
3. Design system & UX principles
Visual language (v1.20 design pass)
- Theme: Dark slate (
#0F172Abackground, surface#1E293B) - Primary action color: Gold
#F59E0B— used for one primary CTA per context (Play, Find, main confirm) - Live / confirmed truth: Green
#22C55E— only when playback is confirmed - Muted meta:
#94A3B8 - Fonts: UI = DM Sans; display titles = Cormorant Garamond
- Type scale tokens:
--fs-title,--fs-body,--fs-label,--fs-meta,--fs-tiny - Corners: 12–18px radius cards
- Folds: Collapsible
<details class="video-fold">for secondary chrome (Search, TVs & remotes, Mirror)
UX principles (why the layout looks this way)
Phone-first Video: Primary path is Where → App → Show (Easy Watch), not a wall of search results.
Search is secondary: “Search anything” is collapsed by default.
Honest playback: UI must not say LIVE / playing without evidence (title, progress, app focus, or confirm poll).
Device labels match the browser: “This Mac”, “This iPhone”, etc. — never sticky wrong names from old localStorage.
Chrome diet: Footer is quiet (“Ready” + ··· for logs). Version lives mainly on Systems.
Gold = primary only: Secondary actions use ghost/neutral borders.
Design scores (target after 1.20)
| Dimension | Goal |
|---|---|
| Information architecture | Calm Video; Home room map clear |
| Trust / feedback | Confirm path + weak “TV on” language |
| Mobile daily use | Large Easy Watch buttons |
| Visual hierarchy | One gold CTA |
4. Global chrome (header, dock, footer, overlays)
Header
| Control | What it does |
|---|---|
| Home Control title | Branding only |
| headerMeta (subtitle) | Short status: e.g. “Home”, “N lights”, “Lights paused” — not full version spam |
| HUB OK pill | Hub process responding |
| LUTRON … / OK / PAUSED | Lights processor connection |
| 🎤 mic button (header) | Opens voice listen (needs HTTPS + cert on phone) |
Dock / tabs (top navigation)
| Tab | Icon | Panel id | What opens |
|---|---|---|---|
| Home | ⌂ | panelHome | Room grid, quick actions, status strip |
| Lights | ◐ | panelLights | All zones / levels / hot buttons |
| Music | ♪ | panelSonos | Sonos, Mirage, free, YouTube music, speakers |
| Video | ▶ | panelVideo | Easy Watch, Find, TVs, Fire Stick |
| Cameras | ◎ | panelCameras | Nest streams |
| Systems | ◈ | panelSystems | Health, network, version, diagnostics |
Duplicate path: Home also has mini buttons that jump to Video, Systems, Music, etc.
Footer log bar
| Control | What it does |
|---|---|
| lastEvent text | Human short status (“Ready”, “Lights paused…”) — not engineer uptime spam |
| Guide link | Opens /guide in a new tab (this document) |
| ··· | Toggles event log panel (#logPanel) |
Other global UI
| Element | Behavior |
|---|---|
Sticky play reel (#playReel) | Fixed bottom card when something was played / confirmed; X dismisses |
| Room overlay sheet | Tap a Home room → sheet for that room’s audio + lights |
| Apple TV pair modal | PIN entry when pairing Companion remote |
| Hot button modal | Create/edit scene shortcuts |
| Voice panel | Mic status + text command fallback |
| Connection banner | Network issues + Rescan |
| Stale cache banner | Page version ≠ hub version → reload |
5. Device identity (“This Mac” / “This iPhone”)
Every browser tab registers itself so Find can “Play on” other devices.
Detection (fwDetectDevice)
Runs on every page load from User-Agent (+ Client Hints when available):
| Device | Display name | Kind |
|---|---|---|
| iPhone | This iPhone | phone |
| iPad (incl. iPadOS-as-Mac UA with touch UI) | This iPad | tablet |
| Desktop Mac / iMac / MacBook | This Mac | computer or hub if URL is localhost |
| Windows | This Windows PC | computer |
| Android phone/tablet | This Android phone/tablet | phone/tablet |
Rules:
- Display name is never the word “hub” (hub is only an internal kind for default Play target on localhost).
- Stale localStorage names like “iPhone” on a Mac are overwritten by live detection.
- Stable
idis kept so other screens can still target “Pete’s browser”. - Heartbeat:
POST /api/client/helloevery ~8s.
Where the name appears
- Easy Watch → Where → third button
- Find → Play on chips
- Toasts / status after open-here play
6. Tab: Home
Purpose
House overview: status, quick jumps, room cards.
Typical controls
| Control | Action |
|---|---|
| Status strip | One-line house state; transport shortcuts when music/TV known |
| Quick help / mini buttons | Jump to Systems, Video, hard refresh, etc. |
| Room cards | Open room sheet for that area |
| Room sheet — lights | On/off/dimmers for zones in room |
| Room sheet — audio | Sonos/Cast for that room when mapped |
| Room sheet — TV | Power / pause / home for room Apple TV when mapped |
| Mirror (in sheet) | Match one Apple TV to another room |
| Hot buttons (if shown) | Saved multi-zone scenes |
Rooms (configured)
Kitchen, Living Room, Den / Office, Dining, Master Suite, Basement, Exterior, Roof Deck, Patio, 3rd Floor, Joseph’s Room, Arianna’s Room.
Lights paused mode
If Lutron processor is offline, UI shows Lights paused but music/video still work.
7. Tab: Lights
Purpose
Whole-house lighting control by zone.
| Control | Action |
|---|---|
| Zone On | Level 100 |
| Zone Off | Level 0 |
| Slider | Dim 1–100 |
| Area / floor groups | Batch on/off when UI groups exist |
| Hot buttons | Save current levels as a named scene; tap to recall |
| Hot button + | Create new scene |
| Delete hot button | Removes scene |
API: /api/set, /api/set-batch, /api/levels, /api/hot-buttons.
8. Tab: Music
Purpose
Play music to Sonos, Mirage/Autonomic, Google speakers, free streams, YouTube→Sonos.
Common controls (many are mode-dependent)
| Control | Action |
|---|---|
| Backend / mode chips | Switch Mirage / Sonos / Speakers / Free / YouTube music, etc. |
| Room / speaker picker | Which Sonos or cast target |
| ▶ Play / ⏸ Pause | Transport |
| Prev / Next | Sonos skip |
| Volume slider | Room volume |
| Favorites / playlists / browse | Library navigation |
| Search | Sonos or YouTube music search |
| YouTube → Den/Sonos | Hub proxies stream so Sonos can play (avoids googlevideo fail) |
| Group Sonos | Multi-room group coordinator + members |
| Free stations | Legal free radio / streams |
| Mac open | Open URL on hub Mac browser |
Music design notes
- Large hero play + row progress bar for YouTube music confirmation of movement.
- Local browser audio often muted when casting to Sonos (DJ mode).
9. Tab: Video
Video is the densest tab. Layout order (top → bottom):
Easy Watch (primary)
Search anything (collapsed fold)
Find results (when a search is open)
Now stage (featured room; honest Live)
TVs & remotes (collapsed fold: room cards, Scan, Mac, Fire help)
Sticky play reel (global)
9.1 Easy Watch (▶ Watch)
Goal: Three taps — Where → App → Show.
Step 1 — Where
| Button | Target id | What Play will do |
|---|---|---|
| Living Room | living | Apple TV Living (av_engine deep link / app launch) |
| Fire Stick | firestick | ADB launch / URL on stick |
| This Mac / This iPhone / … | this_device | Open URL in *this* browser |
| Everywhere | everywhere | Best-effort fan-out: this device + Living + Fire + Mac |
Back returns to previous step.
Crumbs (Where › App › Show) are tappable to jump steps.
Step 2 — App (stream)
| Button | Source | Notes |
|---|---|---|
| YouTube TV | youtube_tv | Owned live TV app |
| Fox News | fox_news | Fox News app / live URL |
| YouTube | youtube | Free clips / search |
| Netflix | netflix | Open app (login on device) |
Step 3 — Show (presets)
YouTube TV presets include: Live guide, Fox News, CNN, ESPN, MSNBC, Local news, Search more…
Fox News presets include: Fox News Live, Fox News app, FOX Sports, Politics
YouTube presets: Open YouTube, Fox News live search, News live
Netflix: Open Netflix
Search more… opens the Search anything fold and focuses the query box (keeps selected Where as Play target).
After Play
Command sent → reel Starting… / status ⏳
confirmVideoPlayback polls now-playing (Apple TV) or Fire Stick focus
✅ Confirmed · ⚠️ Unconfirmed · ❌ Failed
Reel shows LIVE only if confirmed: true
9.2 Search anything (Find & Watch)
| Control | Action |
|---|---|
| Query field | Free text: movies, sports, “Yankees tonight”, etc. |
| Find (gold) | POST /api/find/watch — free clips first, legal apps, sports inject |
| Mode chips | All · Movies · TV · Sports · Live · Free · Kids · Music |
| Play on chips | This device · Living TV · Fire Stick · More… (Mac, Everywhere, other browsers) |
| Result cards | Tap to select (on phone row Play hidden — use bottom Play) |
| Play (bottom bar) | POST /api/find/play + confirmation |
| Sports “Ship it” | When sports_tonight answers, ship buttons jump to YTTV / live targets |
Duplicate: Mode chips exist sticky + hidden in panel host (both stay in sync).
Duplicate: Query field sticky is real; hidden #findWatchQuery mirrors value for legacy code.
9.3 Now stage (featured TV)
| Element | Meaning |
|---|---|
| Live (green pill) | Confirmed evidence (title / progress / app + playing) |
| TV on (gray) | Power on, title not reported |
| Title / sub | Honest status — not “content active” lies |
| Progress bar | Only when confirmed + duration known |
| ⏯ / Off / Rooms | Transport + jump to TVs fold |
| Mirror to other rooms (collapsed) | Multi-select destinations → mirror |
9.4 TVs & remotes fold
| Control | Action |
|---|---|
| Room cards | Per Apple TV: On · Play/Pause · Home · Off |
| Fire Stick card | Home · ▶/⏸ · Back · Netflix shortcut; Apps & full remote in details |
| Scan | /api/video/scan rediscover devices |
| Living on Mac | Opens companion / Mac AV view path |
| Fire Stick help | One-time ADB “Allow” instructions + Recheck |
| Pair Apple TV | Companion pairing PIN modal |
| Remote · mirror · Mac (per room details) | Full D-pad remote, re-pair, view on Mac |
| More devices | Unmapped Apple TVs, Roku shortcuts, Mac hosts, cast devices |
Fire Stick notes
- Preferred serial often Wi‑Fi ADB
192.168.1.240:5555 - Must Allow USB debugging once on a TV screen
- Unauthorized device may also appear on another IP
- ANM Live package if sideloaded (
ar.tvplayer.tv) — subscription errors are app-side
9.5 Play confirmation (all play paths)
confirmVideoPlayback:
- Living: poll
/api/video/now-playing— score title, app, position, power - Fire Stick: poll
/api/video/firestick/status— focus package / media app - Mac: weak confirm (command accepted)
- Everywhere: any room with signal
Levels: confirmed · weak · failed / pending→weak after timeout.
10. Tab: Cameras
| Control | Action |
|---|---|
| Camera grid | Live Nest streams when linked |
| Refresh / auto refresh | Detect new cameras |
| Retry on error | Reconnect WebRTC/session |
Requires Nest OAuth tokens (nest_tokens.json / config). If unlinked, panel explains linking.
11. Tab: Systems
| Section | Contents |
|---|---|
| Version | Hub APP_VERSION |
| Health | Timed checks: hub, lutron, sonos, cast, nest, video, mirage, mac_av, astro, discovery |
| Deep health | Longer probe |
| Network / discovery | Seen devices |
| Speed test | Hub speed helper |
| Astro | Sunrise/sunset lighting schedules status |
| Logs | Server log tail |
| Connection heal | Force network rescan |
Use Systems when something “doesn’t work” before blaming the TV.
12. Voice / mic
| Control | Action |
|---|---|
| 🎤 (header or dock) | Start voice recognition |
| Voice text input | Type a command if mic blocked |
| HTTPS setup | /setup-https install LAN CA, then open :8443 |
Mic on iPhone requires HTTPS + trusted cert. Plain HTTP works for lights/music/video without mic.
13. Sticky play reel
Appears after Play / Easy Watch / featured room sync.
| Element | Behavior |
|---|---|
| Room · status | LIVE only if confirmed; else starting / check TV / paused |
| Title / sub | Title + app + device_state |
| Progress | Ticks when confirmed playing; polls hub every ~6s |
| X | Dismiss reel (hidePlayReel) |
14. Duplicates & overlapping controls
These are intentional or legacy; knowing them avoids confusion.
| Duplicate | Where | Notes |
|---|---|---|
| Play | Easy Watch vs Find Play vs room ▶ | Easy Watch = presets; Find = search results; room ▶ = transport only |
| Where / Play on | Easy Watch step 1 vs Find target chips | Same targets (living, firestick, this_device, …) |
| Search box | Sticky fold vs (hidden) hero field | Sticky is source of truth; hero hidden syncs |
| Mode chips | Sticky + hidden panel row | Both call fwRenderModeChips |
| Mic button | Header + dock | Same voice start |
| Jump to Video | Dock + Home mini + log shortcuts (older) | Same tab |
| Mirror | Now stage fold + per-room mirror + Home sheet | Same /api/video/match |
| Fire Stick Netflix | Transport shortcut + full app grid | Same launch path |
| YouTube vs YouTube TV | Easy Watch apps | Different sources (youtube vs youtube_tv) |
| Mac open | Find target Mac · Living on Mac · View on Mac | Mac AV agent :8788 |
| Status language | Reel + Now stage + room pills | Should all respect confirmation; room pills may still say TV On from power hint |
| Version | Systems · (optional) old badges | Prefer Systems |
| Client devices list | Find “More places” | Other browsers that heartbeated hello |
| Two launchd labels (ops) | com.homecontrol.lutron preferred | Duplicate agents caused double hub historically |
15. Legal / free content policy
- Prefer free full movies with ads, free clips with runtime, free FAST apps (Tubi, Pluto, etc.)
- FULL badge = feature-length preference in ranking
- login badge = subscription app deep link / search portal
- No pirate IPTV scrapers
- Sports: StatsAPI / legal ship-to YTTV / highlights — not illegal streams
16. Backend engines & files
| File | Role |
|---|---|
lutron_lights.py | Main hub HTTP server + entire SPA HTML/CSS/JS |
lutron_engine.py | RadioRA 2 telnet / levels |
sonos_engine.py | Sonos discovery & transport |
cast_engine.py | Chromecast / Google speakers + YT cache/proxy |
autonomic_engine.py | Mirage / Autonomic music |
music_engine.py | Free / library sources |
av_engine.py | Apple TV pyatv Companion |
firestick_engine.py | ADB Fire Stick |
find_watch_engine.py | Search + play routing |
sports_tonight.py | “Yankees tonight?” style answers |
mac_av_engine.py / mac_av_agent.py | Open URLs / YTTV on Mac |
nest_engine.py | Cameras |
voice_assistant.py | Voice parsing |
secrets_env.py + secrets.env | Streaming credentials (local) |
rooms_config.json | Room map |
home_config.json | URLs, systems flags |
firestick_config.json | Stick serials / IPs |
zones.json / scenes.json | Lights |
USER_GUIDE.md | This document |
start_hub.sh | Start venv python hub |
install_mac_autostart.sh | launchd |
17. HTTP / API map (high level)
Pages
| Path | Content |
|---|---|
/ | Main SPA |
/guide | HTML guide (this doc) |
/USER_GUIDE.md | Raw markdown |
/setup-https | Cert install help |
/watch | View on Mac companion |
/api/ping | { ok, version, uptime_sec, url } |
Representative APIs
| Area | Examples |
|---|---|
| Lights | /api/set, /api/set-batch, /api/levels, /api/hot-buttons |
| Home | /api/home/status, /api/home/rooms |
| Sonos | /api/sonos/speakers, …/transport, …/play, …/volume, …/favorites |
| Cast | /api/cast/play-url, …/transport, …/stations |
| Music YT | /api/music/youtube/search, …/play, …/stream |
| Video | /api/video/layout, …/now-playing, …/scan, …/match, …/appletv/command |
| Fire Stick | /api/video/firestick/status, …/launch, …/key, …/connect |
| Find | /api/find/watch, /api/find/play |
| Clients | /api/client/hello, …/devices, …/pending |
| Health | /api/health, /api/connection, /api/logs |
| Cameras | /api/cameras/status, stream endpoints |
18. Start / restart / autostart
macOS (iMac)
cd ~/LutronControl
./start_hub.sh
# or
.venv/bin/python lutron_lights.py
launchd (preferred single agent): ~/Library/LaunchAgents/com.homecontrol.lutron.plist
KeepAlive + RunAtLoad · working directory ~/LutronControl · venv python.
Mac AV agent: mac_av_agent.py on port 8788 (start_hub may launch it).
Windows PC (host the hub)
Full guide: WINDOWS_HOST.md
Install Python 3 (add to PATH)
Copy LutronControl folder to the PC
Run Setup Windows Host.bat
Run Start Home Control.bat
Open http://127.0.0.1:8787/ (phones: http://PC_LAN_IP:8787/)
Optional: Install Auto-Start.bat for login + watchdog
Only one hub at a time on port 8787 (stop iMac hub if Windows is hosting).
Ping check:
curl -s http://127.0.0.1:8787/api/ping
19. Troubleshooting
| Symptom | What to try |
|---|---|
| Wrong version in UI | Hard-refresh; check /api/ping version |
| Says iPhone on Mac | Fixed in 1.20.2+; hard-refresh; last resort localStorage.removeItem('fwDevice') |
| Lights paused | Lutron processor IP / network; music & video still work |
| Fire Stick unauthorized | HDMI to TV → Developer options → Allow this computer |
| Play says OK but nothing on TV | Read confirm status; check pair Apple TV; Fire focus app |
| Sonos YouTube silent | Use hub YT proxy path (Music YT mode), not raw googlevideo |
| Mic blocked | HTTPS + install CA via /setup-https |
| Double hub / flaky ports | Only one launchd agent; free 8787/8443 |
| Search results empty | Try Movies mode; check hub online; free filters hide stubs |
20. Version history (recent UX)
| Version | Highlights |
|---|---|
| 1.19.x | Find & Watch polish, sports ship, sticky search, Fire Stick, play reel |
| 1.19.27 | Real play confirmation (no fake LIVE) |
| 1.19.28 | Easy Watch Where→App→Show |
| 1.20.0 | Design overhaul: calm Video, folds, gold=primary, honest Now stage, quiet footer |
| 1.20.1–1.20.2 | Device labels: live detect This Mac / This iPhone |
| 1.20.3 | This guide + footer Guide link |
| 1.21.0 | Redesign brief: single status strip, calm room cards (no IPs), Settings tab, gated Integrations PIN, lights All off, camera states, play reel only when confirmed |
Quick couch recipes
Fox News on Living Room
Video → Watch → Living Room → Fox News → Fox News Live
YouTube TV guide on Living
Video → Watch → Living Room → YouTube TV → Live guide
Free dog cartoon on Living
Video → Search anything → type query → Find → pick FULL FREE → Play on Living TV
Pause Patio TV
Video → TVs & remotes → Patio card → ⏸
Music on Den Sonos
Music → pick Den/Sonos → search or favorite → ▶
Maintainer notes
- UI is embedded in
lutron_lights.py(HTML = """…""") — large single file. - Prefer bumping
APP_VERSIONon every user-visible change. - Design tokens live in
:rootCSS inside that HTML. - Do not add competing gold “hero” boxes without demoting something else.
- Keep confirmation honesty global when adding new Play entry points.
*End of Home Control complete guide. For ops install notes see also README.txt (sync / File Sharing / Windows legacy).*