Status of wiring dune-weaver-touch directly to the new headless FluidNC
firmware (dune-weaver-firmware), replacing the old dune-weaver host FastAPI
server. The entire QML interface (properties / slots / signals) is preserved, so
no .qml files were changed.
| Concern | Before (host FastAPI) | After (firmware direct) |
|---|---|---|
| Status | WebSocket /ws/status |
poll GET /sand_status (~1 Hz) |
| Actions | REST /run_theta_rho, /stop_execution, … |
$... cmds via /command + /sand_* routes |
| Patterns | local FS ../patterns |
GET /sand_patterns, files from /sd/patterns/... |
| Previews | prebuilt PNG cache | rendered locally from .thr, cached in preview_cache/ |
| Playlists | ../playlists.json |
/sand_playlists + .txt on SD (upload/delete file-ops) |
| LEDs | /api/dw_leds/* numeric ids |
$LED/* / /sand_led named effects/palettes |
| Table address | DUNE_WEAVER_URL (localhost) |
mDNS auto-discovery + DUNE_WEAVER_URL pin |
| Screen / LCD | local sysfs (unchanged) | local sysfs (unchanged) |
New
firmware_client.py — shared async HTTP client singleton (FirmwareClient.instance());
status/patterns/playlists/settings reads, $... commands, /sand_* actions,
/upload file-ops, LED + clear-mode maps, firmware error surfacing.discovery.py — mDNS discovery of _http._tcp tables (model=dune-weaver);
optional zeroconf, degrades to empty list if missing.thr_preview.py — parse .thr, render polar path → cached PNG, sync cache lookup.Rewritten
backend.py — QML-facing controller. Status polling, all actions remapped to
firmware, LED catalogue, playlist file editing, table connect/disconnect via the
old "serial" UI, local screen/LCD kept verbatim.models/pattern_model.py, models/playlist_model.py — firmware-backed, refresh
on baseUrlChanged.Updated
requirements.txt (+zeroconf), .env.example, run.sh (dropped localhost:8080
gate), README.md, added .gitignore.clear_center → in, clear_perimeter → out, adaptive → adaptive,
none → none (CLEAR_MODE_MAP in firmware_client.py). $Sand/Run … clear= needs a
playlist: config section on the board./sand_feed?mm= (motor mm/min); the 50–500 options pass through as feed.$Bye). "Shutdown Pi" → local sudo shutdown.$Playlist/Autostart reliably; enabling needs a
chosen playlist name (best-effort / logged only).connectSerial(url) selects one; saved to touch_settings.json..thr renderer produces valid PNGs; discovery.py imports with/without zeroconf.DUNE_WEAVER_URL. A kiosk
text field in TableControlPage.qml would be a good addition.pip install -r requirements.txt # adds zeroconf
# optionally pin the table:
echo 'DUNE_WEAVER_URL=dunetable.local' >> .env
./run.sh