Figures: several albums per figure, picked on the LED ring

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>
This commit is contained in:
2026-10-04 00:29:18 +02:00
parent a55cc4f67f
commit d465a74cde
37 changed files with 1570 additions and 68 deletions

View File

@@ -10,7 +10,8 @@ general:
# The music collection. One path; the shelves underneath it are fixed names, not
# settings, because each one has its own quirks the code already knows about:
#
# <root>/Figuren/<figure name>/ one folder per figurine
# <root>/Figuren/<figure name>/ one folder per figurine - or, for a figure
# with several albums, one subfolder each
# <root>/Musik/<Artist> - <Album>/ albums, grouped by artist
# <root>/Hörbücher/<Artist> - <Album>/ audiobooks, grouped by character
# <root>/Kinderpodcasts/<Show>/ shows, newest episode first
@@ -57,6 +58,27 @@ general:
# Backlight of the prev/next buttons while a figure is playing, 0..1.
button_leds_brightness: 0.5
# Loudness of the UI sounds - the screen's on/off blubb, the parents' timer, the
# album picker's clicks - in percent of how loud they are made to sit under the
# music. They follow the music's volume, but never drop below what they are at 30 %
# of it. Editable in parent mode.
effects_volume: 100
# The LED ring's album picker, for a figure with several albums (see `figures:`).
# Temporary: for tuning on the device. Every value defaults to a constant in
# musicmouse/reactions/selection.py, which is where the right ones belong once found.
# figure_selection:
# timeout: 8.0 # seconds without a turn before the picker closes
# offset_degrees: 180 # where the first album's section starts on the ring
# ring_direction: 1 # 1 or -1: which way round the sections go
# knob_direction: 1 # 1 or -1: which way the knob turns to the next album
# gap_leds: 1 # dark LEDs between sections
# dim_factor: 0.15 # brightness of the sections not selected, 0..1
# wobble_amplitude: 1.5 # how far the selected section swings, in LEDs
# wobble_period_ms: 1000 # one swing back and forth
# slide_ms: 200 # glide from one section to the next
# edge_blend: 0.25 # 0..0.5: how far section edges shift to their neighbours' hue
# Which files count as music. Anything else - a podcast downloader's archive.json,
# a half-finished .tmp - is ignored.
audio_extensions: [".mp3", ".ogg", ".oga", ".opus", ".flac", ".wav", ".m4a", ".aac"]
@@ -175,6 +197,12 @@ general:
progress_file: tippen-progress.json
# One entry per figurine. The key is the figure name and the subfolder name.
#
# A figure folder that holds audio itself plays that. One that holds album folders
# instead can play any of them, up to six: putting the figure down plays the one it
# played last (or the first, alphabetically), and the LED ring shows one coloured
# section per album for a few seconds. Turn the knob to move between them and press it
# to play the selected one; leave it alone and the music just carries on.
figures:
fuchs:
# RFID tag id, 5 bytes as hex. Must be unique across figures.
@@ -185,7 +213,8 @@ figures:
# "music" (default) or "book". Every other shelf is named after what is on it, so
# its type is obvious; a figure folder is named after the figurine, so this is the
# one thing that has to be said out loud. The web UI draws albums square and
# audiobooks taller than wide, so getting it wrong is visible at a glance.
# audiobooks taller than wide, so getting it wrong is visible at a glance. It holds
# for every album of a figure that has several.
kind: music
eule: