7 Commits

Author SHA1 Message Date
d95a9d8430 Enabled --update flag for differential flashing
Some checks failed
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m20s
Check code formatting / Check-C-Format (push) Successful in 7s
Check code formatting / Check-Python-Flake8 (push) Failing after 9s
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
2025-11-04 20:32:00 +01:00
d05fdbacdb Factored out webserver sample into dedicated module 2025-11-04 20:31:14 +01:00
8e8ec0e71f basic webserver works
Some checks failed
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m21s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Failing after 9s
Check code formatting / Check-Bash-Shellcheck (push) Successful in 4s
Run unit tests on host / Run-Unit-Tests (push) Successful in 10s
Run pytests / Check-Pytest (push) Successful in 11s
2025-11-02 23:37:30 +01:00
06909141ac print network interface info 2025-11-02 23:13:19 +01:00
9d263a37c6 disabled wifi power management for now 2025-11-02 23:12:15 +01:00
0e3ee0e44e Minimal example for api endpoint
Some checks failed
Build RPi Pico firmware image / Build-Firmware (push) Successful in 3m22s
Check code formatting / Check-C-Format (push) Successful in 8s
Check code formatting / Check-Python-Flake8 (push) Failing after 9s
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
2025-11-02 22:21:58 +01:00
86a2001ed4 Forumlated potentially useful json schema.
Note that this is based on an earlier state of the project, and the
terms used in this schema may differ from the current state of the project.
2025-11-02 22:19:55 +01:00
5 changed files with 106 additions and 40 deletions

View File

@@ -41,7 +41,7 @@ flash_via_picotool()
local device="${bus_device[1]//[!0-9]/}"
echo "Found RP2 with serial $serial on Bus $bus Device $device"
picotool load --bus "$bus" --address "$device" "$IMAGEFILE"
picotool load --update --bus "$bus" --address "$device" "$IMAGEFILE"
}
FLASH_VIA_MOUNTPOINT=0

View File

@@ -10,6 +10,8 @@ import network
import os
import time
from math import pi, sin, pow
import ubinascii
from microdot import Microdot
# Own modules
import app
@@ -19,6 +21,7 @@ from mp3player import MP3Player
from nfc import Nfc
from rp2_neopixel import NeoPixel
from utils import BTreeFileManager, Buttons, SDContext, TimerManager
from webserver import start_webserver
try:
import hwconfig
@@ -63,6 +66,16 @@ def setup_wifi():
wlan.config(ssid=f"TonberryPicoAP_{machine.unique_id().hex()}", security=wlan.SEC_OPEN)
wlan.active(True)
# disable power management
wlan.config(pm=network.WLAN.PM_NONE)
mac = ubinascii.hexlify(network.WLAN().config('mac'), ':').decode()
print(f" mac: {mac}")
print(f" channel: {wlan.config('channel')}")
print(f" essid: {wlan.config('essid')}")
print(f" txpower: {wlan.config('txpower')}")
print(f"ifconfig: {wlan.ifconfig()}")
DB_PATH = '/sd/tonberry.db'
@@ -75,7 +88,8 @@ def run():
# Wifi with default config
setup_wifi()
start_webserver()
# Setup MP3 player
with SDContext(mosi=hwconfig.SD_DI, miso=hwconfig.SD_DO, sck=hwconfig.SD_SCK, ss=hwconfig.SD_CS,
baudrate=hwconfig.SD_CLOCKRATE):

View File

@@ -1,38 +0,0 @@
import rp2
import network
import ubinascii
from microdot import Microdot
rp2.country('DE')
wlan = network.WLAN(network.AP_IF)
wlan.config(ssid='TonberryPico', security=network.WLAN.SEC_OPEN)
# Important: we cannot change the ip in station mode, otherwise dhcp won't work!
# wlan.ipconfig(addr4='10.0.0.1')
wlan.active(True) # loads the firmware
while wlan.active() is False:
pass
wlan.config(pm=network.WLAN.PM_NONE)
mac = ubinascii.hexlify(network.WLAN().config('mac'), ':').decode()
print(f" mac: {mac}")
print(f" channel: {wlan.config('channel')}")
print(f" essid: {wlan.config('essid')}")
print(f" txpower: {wlan.config('txpower')}")
print(f"ifconfig: {wlan.ifconfig()}")
app = Microdot()
@app.route('/')
async def index(request):
print("wohoo, a guest :)")
print(f" app: {request.app}")
print(f" client: {request.client_addr}")
print(f" method: {request.method}")
print(f" url: {request.url}")
print(f" headers: {request.headers}")
print(f" cookies: {request.cookies}")
return "TonberryPico says 'Hello World!'"
app.run(port=80)

View File

@@ -0,0 +1,53 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"PlaybackPosition": {
"type": "object",
"properties": {
"position_seconds": { "type": "number" },
"device_uptime": { "type": "number" }
},
"required": ["position_seconds"]
},
"AudioFile": {
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"filename": { "type": "string" },
"size_bytes": { "type": "integer" },
"duration_seconds": { "type": "number" },
"last_played_uptime": { "type": "number" },
"playback_position": { "$ref": "#/definitions/PlaybackPosition" }
},
"required": ["id", "filename"]
},
"Playlist": {
"type": "object",
"properties": {
"id": { "type": "string", "format": "uuid" },
"name": { "type": "string" },
"audio_files": {
"type": "array",
"items": { "$ref": "#/definitions/AudioFile" }
},
"current_track_index": { "type": "integer", "minimum": 0 },
"last_played_uptime": { "type": "number" },
"playback_position": { "$ref": "#/definitions/PlaybackPosition" }
},
"required": ["id", "name", "audio_files"]
},
"NfcTag": {
"type": "object",
"properties": {
"uid": { "type": "string" },
"name": { "type": "string" },
"linked_type": {
"type": "string",
"enum": ["audio_file", "playlist"]
},
"linked_id": { "type": "string", "format": "uuid" }
},
"required": ["uid", "linked_type", "linked_id"]
}
}
}

37
software/src/webserver.py Normal file
View File

@@ -0,0 +1,37 @@
'''
SPDX-License-Identifier: MIT
Copyright (c) 2024-2025 Stefan Kratochwil <Kratochwil-LA@gmx.de>
'''
import asyncio
from microdot import Microdot
webapp = Microdot()
server = None
def start_webserver():
server = asyncio.create_task(webapp.start_server(port=80))
@webapp.route('/')
async def index(request):
print("wohoo, a guest :)")
print(f" app: {request.app}")
print(f" client: {request.client_addr}")
print(f" method: {request.method}")
print(f" url: {request.url}")
print(f" headers: {request.headers}")
print(f" cookies: {request.cookies}")
return "TonberryPico says 'Hello World!'"
@webapp.route('/v1/api/playback/control', methods=['POST'])
async def playback_control(request):
if not request.json:
return {'success': False}
# Example:
# curl -H "Content-Type: application/json" --data '{"action": "play", "target_type": "audio_file", "target_id": "1234"}' http://192.168.4.1/v1/api/playback/control
print(f'Calling {request.json["action"]} on {request.json["target_type"]} with id \
{request.json["target_id"]}')