From 19dff763bd9a5b81d0acfc14894f90f3419a66dd Mon Sep 17 00:00:00 2001 From: Matthias Blankertz Date: Tue, 16 Dec 2025 20:48:01 +0100 Subject: [PATCH 1/3] feat: webserver: keep alive; move playback write prot to handler - Reset the app idle timer when interacting with the webapp, so that the device does not turn off while the web ui is used. - Handle denying put/post while playback is active centrally in the before_request handler, so that it does not need to be copy/pasted into every request handler. Signed-off-by: Matthias Blankertz --- software/src/app.py | 4 ++++ software/src/webserver.py | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/software/src/app.py b/software/src/app.py index cbe8503..871e03d 100644 --- a/software/src/app.py +++ b/software/src/app.py @@ -116,6 +116,10 @@ class PlayerApp: # Check again in a minute self.timer_manager.schedule(time.ticks_ms() + self.idle_timeout_ms, self.onIdleTimeout) + def reset_idle_timeout(self): + if not self.playing: + self.timer_manager.schedule(time.ticks_ms() + self.idle_timeout_ms, self.onIdleTimeout) + def is_playing(self) -> bool: return self.playing diff --git a/software/src/webserver.py b/software/src/webserver.py index 95cacc5..8769bf0 100644 --- a/software/src/webserver.py +++ b/software/src/webserver.py @@ -20,6 +20,13 @@ def start_webserver(config_, app_): app = app_ +@webapp.before_request +async def before_request_handler(request): + if request.method in ['PUT', 'POST'] and app.is_playing(): + return "Cannot write to device while playback is active", 503 + app.reset_idle_timeout() + + @webapp.route('/') async def index(request): print("wohoo, a guest :)") @@ -52,8 +59,6 @@ async def config_get(request): @webapp.route('/api/v1/config', methods=['PUT']) async def config_put(request): - if app.is_playing(): - return 503 try: config.set_config(request.json) except ValueError as ex: From e2f9287ebd9fedf2a1413ca0ebbfebf4075e9d4e Mon Sep 17 00:00:00 2001 From: Stefan Kratochwil Date: Tue, 16 Dec 2025 22:40:13 +0100 Subject: [PATCH 2/3] feat: last connected tag uid available at /api/v1/last_tag_uid --- software/src/app.py | 3 +++ software/src/webserver.py | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/software/src/app.py b/software/src/app.py index 871e03d..c83c236 100644 --- a/software/src/app.py +++ b/software/src/app.py @@ -190,3 +190,6 @@ class PlayerApp: self.timer_manager.cancel(self.onIdleTimeout) self.leds.set_state(self.leds.PLAYING) self.playing = True + + def get_nfc(self): + return self.nfc diff --git a/software/src/webserver.py b/software/src/webserver.py index 8769bf0..327357a 100644 --- a/software/src/webserver.py +++ b/software/src/webserver.py @@ -11,13 +11,15 @@ webapp = Microdot() server = None config = None app = None +nfc = None def start_webserver(config_, app_): - global server, config, app + global server, config, app, nfc server = asyncio.create_task(webapp.start_server(port=80)) config = config_ app = app_ + nfc = app.get_nfc() @webapp.before_request @@ -64,3 +66,9 @@ async def config_put(request): except ValueError as ex: return str(ex), 400 return '', 204 + + +@webapp.route('/api/v1/last_tag_uid', methods=['GET']) +async def last_tag_uid_get(request): + tag, _ = nfc.get_last_uid() + return "No tag present" if tag is None else tag From 32bf6a8d68d0248007224bab545435396383da02 Mon Sep 17 00:00:00 2001 From: Stefan Kratochwil Date: Tue, 16 Dec 2025 23:13:04 +0100 Subject: [PATCH 3/3] always return content type application/json --- software/src/webserver.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/software/src/webserver.py b/software/src/webserver.py index 327357a..ca4d658 100644 --- a/software/src/webserver.py +++ b/software/src/webserver.py @@ -71,4 +71,4 @@ async def config_put(request): @webapp.route('/api/v1/last_tag_uid', methods=['GET']) async def last_tag_uid_get(request): tag, _ = nfc.get_last_uid() - return "No tag present" if tag is None else tag + return {'tag': tag}