The HAP-Revival web UI (tools/webui.py) is a Progressive Web
App (PWA). That means you can add it to your iPhone or iPad home screen and it
behaves like a native remote: its own icon, full-screen (no Safari address bar),
its own entry in the app switcher. No App Store, no Mac, no Xcode, no Apple
developer account — just Safari.
This is the control app you can use today, while the native iOS/iPad app and the custom on-device daemon are still being built.
- A real home-screen icon (a vinyl record) and app name (HAP).
- Standalone full-screen launch — the browser chrome disappears.
- Now-playing with cover art, play / pause / seek / next / previous, the sound settings (DSEE, DSD remastering, gapless, oversampling…), themes, and a minimal mode — everything the browser UI already does, in an app shell.
- Your theme / minimal-mode preferences are remembered (stored on-device).
You run the web UI on a computer on the same network as the HAP (a PC, a Mac, a Raspberry Pi — anything that runs Python). The phone/tablet then opens it over Wi-Fi.
# Python 3.10+; stdlib only, nothing to install
python tools/webui.py <hap-ip> # serves on http://localhost:8080To reach it from your phone, bind to the network interface (not just localhost) so other devices on the LAN can connect:
python tools/webui.py --bind 0.0.0.0 --port 8080 <hap-ip>Note the computer's LAN IP (e.g. 192.168.1.50). On that machine:
- Windows:
ipconfig→ "IPv4 Address" - macOS / Linux:
ipconfig getifaddr en0/hostname -I
Tip: for a remote that's always there, run this on a machine that's always on (a NAS, a Pi, the same box you keep the music library on). A future revision will bundle this into the on-device daemon so no helper machine is needed.
- Open Safari (it must be Safari — Chrome/Firefox on iOS can't install PWAs).
- Go to
http://<computer-ip>:8080(e.g.http://192.168.1.50:8080). - Tap the Share button (the square with the up-arrow).
- Scroll down and tap Add to Home Screen.
- The name is pre-filled as HAP and the vinyl icon appears. Tap Add.
Done. Launch it from the home screen and it opens full-screen, no address bar — just the remote.
Open the same URL, then ⋮ menu → Install app (or the install prompt that appears in the address bar). Same standalone behaviour.
The PWA is three small additions to the existing stdlib web server, no new dependencies:
| Piece | Route | Purpose |
|---|---|---|
| Web App Manifest | /manifest.webmanifest |
name, icons, display: standalone, theme color — what makes it "installable" |
| Icon set | /pwa/*.png |
192 / 512 / maskable / apple-touch — generated by tools/make_pwa_icons.py (pure stdlib, regenerate any time) |
| Service worker | /sw.js |
caches only the static icons + manifest; never caches /api/*, so live device state is always fresh |
The service worker deliberately does not cache device state or control actions — those always go to the network. It only caches the icon set so the app shell loads instantly. There is nothing to go stale.
The home-screen icon is committed under tools/pwa/; to restyle
it, edit tools/make_pwa_icons.py and re-run python tools/make_pwa_icons.py.
- Same-LAN only. The phone reaches the helper machine over your home network. Remote access would need a VPN / reverse proxy — out of scope for now.
- The helper machine must be running for the app to work. This goes away once the control daemon runs on the HAP itself (Phase 4).
- No push. The HAP has no push channel, so the app polls every 3 s — exactly as the browser UI and Sony's own app do. (Our future on-device daemon can speak push; the HAP firmware can't.)
- iOS only installs PWAs from Safari, and only with the device on Wi-Fi.
This PWA is the bridge. The native iOS/iPad app (Phase 5) will talk to the same control API, so the work mapping the API and shaping this UI carries straight over. When the on-device daemon (Phase 4) lands, the helper machine disappears and the app points at the HAP directly.