mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 20:16:35 +00:00
New kiosk/src/onvif_events.rs: for each ONVIF camera in the bundle,
creates a PullPoint subscription, polls every 3s, parses
NotificationMessage XML into structured JSON (topic + source key/values
+ data key/values + timestamp), and POSTs to /api/kiosk/event with
source_type=onvif + camera_id.
Forwards ALL event topics: motion, ANPR (LicensePlateRecognition),
line crossing, intrusion, digital input, analytics, tamper — everything
the camera exposes. Node-RED sorts what matters.
Subscription lifecycle:
- CreatePullPointSubscription with 60s InitialTerminationTime
- Renew every 55s before timeout
- Unsubscribe on bundle change / shutdown
- Auto-resubscribe on pull/renew failure (30s backoff)
- Generation tracking via Weak<()> so old workers self-terminate
when start() is called with a new bundle
WSSE PasswordDigest auth for SOAP calls — same scheme the server's
onvif.ts uses. sha1 crate added.
BundleCamera extended with onvif_host/port/username/password_encrypted
fields (server already ships them; kiosk just wasn't deserializing).
Gated by BF_ENABLE_ONVIF_EVENTS=1. Enabled by default in the pi-gen
image env file.
TODO: cluster-key-based decryption of onvif_password_encrypted. For
now relies on the RTSP URI having plaintext credentials embedded (which
the ONVIF import path already ensures via rtspWithCredentials).
55 lines
1.5 KiB
Rust
55 lines
1.5 KiB
Rust
mod at_rest;
|
|
mod bundle;
|
|
mod cec;
|
|
mod firmware;
|
|
mod gpio;
|
|
mod hwmon;
|
|
mod local_server;
|
|
mod onvif_events;
|
|
mod os_update;
|
|
mod pipeline;
|
|
mod server;
|
|
mod ui;
|
|
mod ws_client;
|
|
|
|
pub use ui::WorkerMsg;
|
|
|
|
pub enum ServerMsg {
|
|
ReloadBundle,
|
|
Standby(Option<u32>),
|
|
Wake(Option<u32>),
|
|
/// 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<u32>,
|
|
layout_id: u32,
|
|
},
|
|
/// Server-pushed "go check for a firmware update now".
|
|
FirmwareCheck,
|
|
}
|
|
|
|
use gstreamer::prelude::PluginFeatureExtManual;
|
|
use gtk4::prelude::{ApplicationExt, ApplicationExtManual};
|
|
use tracing::info;
|
|
use tracing_subscriber::EnvFilter;
|
|
|
|
fn main() {
|
|
tracing_subscriber::fmt()
|
|
.with_env_filter(
|
|
EnvFilter::from_default_env().add_directive("betterframe_kiosk=info".parse().unwrap()),
|
|
)
|
|
.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());
|
|
}
|