Commit graph

9 commits

Author SHA1 Message Date
Mitchell R
411d9900a9
chore: target latest-stable everywhere — Debian Trixie + gtk4 v4_14
- CI workflow container: debian:trixie-slim (was bookworm-slim)
- Server image base: node:23-trixie-slim (was bookworm-slim)
- Kiosk Cargo.toml: gtk4 features v4_14 (was v4_8) — matches Trixie's
  stock gtk 4.14 without backports juggling
- setup-pi-kiosk.sh header: Trixie+ target (was Bookworm+)

Glibc matches across Pi OS Trixie, Coolify host (Trixie), CI build
container — no symbol drift at runtime.
2026-05-19 04:21:14 +02:00
Mitchell R
b2f61d2bc9
fix(kiosk): build against stock bookworm gtk 4.8.3 (drop v4_12 feature)
Pi OS Bookworm + Debian bookworm both ship libgtk-4 4.8.3. No code in
the kiosk uses 4.12+ APIs (compute_bounds, WidgetPaintable, Picture,
add_tick_callback, Fixed, set_content_fit are all <= 4.8). Swap
gtk4 feature v4_12 → v4_8 and drop the bookworm-backports juggling
in CI.
2026-05-19 04:18:54 +02:00
Mitchell R
6a8f6d76af feat(kiosk): LAN-side local HTTP server (GET layout API + admin proxy)
Kiosk now exposes :18090 with two surfaces:

- GET /local/layout/:id?key=<kiosk_local_key>
  Bookmark-friendly layout switch on this kiosk. Auth = kiosk-generated
  local key (32 random bytes, hex, stored at <state_dir>/local.key).

- ANY /proxy/* — forwards to BF server with the request's Authorization
  header preserved. Lets LAN clients reach a cloud-hosted BF server via
  the kiosk's local socket; kiosk adds no auth of its own.

Heartbeat reports {local_key, local_port}; kiosks table grows
local_key/local_port/local_last_ip columns. Admin kiosk edit page now
shows the local URLs as a copy-paste block.

Override port: BF_KIOSK_LOCAL_PORT. Disable: BF_KIOSK_LOCAL_DISABLE=1.
2026-05-14 07:24:21 +02:00
Mitchell R
e5009fdd14 feat(ota): replacement pairing + firmware OTA (admin UI, kiosk client, CI) 2026-05-13 20:56:42 +02:00
Mitchell R
975cc184b3 feat: multi-display + snapshot + health + GPIO + nodered embed
Multi-display:
- Bundle ships displays[] each with own layouts + idle/sleep
- Rust kiosk creates one ApplicationWindow per gdk monitor
- Per-display state (layout, idle, sleep) via HashMap
- WARM_CAMERAS pool shared across displays
- Backward-compat top-level display/layouts still emitted

System Health (/admin/health):
- Online status, CPU temp (color-coded), fan RPM/PWM
- Bundle version mismatch detection
- 30s auto-refresh

Camera snapshot/test:
- shared/snapshot.ts: ffmpeg/gst-launch fallback, 5s timeout
- /admin/entities/:id/snapshot returns JPEG
- EntityEditPage shows live preview with Refresh

GPIO (Pi buttons/sensors):
- kiosk_gpio_bindings table + CRUD admin UI
- Bundle ships gpio_bindings[]
- kiosk/src/gpio.rs with gpiod crate, worker thread per pin
- Edge events POST to /api/kiosk/event with source_type=gpio

Layout switch fixes:
- GET aliases added so direct URL hits work
- New /admin/displays/:displayId/layout/:layoutId for multi-display
- DisplayEditPage gets "Switch Layout Now" section

Node-RED embed:
- /admin/nodered renders iframe at /nrdp/
- Sandbox attrs allow scripts/forms/popups
- Sidebar link now opens embedded view
2026-05-13 01:18:22 +02:00
Mitchell R
766bf8dee0 feat: WebKit for web/html cells + display auto-discovery via heartbeat
Rust kiosk:
- web cells now use webkit6 WebView (load_uri)
- html cells use WebView.load_html (full HTML rendering)
- query_displays() reads /sys/class/drm/ for connected HDMI/DP outputs
- Heartbeat reports display geometry every 60s

Server:
- /api/kiosk/heartbeat accepts displays array
- Syncs kiosk-reported displays to display records
- Updates dimensions when changed, creates new displays for new ports
2026-05-10 22:39:53 +02:00
Mitchell R
16ab165b06 feat: live updates via WebSocket — server pushes, kiosk reloads
Server side:
- service-coordinator-ws: full WS implementation using ws package
- Auth via ?token=<kiosk_key> query param
- Coordinator registry for cross-plugin notification
- Admin mutations call notifyKiosks() → server pushes reload-bundle
- 30s ping/pong heartbeat

Kiosk side:
- Rust ws_client with tokio runtime + tokio-tungstenite
- Auto-reconnect with exponential backoff (1s → 60s cap)
- On reload-bundle: re-fetches bundle, re-renders layout
- Pong replies to server pings

Also fix: auto-suffix kiosk name on UNIQUE collision (re-pair with
same hostname no longer fails).
2026-05-10 22:15:58 +02:00
Mitchell R
c4315917d8 fix: resolve all Rust compile errors in kiosk app 2026-05-10 20:04:43 +02:00
Mitchell R
371c023c81
feat: Rust kiosk app — GTK4 + GStreamer multi-camera display
- Server discovery (localhost → betterframe.local → cloud)
- Pairing flow with fullscreen code display
- Bundle fetch and layout rendering
- GTK4 Grid layout matching template regions
- GStreamer pipelines per camera cell via gtk4paintablesink
- Heartbeat loop in background thread
- Placeholder widgets for web/html cells
2026-05-10 04:18:40 +02:00