Authentication (01), one input policy for skip/mute/volume steps (04), the
firmware's interleaved serial frames (05), podcast as an album kind (06), and eight
smaller cleanups (07). Each says why, what was decided, the design, the tests and
when it is done.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- python-backend/README: track analysis is implemented (2e0e6ad); the cache layout,
the module table (lirc, screen, timers, podcasts, tippen) and the route table
(track analysis, HA proxy, typing game) were missing pieces.
- docs/REPO_OVERVIEW: Mein Zimmer and the clock are implemented; Home Assistant is
also reached over HTTP through the room page's proxy, not MQTT only; the IR remote,
scripts/, the optional config sections and figure kind were not mentioned.
- web/README: the key table was the mockup's (Ctrl transport keys, TAB over 'all');
?pi=1 is now a preset with per-browser overrides, not a read-once flag; the room
page and the typing game exist; eslint is part of the checks.
- Docstrings that described earlier designs: HaConfig (written as browser-direct in
the same commit that built the proxy, a8ed350), services/__init__, events,
playback, media, colors, tippen progress and AppHeader, lowPower.ts, and the
'Hoerbuecher' spelling.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- claude-design/Dolphin Beats Music Player.zip (32 MB): the design tool's export of
the mockups already unpacked next to it. Still in history (30065bb) if needed.
- claude-design/pasted-*.png: byte-identical copies of dolphin-mascot.png and
dolphin-remote.png that nothing references.
- python-backend/notebooks: the chord-recognition course material with stale paths.
effect_debug.ipynb stays.
The hardware models are untouched, and the history keeps its size: removing files
from the tree does not shrink the pack.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a7fb56c pinned mypy to Python 3.11 for the Pi. In a dev venv that also has the
analysis extra, numpy's stubs use 3.12 syntax, so mypy aborted on them before
checking a single file - and from the next day on four real errors went in
unnoticed (ebab03b, 0ef5a04, 9fd106b). Skip following numpy/librosa instead; only
librosa_analyzer.py touches them. Fix the four errors (variables reused with a
narrower type).
There is no CI, so scripts/check.sh is the gate: pytest, ruff, mypy, vitest, tsc
and eslint in one command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A figure folder that holds album folders instead of audio can play any of them,
up to six, in folder order (depth-first, alphabetical). Each is its own album,
titled "Fuchs - <folder>" and of the figure's kind. Putting the figure down plays
the album it played last, or the first, straight away; another figure placed in
between forgets the position in that album, not the album itself.
Meanwhile the ring offers all of them: one section per album from a fixed palette,
edges shifting towards the neighbours' hue, the selected one bright and wobbling.
The knob moves the selection one section per detent and wraps; pressing plays the
selected album, and left alone for 8 s the picker fades into the figure's colours
and the music carries on. While open, the device hands the knob to the picker
(`capture_knob`): turns do not change the volume and the press is not published to
Home Assistant. A tick per step and a confirm "pling" go with it.
The firmware only draws: one new ring effect, LED_WHEEL_EFFECT_SEGMENT_SELECT (23),
re-sent on every detent with the section to glide from. The look is tunable through
a temporary `general.figure_selection` config section until the right values
become constants.
Every UI sound - the screen's blubb, the parents' timer, the picker - now follows
the music volume with a floor, times a new parent-mode "Effekt-Lautstärke"
(`general.effects_volume`).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A first pass over an unanalysed library is hours of librosa, and there was no
reason for a desktop to spend them one core at a time. Analysis now runs in a
process pool sized by `general.library.analysis_workers`, defaulting to one per
core bar one (capped at 8) when the key is absent.
Two consequences worth knowing before touching this: whatever an `Analyzer`
returns has to be picklable, and an analyzer that keeps state on its own
instance - a test double counting calls - only behaves as written with
`analysis_workers=1`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>