feat: /api/v1/reboot/[bootloader|application], confirm with pink LED pattern
Some checks failed
Build RPi Pico firmware image / Build-Firmware (push) Successful in 4m43s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Failing after 10s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 5s
Run unit tests on host / Run-Unit-Tests (push) Successful in 8s
Run pytests / Check-Pytest (push) Successful in 11s

This commit is contained in:
2025-12-21 16:57:37 +01:00
parent 02150aec42
commit da9843adb9
3 changed files with 31 additions and 2 deletions

View File

@@ -195,3 +195,9 @@ class PlayerApp:
def get_playlist_db(self): def get_playlist_db(self):
return self.playlist_db return self.playlist_db
def get_timer_manager(self):
return self.timer_manager
def get_leds(self):
return self.leds

View File

@@ -10,6 +10,7 @@ import time
class LedManager: class LedManager:
IDLE = const(0) IDLE = const(0)
PLAYING = const(1) PLAYING = const(1)
REBOOTING = const(2)
def __init__(self, np): def __init__(self, np):
self.led_state = LedManager.IDLE self.led_state = LedManager.IDLE
@@ -19,7 +20,7 @@ class LedManager:
asyncio.create_task(self.run()) asyncio.create_task(self.run())
def set_state(self, state): def set_state(self, state):
assert state in [LedManager.IDLE, LedManager.PLAYING] assert state in [LedManager.IDLE, LedManager.PLAYING, LedManager.REBOOTING]
self.led_state = state self.led_state = state
def _gamma(self, value, X=2.2): def _gamma(self, value, X=2.2):
@@ -50,6 +51,8 @@ class LedManager:
self._pulse(time_, (0, 1, 0), 3) self._pulse(time_, (0, 1, 0), 3)
elif self.led_state == LedManager.PLAYING: elif self.led_state == LedManager.PLAYING:
self._rainbow(time_) self._rainbow(time_)
elif self.led_state == LedManager.REBOOTING:
self._pulse(time_, (1, 0, 1), 0.2)
time_ += 0.02 time_ += 0.02
before = time.ticks_ms() before = time.ticks_ms()
await self.np.async_write() await self.np.async_write()

View File

@@ -5,10 +5,13 @@ Copyright (c) 2024-2025 Stefan Kratochwil <Kratochwil-LA@gmx.de>
import asyncio import asyncio
import json import json
import machine
import os import os
import time
from array import array from array import array
from microdot import Microdot, redirect, send_file, Request from microdot import Microdot, redirect, send_file, Request
from utils import TimerManager, LedManager
webapp = Microdot() webapp = Microdot()
server = None server = None
@@ -16,17 +19,21 @@ config = None
app = None app = None
nfc = None nfc = None
playlist_db = None playlist_db = None
leds = None
timer_manager = None
Request.max_content_length = 128 * 1024 * 1024 # 128MB requests allowed Request.max_content_length = 128 * 1024 * 1024 # 128MB requests allowed
def start_webserver(config_, app_): def start_webserver(config_, app_):
global server, config, app, nfc, playlist_db global server, config, app, nfc, playlist_db, leds, timer_manager
server = asyncio.create_task(webapp.start_server(port=80)) server = asyncio.create_task(webapp.start_server(port=80))
config = config_ config = config_
app = app_ app = app_
nfc = app.get_nfc() nfc = app.get_nfc()
playlist_db = app.get_playlist_db() playlist_db = app.get_playlist_db()
leds = app.get_leds()
timer_manager = app.get_timer_manager()
@webapp.before_request @webapp.before_request
@@ -246,3 +253,16 @@ async def audiofile_delete(request):
path = fsroot + '/' + request.args['location'] path = fsroot + '/' + request.args['location']
recursive_delete(path) recursive_delete(path)
return '', 204 return '', 204
@webapp.route('/api/v1/reboot/<method>', methods=['POST'])
async def reboot(request, method):
if method == 'bootloader':
leds.set_state(LedManager.REBOOTING)
timer_manager.schedule(time.ticks_ms() + 1500, machine.bootloader)
elif method =='application':
leds.set_state(LedManager.REBOOTING)
timer_manager.schedule(time.ticks_ms() + 1500, machine.reset)
else:
return 'method not supported', 400
return '', 204