- Python 44.9%
- JavaScript 22%
- HTML 20.6%
- CSS 10.9%
- Shell 1.6%
The acrossfade-based transition broke ffmpeg's realtime pacing when mixing two -re inputs in one -filter_complex, streaming a whole track to Icecast in a few seconds instead of its real duration. A Liquidsoap replacement was also evaluated but rejected: the Debian Trixie package segfaults on this Pi due to an ABI mismatch with the Raspberry Pi's own ffmpeg build, and downgrading ffmpeg system-wide would risk breaking baresip's hardware-accelerated video calls. Skip now just kills the running ffmpeg process; radioplay.sh's existing end-of-track queue-advance logic takes it from there, exactly as it already does when a track finishes naturally. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
|---|---|---|
| app | ||
| config | ||
| scripts | ||
| skills/homescreen-implementation | ||
| specs | ||
| static | ||
| tests | ||
| .gitignore | ||
| pyproject.toml | ||
| README.md | ||
Homescreen
Touchscreen homescreen for a Raspberry Pi with five main pages:
- Kalender
- Telefon
- Radio
- PV-Anlage
- Ämtliplan
Start
Install dependencies and start the local server:
python3.13 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
uvicorn app.main:app --reload
Then open http://127.0.0.1:8000.
Run API smoke tests with:
pytest -q
Current status
- Python backend with live calendar, contacts, radio, energy, and chores endpoints
- Calls run in production over
baresip(audio and video), with alinphonecshfallback - Static fullscreen-oriented frontend
- Config files for calendars, contacts, radio stations, chores, and ioBroker
Python version
The project now targets Python 3.10+.
Recommended local setup:
- Python 3.13
- virtual environment in
.venv
Environments
- Development: macOS on Intel
- Production target: Raspberry Pi 5 on Raspberry Pi OS, with a Verbatim PMT-17 portable touchscreen as the display. Touch input on this screen has been tested and confirmed working.
The backend is structured so integrations stay behind Python services. Frontend code remains platform-neutral, while Raspberry-Pi-specific concerns such as Linphone control and kiosk startup can be added later without changing the UI contract.
For telephony, video calls are a product requirement, not an optional enhancement. The production SIP path must support video reliably, with H.264 preferred for Linphone interoperability and VP8 kept as a fallback where possible.
Deployment
Production is deployed from Git only.
Recommended flow:
git add ...
git commit -m "Your change"
git push origin main
ssh pi@<raspberry-pi>
sudo git -C /opt/homescreen pull --ff-only
sudo systemctl restart homescreen.service
Do not update /opt/homescreen via scp, rsync, or tar-over-SSH. The Pi should stay on a normal Git checkout so deployed code matches repository history.
Kiosk Browser
The Raspberry Pi kiosk browser is Chromium started from ~pi/.config/autostart/frontend.desktop.
Use --password-store=basic in the Chromium command line so the kiosk session does not prompt for GNOME Keyring or Secret Service access during unattended startup.
To avoid Chromium restoring stale kiosk sessions after updates or reboots, start it through scripts/launch-kiosk.sh from the Git checkout. The script uses a fresh dedicated temporary Chromium profile on each start.
Secrets
Copy config/secrets.example.json to config/secrets.json and fill in the real credentials.
Current secret blocks:
nextcloudfor CalDAV accessiobrokerfor the REST API onzephyr.schnurri.ch:8083linphonefor Raspberry-Pi-side dialing commandsbaresipas a pragmatic SIP CLI fallback when the Debianlinphonecshpath is unreliable
For the productive Raspberry Pi setup, the current baresip path expects PulseAudio/PipeWire style audio devices.
Recommended defaults:
baresip.audioPlayer = "pulse,default"baresip.audioSource = "pulse,default"baresip.audioAlert = "pulse,default"
The current production path also offers PCMU, PCMA, G722, and Opus for audio plus H.264 for video.
For Raspberry-Pi phone dialing, linphone.sip can hold the SIP registration data used by linphonecsh register.
If your PBX has broken or incomplete IPv6 reachability, set linphone.disableIpv6 to true and use the IPv4 host directly.
Contact photos
Store MVP contact photos in:
static/assets/contacts/
Filename rule:
- file name must match the contact
id - preferred format is
.jpg - examples:
static/assets/contacts/mama.jpgstatic/assets/contacts/arzt.jpgstatic/assets/contacts/yorick.jpg
If a contact has no image yet, keep the photoUrl empty or point it to a later file and the UI can fall back to initials.
Radio
Configured in config/radio.json:
stations: fixed online stations (Icecast/HTTP streams)nfsMountPath: NFS share that can be browsed and played from the Radio tabconfigFile/serviceName: the localradioplaysystemd service is driven through this config file and restarted on playback changes
If another NFS track is tapped while something is already playing, it is added to a queue instead of interrupting playback. A stop action clears both playback and the queue.
Ämtliplan (Chores)
Configured in config/chores.json (chore catalog with point value and icon). Per-member scores live in config/chores_state.json (untracked in Git, see .gitignore) and reset automatically every Sunday at 20:00.
Once a member collects 20 points without spinning in between, a spin of the "Glücksrad" (wheel of fortune) unlocks. Spinning (POST /api/chores/spin) randomly awards 5 bonus points, another spin, or nothing.
A long-press on a person's score opens a correction dialog for parents (POST /api/chores/adjust).