A PySide6/QML touch interface for the Dune Weaver sand table. It talks directly to the table's FluidNC firmware over its stateless HTTP/JSON API — there is no separate host (Raspberry Pi FastAPI) service in between.
The firmware is headless and advertises itself over mDNS. On launch the app:
_http._tcp advertisements with model=dune-weaver).
If exactly one is found it connects automatically; otherwise pick one from the Control
page's table list (tap Refresh to re-scan).DUNE_WEAVER_URL in .env (e.g. DUNE_WEAVER_URL=dunetable.local
or an IP). This skips discovery.The chosen table is remembered in touch_settings.json.
GET /sand_status (~1 Hz) instead of a WebSocket.$... commands via /command and the /sand_* routes
(run/stop/pause/resume/home/goto/feed/LED).GET /sand_patterns; previews are rendered locally from the
raw .thr files (/sd/patterns/...) and cached under preview_cache/..txt files on the SD card — listed via GET /sand_playlists,
read from /sd/playlists/..., and created/edited by uploading/deleting files.$LED/* / /sand_led).See the firmware's API.md for the full contract.
GET /sand_patterns on the table; .thr previews rendered locally$... commands via /command + /sand_* routesGET /sand_status (~1 Hz)firmware_client.py — shared async HTTP client + LED/clear-mode maps (singleton)discovery.py — mDNS table discovery (zeroconf; degrades gracefully if absent)thr_preview.py — renders .thr → cached PNG previewsbackend.py — QML-facing controller (status poll, actions, LEDs, playlists, local screen)models/ — PatternModel / PlaylistModel, both firmware-backedOne command to set up everything for kiosk/production use:
sudo ./install.sh
This will:
venv/)/usr/local/bin/screen-on, screen-off, touch-monitor)# Control the service
sudo systemctl start dune-weaver-touch # Start now
sudo systemctl stop dune-weaver-touch # Stop service
sudo systemctl status dune-weaver-touch # Check status
sudo journalctl -u dune-weaver-touch -f # View logs
# Disable auto-start
sudo systemctl disable dune-weaver-touch
Create virtual environment and install dependencies:
python3 -m venv venv
source venv/bin/activate # or: . venv/bin/activate
pip install -r requirements.txt
Power on the sand table and make sure it's on the same network (or set
DUNE_WEAVER_URL in .env to pin its address).
Run the touch interface:
./run.sh # Uses virtual environment automatically
# OR manually:
./venv/bin/python main.py
For custom installations:
sudo ./setup-autostart.sh
Choose from multiple setup options including systemd service, desktop autostart, or kiosk optimizations.
dune-weaver-touch/
├── main.py # Application entry point
├── backend.py # Backend controller with API/WebSocket integration
├── models/
│ ├── pattern_model.py # Pattern list model with file system access
│ └── playlist_model.py # Playlist model reading from JSON
├── qml/
│ ├── main.qml # Main window with StackView navigation
│ ├── pages/
│ │ ├── PatternListPage.qml # Grid view of patterns with search
│ │ ├── PatternDetailPage.qml # Pattern details with execution controls
│ │ ├── PlaylistPage.qml # Playlist selection and execution
│ │ └── ExecutionPage.qml # Current execution status display
│ └── components/
│ └── PatternCard.qml # Pattern thumbnail card
├── requirements.txt
└── README.md
DUNE_WEAVER_URL)