BetterFrame/kiosk/src/main.rs
Mitchell R 908fd417c0
refactor(kiosk): migrate all bundle IDs to String for UUIDv7 + ONVIF image proxy
- All bundle struct ID fields (kiosk_id, display_id, layout_id,
  camera_id, stream_id, gpio_id) now String with de_flexible_id
  deserializer accepting both JSON numbers and strings.
- PoolKey, DisplayState hashmap, WorkerMsg, ServerMsg all use String
  IDs throughout. Zero u32 ID references remain.
- ONVIF event image proxy: kiosk detects PictureUri in event data,
  downloads image from camera (basic/digest auth), base64 encodes,
  attaches to event payload before forwarding to server.
- Add md5 crate for HTTP Digest auth on camera image fetch.
- ws_client: flexible_id_from_value helper for WS message ID parsing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-26 13:09:32 +02:00

71 lines
2 KiB
Rust

mod at_rest;
mod axiom;
mod bundle;
mod cec;
mod firmware;
mod gpio;
mod hwmon;
mod local_server;
mod onvif_events;
mod os_update;
mod pipeline;
mod remote_debug;
mod server;
mod ui;
mod ws_client;
pub use ui::WorkerMsg;
pub enum ServerMsg {
ReloadBundle,
Standby(Option<String>),
Wake(Option<String>),
/// Some(0..=255) = manual PWM. None = restore auto.
Fan(Option<u32>),
/// Switch to a specific layout by ID, optionally scoped to one display.
SwitchLayout {
display_id: Option<String>,
layout_id: String,
},
/// Server-pushed "go check for a firmware update now".
FirmwareCheck,
/// Server-pushed "go check for an OS update now".
OsCheck,
/// Show terminal auth code on screen (overlay).
ShowTerminalCode(String),
/// Dismiss the terminal code overlay.
DismissTerminalCode,
}
use gstreamer::prelude::PluginFeatureExtManual;
use gtk4::prelude::{ApplicationExt, ApplicationExtManual};
use tracing::info;
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
fn main() {
let env_filter = EnvFilter::from_default_env()
.add_directive("betterframe_kiosk=info".parse().unwrap());
let registry = tracing_subscriber::registry()
.with(env_filter)
.with(tracing_subscriber::fmt::layer());
if let Some(axiom_layer) = axiom::AxiomLayer::new() {
info!("axiom logging enabled");
registry.with(axiom_layer).init();
} else {
registry.init();
}
gstreamer::init().expect("Failed to init GStreamer");
// Demote Pi5 hw H265 decoder — rejects non-standard resolutions like 960x1080
if let Some(factory) = gstreamer::ElementFactory::find("v4l2slh265dec") {
factory.set_rank(gstreamer::Rank::NONE);
info!("demoted v4l2slh265dec to NONE (sw fallback)");
}
let app = ui::build_app();
// Pass empty args to GTK — server URL handled via env or argv directly
app.set_flags(gtk4::gio::ApplicationFlags::NON_UNIQUE);
std::process::exit(app.run_with_args::<&str>(&[]).into());
}