Snap volume to whole steps, and hide deleted AVR sources

A tap now moves to the next multiple of VOLUME_STEP rather than adding
it, so 23 goes to 25 and 25 goes to 30 and the levels stay round. The
panel counts taps and lets the speakers do the rounding from whatever
level they are actually at, since the phone's copy can be seconds old;
the same rule is mirrored in JS so the optimistic number never has to
correct itself when the reply lands.

The input picker also asks the AVR which sources are still switched on
(SSSOD ?) and leaves out the ones deleted in its setup menu. Sources it
does not mention are kept, so a model that ignores the command shows its
whole list rather than nothing; deleted sources also keep their names, in
case the AVR is sitting on one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 21:39:31 +02:00
co-authored by Claude Opus 5
parent 4affd18b3b
commit 1a1fcc84d6
9 changed files with 198 additions and 33 deletions
+17 -6
View File
@@ -6,11 +6,14 @@ both the interface and the HTTP bridge behind it.
Everything it does fits on one screen:
- **Volume** up/down for the Home 400 and the Living Room pair (hold to keep moving)
- **Volume** up/down for the Home 400 and the Living Room pair. A tap lands
on the next multiple of `VOLUME_STEP` — from 23 it goes to 25, not 28 —
so the levels stay round. Hold to keep moving.
- **Group** either room with the AVR — the AVR is always the host, so its
sound takes over whatever joins it
- **Ungroup** either room again, or all of them at once
- **Change the AVR's input**, listed under the names you gave them
- **Change the AVR's input**, listed under the names you gave them, minus
the sources you deleted in the AVR's setup menu
## The kit it assumes
@@ -25,7 +28,7 @@ Any other mix works — it is all in `config.py`.
## Install
```bash
cd /home/pi/heos
cd /var/www/html/heos
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
@@ -62,8 +65,13 @@ ROOM_KEYS = ["home400", "living_room_group"] # the cards, in order
`HEOS_HOST` only needs to point at **one** device: HEOS is distributed, so any
unit can see and control the whole network. `AVR_HOST` must be the AVR itself.
`AVR_INPUT_CODES` narrows the input picker to the sources you actually use
(and sets their order); leave it empty to list everything the AVR reports.
`VOLUME_STEP` is the grid the volume buttons snap to, not simply how much
they add: at 5, a tap moves 23 to 25 and 25 to 30.
The input picker already leaves out sources switched off in the AVR's own
setup menu (it asks the AVR with `SSSOD ?`). `AVR_INPUT_CODES` narrows it
further to the sources you actually use, and sets their order; leave it empty
to list everything the AVR still has switched on.
## Add it to the iOS home screen
@@ -151,13 +159,16 @@ Used by the interface:
| --- | --- |
| `GET /api/state` | everything the UI draws, in one call |
| `GET /api/targets` | every player and group HEOS can see |
| `POST /api/volume` | `{"target": "home400", "delta": 2}` or `{"level": 25}` |
| `POST /api/volume` | `{"target": "home400", "steps": 1}` — taps, snapped to `VOLUME_STEP`. Also takes `delta` (raw points) or `level` (absolute) |
| `POST /api/mute` | `{"target": "home400"}` |
| `POST /api/group` | `{"target": "home400", "joined": true}` |
| `POST /api/group/none` | every room back on its own |
| `GET /api/avr/inputs` | your renamed sources |
| `POST /api/avr/input` | `{"code": "GAME"}` |
`POST /volume/up` and `/volume/down` take one snapped tap by default; pass
`?step=3` and they move that many raw points instead, as they always did.
The original bridge's endpoints still answer, so existing Shortcuts and
scripts keep working: `/targets`, `/volume`, `/volume/{set,up,down,mute}`,
`/playback/{play,pause,stop,next,previous}`, `/group/{create,remove}`,