feat: Replace hardcoded timeouts in app with configurable

Signed-off-by: Matthias Blankertz <matthias@blankertz.org>
This commit is contained in:
2025-11-28 19:41:44 +01:00
parent 2225906664
commit 83deb1b4c2
4 changed files with 41 additions and 10 deletions

View File

@@ -6,7 +6,8 @@ import time
from utils import TimerManager from utils import TimerManager
Dependencies = namedtuple('Dependencies', ('mp3player', 'nfcreader', 'buttons', 'playlistdb', 'hwconfig', 'leds')) Dependencies = namedtuple('Dependencies', ('mp3player', 'nfcreader', 'buttons', 'playlistdb', 'hwconfig', 'leds',
'config'))
# Should be ~ 6dB steps # Should be ~ 6dB steps
VOLUME_CURVE = [1, 2, 4, 8, 16, 32, 63, 126, 251] VOLUME_CURVE = [1, 2, 4, 8, 16, 32, 63, 126, 251]
@@ -14,11 +15,12 @@ VOLUME_CURVE = [1, 2, 4, 8, 16, 32, 63, 126, 251]
class PlayerApp: class PlayerApp:
class TagStateMachine: class TagStateMachine:
def __init__(self, parent, timer_manager): def __init__(self, parent, timer_manager, timeout=5000):
self.parent = parent self.parent = parent
self.timer_manager = timer_manager self.timer_manager = timer_manager
self.current_tag = None self.current_tag = None
self.current_tag_time = time.ticks_ms() self.current_tag_time = time.ticks_ms()
self.timeout = timeout
def onTagChange(self, new_tag): def onTagChange(self, new_tag):
if new_tag is not None: if new_tag is not None:
@@ -31,7 +33,7 @@ class PlayerApp:
self.current_tag = new_tag self.current_tag = new_tag
self.parent.onNewTag(new_tag) self.parent.onNewTag(new_tag)
else: else:
self.timer_manager.schedule(time.ticks_ms() + 5000, self.onTagRemoveDelay) self.timer_manager.schedule(time.ticks_ms() + self.timeout, self.onTagRemoveDelay)
def onTagRemoveDelay(self): def onTagRemoveDelay(self):
if self.current_tag is not None: if self.current_tag is not None:
@@ -40,7 +42,10 @@ class PlayerApp:
def __init__(self, deps: Dependencies): def __init__(self, deps: Dependencies):
self.timer_manager = TimerManager() self.timer_manager = TimerManager()
self.tag_state_machine = self.TagStateMachine(self, self.timer_manager) self.config = deps.config(self)
self.tag_timeout_ms = self.config.get_tag_timeout() * 1000
self.idle_timeout_ms = self.config.get_idle_timeout() * 1000
self.tag_state_machine = self.TagStateMachine(self, self.timer_manager, self.tag_timeout_ms)
self.player = deps.mp3player(self) self.player = deps.mp3player(self)
self.nfc = deps.nfcreader(self.tag_state_machine) self.nfc = deps.nfcreader(self.tag_state_machine)
self.playlist_db = deps.playlistdb(self) self.playlist_db = deps.playlistdb(self)
@@ -103,7 +108,7 @@ class PlayerApp:
self.hwconfig.power_off() self.hwconfig.power_off()
else: else:
# Check again in a minute # Check again in a minute
self.timer_manager.schedule(time.ticks_ms() + 60*1000, self.onIdleTimeout) self.timer_manager.schedule(time.ticks_ms() + self.idle_timeout_ms, self.onIdleTimeout)
def _set_playlist(self, tag: bytes): def _set_playlist(self, tag: bytes):
if self.playlist is not None: if self.playlist is not None:
@@ -144,7 +149,7 @@ class PlayerApp:
self._onActive() self._onActive()
def _onIdle(self): def _onIdle(self):
self.timer_manager.schedule(time.ticks_ms() + 60*1000, self.onIdleTimeout) self.timer_manager.schedule(time.ticks_ms() + self.idle_timeout_ms, self.onIdleTimeout)
self.leds.set_state(self.leds.IDLE) self.leds.set_state(self.leds.IDLE)
def _onActive(self): def _onActive(self):

View File

@@ -94,7 +94,8 @@ def run():
pin_next=hwconfig.BUTTON_NEXT), pin_next=hwconfig.BUTTON_NEXT),
playlistdb=lambda _: playlistdb, playlistdb=lambda _: playlistdb,
hwconfig=lambda _: hwconfig, hwconfig=lambda _: hwconfig,
leds=lambda _: LedManager(np)) leds=lambda _: LedManager(np),
config=lambda _: config)
the_app = app.PlayerApp(deps) the_app = app.PlayerApp(deps)
# Start # Start

View File

@@ -9,6 +9,8 @@ import os
class Configuration: class Configuration:
DEFAULT_CONFIG = { DEFAULT_CONFIG = {
'LED_COUNT': 1, 'LED_COUNT': 1,
'IDLE_TIMEOUT_SECS': 60,
'TAG_TIMEOUT_SECS': 5,
} }
def __init__(self, config_path='/config.json'): def __init__(self, config_path='/config.json'):
@@ -44,5 +46,14 @@ class Configuration:
os.rename(self.config_path + '.new', self.config_path) os.rename(self.config_path + '.new', self.config_path)
os.sync() os.sync()
def _get(self, key):
return self.config.get(key, self.DEFAULT_CONFIG[key])
def get_led_count(self): def get_led_count(self):
return self.config.get('LED_COUNT', self.DEFAULT_CONFIG['LED_COUNT']) return self._get('LED_COUNT')
def get_idle_timeout(self):
return self._get('IDLE_TIMEOUT_SECS')
def get_tag_timeout(self):
return self._get('TAG_TIMEOUT_SECS')

View File

@@ -124,6 +124,19 @@ class FakeLeds:
self.state = state self.state = state
class FakeConfig:
def __init__(self): pass
def get_led_count(self):
return 1
def get_idle_timeout(self):
return 60
def get_tag_timeout(self):
return 5
def fake_open(filename, mode): def fake_open(filename, mode):
return FakeFile(filename, mode) return FakeFile(filename, mode)
@@ -136,13 +149,14 @@ def faketimermanager(monkeypatch):
def _makedeps(mp3player=FakeMp3Player, nfcreader=FakeNfcReader, buttons=FakeButtons, def _makedeps(mp3player=FakeMp3Player, nfcreader=FakeNfcReader, buttons=FakeButtons,
playlistdb=FakePlaylistDb, hwconfig=FakeHwconfig, leds=FakeLeds): playlistdb=FakePlaylistDb, hwconfig=FakeHwconfig, leds=FakeLeds, config=FakeConfig):
return app.Dependencies(mp3player=lambda _: mp3player() if callable(mp3player) else mp3player, return app.Dependencies(mp3player=lambda _: mp3player() if callable(mp3player) else mp3player,
nfcreader=lambda x: nfcreader(x) if callable(nfcreader) else nfcreader, nfcreader=lambda x: nfcreader(x) if callable(nfcreader) else nfcreader,
buttons=lambda _: buttons() if callable(buttons) else buttons, buttons=lambda _: buttons() if callable(buttons) else buttons,
playlistdb=lambda _: playlistdb() if callable(playlistdb) else playlistdb, playlistdb=lambda _: playlistdb() if callable(playlistdb) else playlistdb,
hwconfig=lambda _: hwconfig() if callable(hwconfig) else hwconfig, hwconfig=lambda _: hwconfig() if callable(hwconfig) else hwconfig,
leds=lambda _: leds() if callable(leds) else leds) leds=lambda _: leds() if callable(leds) else leds,
config=lambda _: config() if callable(config) else config)
def test_construct_app(micropythonify, faketimermanager): def test_construct_app(micropythonify, faketimermanager):