Skip to content

getsubwave/pico-subwave

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pico-subwave

A desk mini player for SUB/WAVE. Shows what's playing on the LCD and skips the track from a physical button.

Runs MicroPython on a Raspberry Pi Pico 2 W in a Pimoroni Pico Explorer Base.

Skip is an operator override. SUB/WAVE is one shared broadcast — skipping skips it for every listener, not just this device. That's why it's a deliberate hold, not a tap.

Buttons

Button Action
A Now Playing screen
A (hold 1s) Skip track — needs admin credentials
B Up Next — what's queued
X Track info — BPM, key, mood, genre, energy, year
Y Backlight on/off (any button wakes)

Screens

Now Playing shows title, artist, album, and a progress bar. The status bar carries the DJ name, listener count, and a health dot: green fresh, amber stale, red no WiFi.

Several fields are best-effort on the Subwave side and degrade rather than fail:

  • duration is absent for tracks unknown to both the queue and the library → elapsed only, no bar.
  • BPM / key / mood / genre appear only once the analyzer has tagged the track → -.
  • nowPlaying is null when the station is off air → OFF AIR.

Setup

  1. Flash Pimoroni MicroPython firmware (provides picographics and pimoroni).
  2. pipx install mpremote
  3. Configure:
    cp src/wifi_config.template.py src/wifi_config.py       # WiFi
    cp src/subwave_config.template.py src/subwave_config.py # admin creds
  4. ./push.sh

Both config files are gitignored.

Get the credentials right first time. Subwave allows 10 failed admin attempts per IP, then blocks that IP for 15 minutes — and the Pico shares your public IP. On a 401 the firmware latches and refuses further skips rather than burning the budget; fix the config and reboot to clear it.

Credentials are only needed for skip. Everything else works without them — /api/now-playing is public.

Pointing at a different station

One knob, in src/config.py:

API_BASE = "https://radio.klair.co/api"      # public deployment (Caddy, /api prefix)
# API_BASE = "http://192.168.1.101:7701"     # LAN/byo install — routes at the root

Architecture

Three async tasks: poll /api/now-playing every 5s, scan buttons every 20ms, redraw every 1s so the progress bar ticks between polls.

Module Purpose
main.py Boot, WiFi, task orchestration
config.py API base, pins, timings
net.py HTTP/HTTPS client with chunked decoding
subwave.py API client + parsing; the skip auth latch
screens.py LCD rendering + layout helpers
buttons.py Debounced A/B/X/Y, short vs long press
wifi.py STA connect + NTP sync (copied from pico-hook)
buzzer.py Tones (copied from pico-hook)

subwave.py fetches and never draws; screens.py draws and never fetches. That split is what lets the parsing and layout logic be tested off-device.

Notes for anyone extending this

  • Cloudflare returns Transfer-Encoding: chunked. pico-hook's ntfy.py:_http_get doesn't de-chunk — it works against ntfy.sh only because ntfy doesn't chunk. net.py handles it. Don't copy the old helper here.
  • NTP is mandatory, not cosmetic. The API has no elapsed field; it's derived as now - timestamp against the server's clock. timestamp is unix seconds while the rest of the API uses epoch milliseconds.
  • The module is net.py, not http.pyhttp shadows a CPython stdlib package and breaks the host tests.
  • TLS is unvalidated. MicroPython does no certificate checking by default, so admin credentials cross the internet encrypted but unauthenticated. Pinning was attempted and hard-wedged the board; see the design doc's "Out of scope".

Tests

Parsing and layout are pure functions, tested on the host against payloads captured live from radio.klair.co:

python3 -m pytest tests/ -q

Hardware

  • Raspberry Pi Pico 2 W (RP2350)
  • Pimoroni Pico Explorer Base — 240x240 IPS LCD, buttons on GP12 (A), GP13 (B), GP14 (X), GP15 (Y)
  • Passive buzzer on GP0 via jumper (optional; only used for skip feedback)

Design

See docs/superpowers/specs/2026-07-16-pico-subwave-design.md.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors