# Daynivo Kiosk OS Lichte, onderhoudbare kioskdistributie voor de Raspberry Pi 3 (Model B/B+) op basis van Raspberry Pi OS Lite 32-bit (Bookworm of Trixie). Na het opstarten toont Chromium fullscreen één HTTPS-pagina. Beheer gaat via de webinterface **Daynivo Kiosk Manager** op `http://kiosk.local:8080`. - Geen desktopomgeving: alleen een minimale X-server plus Chromium. - Herstelt zichzelf: browsercrashes, een vastgelopen pagina, netwerkuitval en stroomuitval. - Geen standaardwachtwoorden: de eerste beheerder claimt het apparaat met een setupcode die op het scherm staat. - Netwerkwijzigingen met automatische rollback. - Geen klantspecifieke code: alles per klant staat in `/etc/voxip-kiosk/config.json` en kan bij uitrol via de bootpartitie worden meegegeven. De architectuur en de veiligheidskeuzes staan in [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md). De testprocedure op echte hardware staat in [`docs/HARDWARE-TEST.md`](docs/HARDWARE-TEST.md). ## Snel aan de slag ### Optie A — kant-en-klare image 1. Bouw de image (zie hieronder) of gebruik een uitgebrachte `*-daynivo-kiosk-os-*.img.xz`. 2. Schrijf hem met **Raspberry Pi Imager** (*Eigen image gebruiken*) of **balenaEtcher** naar een microSD-kaart van 16 GB of groter. 3. Optioneel, in Raspberry Pi Imager → *OS-aanpassingen*: wifi, gebruiker met wachtwoord en/of SSH-sleutel, tijdzone. Zonder aanpassingen heeft de image **geen** bruikbaar wachtwoord en staat SSH uit. 4. Optioneel: zet een `voxip-config.json` op de bootpartitie (zie [Uitrol bij meerdere klanten](#uitrol-bij-meerdere-klanten)). 5. Start de Pi. Bij de eerste boot wordt de rootpartitie automatisch vergroot tot de hele SD-kaart. Daarna verschijnt een setupscherm met de setupcode en het adres van de beheerinterface. 6. Open `http://kiosk.local:8080` (of het getoonde IP-adres), voer de setupcode in en kies een uniek beheerderswachtwoord. ### Optie B — installeren op een bestaande Raspberry Pi OS Lite Vereist: Raspberry Pi OS Lite Bookworm of Trixie met NetworkManager (de standaard sinds Bookworm). ```bash sudo apt-get install -y git git clone daynivo-kiosk-os cd daynivo-kiosk-os sudo ./install.sh --url "https://schermen-ijsselflat.voxip.nl" --name "IJsselflat" --hostname ijsselflat ``` Alle opties zijn optioneel. Het script installeert de benodigde pakketten, maakt de gebruikers `kiosk` en `voxip` aan, installeert de services en start de kiosk. Aan het eind toont het de setupcode. Draaide hier eerder de Daynivo-kiosk (`raspberry-pi/install-kiosk.sh` uit de Daynivo-repository)? Dan neemt `install.sh` de display-URL (inclusief `?token=`) automatisch over en schakelt `display-kiosk.service` uit. ### Updaten ```bash cd daynivo-kiosk-os sudo ./update.sh # git pull --ff-only + back-up van /etc/voxip-kiosk + install.sh --upgrade ``` Een update overschrijft nooit bestaande configuratie of het beheerderswachtwoord. Back-ups staan in `/var/backups/voxip-kiosk-*.tar.gz` (de laatste vijf). Op een apparaat met de image staat de broncode in `/usr/src/voxip-kiosk`. Clone de repository voor updates naar een eigen map, of pak een release uit en draai daar `sudo ./update.sh --no-pull`. ### Verwijderen ```bash sudo ./uninstall.sh # programma's en services weg, configuratie blijft sudo ./uninstall.sh --purge # ook configuratie, status, logs, netwerkprofielen en gebruikers ``` ## Image bouwen Het image wordt gebouwd met [pi-gen](https://github.com/RPi-Distro/pi-gen), de officiële bouwtool van Raspberry Pi OS. De extra stage `image/stage-voxip` voert hetzelfde `install.sh` uit als een handmatige installatie. Vereist: een Linux-buildmachine (x86_64 of arm64) met Docker en git. Op x86_64 is ook `binfmt`/qemu nodig voor ARM-emulatie: ```bash sudo apt-get install -y qemu-user-static binfmt-support # alleen op x86_64 ./image/build.sh # bouwt in Docker # of zonder Docker, op Debian/Ubuntu met de pi-gen-afhankelijkheden: sudo ./image/build.sh --native ``` Resultaat: `image/deploy/-daynivo-kiosk-os-.img.xz` plus een `.sha256` en `BUILD-INFO-.txt`. Instelbaar via omgevingsvariabelen: | Variabele | Standaard | Betekenis | |---|---|---| | `PI_GEN_REF` | `2024-11-19-raspios-bookworm-armhf` | pi-gen-tag (32-bit) | | `RELEASE` | `bookworm` | `bookworm` of `trixie` (moet bij `PI_GEN_REF` passen) | | `VOXIP_DEFAULT_URL` | `https://schermen-ijsselflat.voxip.nl` | standaard kiosk-URL | | `VOXIP_DEVICE_NAME` | `Daynivo Kiosk` | standaard apparaatnaam | | `TARGET_HOSTNAME` | `kiosk` | hostname (`http://.local:8080`) | | `ALLOW_DIRTY` | `0` | `1` = bouw de werkmap in plaats van de laatste commit | **Reproduceerbaarheid.** pi-gen staat vast op een tag en de broncode gaat via `git archive` van één commit mee. Beide staan in `BUILD-INFO` (ook in de image: `/usr/share/voxip-kiosk/BUILD-INFO`). De Debian- en Raspberry Pi-pakketten komen uit de archieven zoals die op het moment van bouwen zijn. Er bestaat geen snapshot-archief voor Raspberry Pi OS, dus twee builds op verschillende dagen kunnen nieuwere pakketversies bevatten. Bewaar voor een uitrol daarom de gebouwde `.img.xz` zelf. ## Beheer ### Webinterface — `http://.local:8080` | Pagina | Functies | |---|---| | **Dashboard** | Chromium-status, kiosk-URL, uptime, CPU, temperatuur, voeding (onderspanning), RAM, SD-kaart, IP-adressen, verbinding, versie. Grote knoppen voor *Pagina herladen*, *Chromium herstarten* en *Raspberry Pi herstarten*. | | **Kiosk** | URL (alleen HTTPS), apparaatnaam, automatisch verversen, browserprofiel, herstart na crash, screenshot van het scherm, laatste meldingen. | | **Systeem** | Herstarten, veilig uitschakelen, hostname, rotatie, resolutie, zoom, screensaver/DPMS, poort/HTTPS van de beheerinterface. | | **Netwerk** | Status van ethernet en wifi, wifi scannen, wifi instellen, DHCP of statisch IP, DNS, wifi-land. Iedere wijziging moet binnen 3 minuten bevestigd worden, anders volgt een rollback. | | **Logboek** | Logs per onderdeel (kiosk, Chromium, agent, healthcheck, beheer, netwerk, systeem). | *Pagina herladen* gebruikt het Chrome DevTools Protocol op localhost: de browser blijft draaien. *Chromium herstarten* herstart alleen de browser. *Raspberry Pi herstarten* herstart het hele systeem. ### Commandoregel (via SSH) ```bash sudo voxip-kiosk-ctl status # overzicht sudo voxip-kiosk-ctl setup-code # setupcode voor de eerste configuratie sudo voxip-kiosk-ctl reset-password # wachtwoord vergeten: nieuwe setupcode sudo voxip-kiosk-ctl set-url https://… # URL wijzigen sudo voxip-kiosk-ctl reload # pagina herladen sudo voxip-kiosk-ctl restart-browser # Chromium herstarten sudo voxip-kiosk-ctl health # healthcheck-rapport sudo voxip-kiosk-ctl maintenance on|off # healthcheck tijdelijk niets laten herstellen journalctl -u voxip-kiosk-browser -u voxip-kiosk-agent -f ``` ### Configuratie — `/etc/voxip-kiosk/config.json` | Sleutel | Standaard | Betekenis | |---|---|---| | `device_name` | `Daynivo Kiosk` | naam in beheer en op de offlinepagina | | `url` | `https://schermen-ijsselflat.voxip.nl` | kiosk-URL, alleen HTTPS | | `refresh_interval` | `0` | 0 = uit, anders 30–86400 seconden | | `screen_always_on` | `true` | geen screensaver/DPMS | | `screen_off_minutes` | `10` | scherm uit na N minuten (als `screen_always_on` uit staat) | | `rotation` | `0` | 0, 90, 180, 270 | | `resolution` | `auto` | `auto` of bijv. `1920x1080` / `1280x720@60` | | `zoom` | `1.0` | 0,25–4, schaalt de pagina (grote tv's) | | `browser_restart` | `true` | Chromium automatisch herstarten na een crash | | `browser_profile` | `persistent` | `persistent` = cookies en offline-cache blijven bewaard, `ephemeral` = alleen in RAM | | `admin_port` | `8080` | poort van de beheerinterface | | `admin_https` | `false` | HTTPS met zelfondertekend certificaat | | `admin_allow_public` | `false` | ook toegang vanaf publieke IP-adressen (afgeraden) | Wijzigingen via de webinterface of `voxip-kiosk-ctl` worden atomair opgeslagen, met een `.bak` van de vorige versie. Een URL-wijziging gaat in zonder dat Chromium herstart. Scherminstellingen gelden na een herstart van Chromium (een vinkje in de webinterface doet dat direct). ## Uitrol bij meerdere klanten Eén image voor alle klanten. Per apparaat zet je na het flashen op de bootpartitie (`bootfs`, zichtbaar op Windows en macOS): - **`voxip-config.json`**: instellingen voor deze kiosk, plus optioneel `hostname` en `wifi_country`. Een voorbeeld staat als `voxip-config.example.json` op de bootpartitie. - **`voxip-authorized_keys`**: openbare SSH-sleutels. SSH gaat dan aan, alleen met sleutel-login. - Wifi en een eigen gebruiker stel je in via Raspberry Pi Imager. De bestanden worden bij het opstarten verwerkt en hernoemd naar `*.applied`, of naar `*.rejected` met de reden in `voxip-config.error.txt`. ### Daynivo-schermen Voor een Daynivo-display gebruik je als `url` de kiosk-URL van het scherm uit Daynivo (*Schermen* → scherm → kiosk-URL, inclusief `?token=`). Het token wordt in de webinterface, de CLI en de logs afgeschermd (`?token=…ab12`). De kiosk laat een lopende pagina staan als het netwerk wegvalt. Daynivo toont dan zijn eigen laatst bekende inhoud, en automatisch verversen wordt overgeslagen zolang de server niet bereikbaar is. ## Ontwikkelen en testen ```bash python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt .venv/bin/python -m pytest # unit- en webtests make lint # shellcheck (indien geïnstalleerd) make test-bookworm # dezelfde tests in Debian Bookworm met de apt-pakketten van de Pi (Docker) ``` Lokaal draaien van de webinterface (zonder Pi; systeemacties falen netjes): ```bash make dev # http://127.0.0.1:8080 met tijdelijke mappen in .dev/ ``` ## Probleemoplossing | Symptoom | Oplossing | |---|---| | Zwart scherm na opstarten | `sudo voxip-kiosk-ctl status`. Kijk in de journal van `voxip-kiosk-x`/`voxip-kiosk-browser`. Staat de monitor aan vóór de Pi? | | Beheerinterface onbereikbaar na netwerkwijziging | Wacht 3 minuten (automatische rollback) of zet `voxip-network-reset` op de bootpartitie en herstart. | | Wachtwoord vergeten | `sudo voxip-kiosk-ctl reset-password` via SSH, of verwijder `/etc/voxip-kiosk/admin.json` met de SD-kaart in een Linux-pc. | | `kiosk.local` werkt niet | Gebruik het IP-adres (staat op het setupscherm en in je router). Windows heeft soms Bonjour/mDNS nodig. Geef iedere kiosk een unieke hostname. | | Onderspanning in het dashboard | Gebruik de officiële 5,1 V/2,5 A-voeding. Onderspanning veroorzaakt crashes en SD-kaartcorruptie. |