From 5c8a61eb27fd7a23c9d80e53b8a36f72de74dda3 Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Sat, 27 Dec 2025 15:17:00 +0100 Subject: [PATCH] feat: Allow configuring volume set at startup Signed-off-by: Matthias Blankertz --- software/frontend/index.html | 4 ++++ software/src/app.py | 9 ++++++++- software/src/utils/config.py | 4 ++++ software/tests/test_playerapp.py | 5 ++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/software/frontend/index.html b/software/frontend/index.html index 87dfe92..0a74d1a 100644 --- a/software/frontend/index.html +++ b/software/frontend/index.html @@ -358,6 +358,7 @@ 'root.TAGMODE': 'Tag mode', 'root.LED_COUNT': 'Length of WS2182 (Neopixel) LED chain', 'root.VOLUME_MAX': 'Maximum volume (0-255)', + 'root.VOLUME_BOOT': 'Volume at startup (0-255)', 'root.LED_MAX': 'Maximum LED brightness (0-255)' }; const config_input_override = { @@ -401,6 +402,9 @@ 'root.VOLUME_MAX': { 'input-type': 'number' }, + 'root.VOLUME_BOOT': { + 'input-type': 'number' + }, 'root.LED_MAX': { 'input-type': 'number' } diff --git a/software/src/app.py b/software/src/app.py index 386c18e..5a9c0b7 100644 --- a/software/src/app.py +++ b/software/src/app.py @@ -53,11 +53,18 @@ class PlayerApp: self.leds = deps.leds(self) self.tag_mode = self.config.get_tagmode() self.volume_max = self.config.get_volume_max() + self.volume_pos = 3 # fallback if config.get_volume_boot is nonsense + try: + for idx, val in enumerate(VOLUME_CURVE): + if val >= self.config.get_volume_boot(): + self.volume_pos = idx + break + except (TypeError, ValueError): + pass self.playing_tag = None self.playlist = None self.buttons = deps.buttons(self) if deps.buttons is not None else None self.mp3file = None - self.volume_pos = 3 self.paused = False self.playing = False self.player.set_volume(VOLUME_CURVE[self.volume_pos]) diff --git a/software/src/utils/config.py b/software/src/utils/config.py index 53485e1..6584cba 100644 --- a/software/src/utils/config.py +++ b/software/src/utils/config.py @@ -28,6 +28,7 @@ class Configuration: 'PASSPHRASE': '', }, 'VOLUME_MAX': 255, + 'VOLUME_BOOT': 16, 'LED_MAX': 255, } @@ -105,6 +106,9 @@ class Configuration: def get_led_max(self) -> int: return self._get('LED_MAX') + def get_volume_boot(self) -> int: + return self._get('VOLUME_BOOT') + # For the web API def get_config(self) -> Mapping[str, Any]: return self.config diff --git a/software/tests/test_playerapp.py b/software/tests/test_playerapp.py index b416ac3..d9748b4 100644 --- a/software/tests/test_playerapp.py +++ b/software/tests/test_playerapp.py @@ -142,6 +142,9 @@ class FakeConfig: def get_volume_max(self): return 255 + def get_volume_boot(self): + return 16 + def fake_open(filename, mode): return FakeFile(filename, mode) @@ -170,7 +173,7 @@ def test_construct_app(micropythonify, faketimermanager): deps = _makedeps(mp3player=fake_mp3) dut = app.PlayerApp(deps) fake_mp3 = dut.player - assert fake_mp3.volume is not None + assert fake_mp3.volume is not None and fake_mp3.volume >= 16 def test_load_playlist_on_tag(micropythonify, faketimermanager, monkeypatch):