lesavka: refresh live eye detection
This commit is contained in:
parent
64f6ab3336
commit
fc38925f0d
@ -4,7 +4,7 @@ path = "src/main.rs"
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_client"
|
name = "lesavka_client"
|
||||||
version = "0.11.20"
|
version = "0.11.21"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -81,6 +81,7 @@ fn print_state(state: lesavka_common::lesavka::CapturePowerState) {
|
|||||||
println!("available={}", state.available);
|
println!("available={}", state.available);
|
||||||
println!("enabled={}", state.enabled);
|
println!("enabled={}", state.enabled);
|
||||||
println!("mode={}", state.mode);
|
println!("mode={}", state.mode);
|
||||||
|
println!("detected_devices={}", state.detected_devices);
|
||||||
println!("active_leases={}", state.active_leases);
|
println!("active_leases={}", state.active_leases);
|
||||||
println!("unit={}", state.unit);
|
println!("unit={}", state.unit);
|
||||||
println!("detail={}", state.detail);
|
println!("detail={}", state.detail);
|
||||||
|
|||||||
@ -738,6 +738,8 @@ pub fn run_gui_launcher(server_addr: String) -> Result<()> {
|
|||||||
let caps_request_in_flight = Rc::new(Cell::new(false));
|
let caps_request_in_flight = Rc::new(Cell::new(false));
|
||||||
let diagnostics_network = Rc::new(RefCell::new(NetworkTelemetry::default()));
|
let diagnostics_network = Rc::new(RefCell::new(NetworkTelemetry::default()));
|
||||||
let diagnostics_process = Rc::new(RefCell::new(ProcessCpuSampler::new()));
|
let diagnostics_process = Rc::new(RefCell::new(ProcessCpuSampler::new()));
|
||||||
|
let next_power_probe =
|
||||||
|
Rc::new(Cell::new(Instant::now() + Duration::from_millis(500)));
|
||||||
let next_diagnostics_probe =
|
let next_diagnostics_probe =
|
||||||
Rc::new(Cell::new(Instant::now() + Duration::from_millis(250)));
|
Rc::new(Cell::new(Instant::now() + Duration::from_millis(250)));
|
||||||
let next_diagnostics_sample =
|
let next_diagnostics_sample =
|
||||||
@ -1891,6 +1893,21 @@ pub fn run_gui_launcher(server_addr: String) -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
|
let child_running = child_proc.borrow().is_some();
|
||||||
|
|
||||||
|
if now >= next_power_probe.get()
|
||||||
|
&& !power_request_in_flight.get()
|
||||||
|
&& (child_running
|
||||||
|
|| state.borrow().capture_power.enabled
|
||||||
|
|| state.borrow().remote_active)
|
||||||
|
{
|
||||||
|
power_request_in_flight.set(true);
|
||||||
|
let server_addr =
|
||||||
|
selected_server_addr(&server_entry, server_addr_fallback.as_ref());
|
||||||
|
request_capture_power_refresh(power_tx.clone(), server_addr, Duration::ZERO);
|
||||||
|
next_power_probe.set(now + Duration::from_secs(2));
|
||||||
|
}
|
||||||
|
|
||||||
if now >= next_diagnostics_probe.get() && !caps_request_in_flight.get() {
|
if now >= next_diagnostics_probe.get() && !caps_request_in_flight.get() {
|
||||||
caps_request_in_flight.set(true);
|
caps_request_in_flight.set(true);
|
||||||
let server_addr =
|
let server_addr =
|
||||||
@ -1915,7 +1932,6 @@ pub fn run_gui_launcher(server_addr: String) -> Result<()> {
|
|||||||
next_diagnostics_sample.set(now + Duration::from_secs(1));
|
next_diagnostics_sample.set(now + Duration::from_secs(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
let child_running = child_proc.borrow().is_some();
|
|
||||||
refresh_launcher_ui(&widgets, &state.borrow(), child_running);
|
refresh_launcher_ui(&widgets, &state.borrow(), child_running);
|
||||||
refresh_test_buttons(&widgets, &mut tests.borrow_mut());
|
refresh_test_buttons(&widgets, &mut tests.borrow_mut());
|
||||||
glib::ControlFlow::Continue
|
glib::ControlFlow::Continue
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "lesavka_common"
|
name = "lesavka_common"
|
||||||
version = "0.11.20"
|
version = "0.11.21"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn banner_includes_version() {
|
fn banner_includes_version() {
|
||||||
assert_eq!(banner("0.11.20"), "lesavka-common CLI (v0.11.20)");
|
assert_eq!(banner("0.11.21"), "lesavka-common CLI (v0.11.21)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,7 @@ bench = false
|
|||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "lesavka_server"
|
name = "lesavka_server"
|
||||||
version = "0.11.20"
|
version = "0.11.21"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
autobins = false
|
autobins = false
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#[allow(clippy::useless_attribute)]
|
#[allow(clippy::useless_attribute)]
|
||||||
#[forbid(unsafe_code)]
|
#[forbid(unsafe_code)]
|
||||||
use futures_util::{Stream, StreamExt};
|
use futures_util::{Stream, StreamExt};
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||||
@ -112,15 +113,59 @@ impl Handler {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn detected_capture_devices() -> u32 {
|
fn detected_capture_devices_from_symlinks() -> u32 {
|
||||||
["/dev/lesavka_l_eye", "/dev/lesavka_r_eye"]
|
["/dev/lesavka_l_eye", "/dev/lesavka_r_eye"]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|path| Path::new(path).exists())
|
.filter(|path| Path::new(path).exists())
|
||||||
.count() as u32
|
.count() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_detected_capture_devices(mut state: CapturePowerState) -> CapturePowerState {
|
fn detected_capture_devices_from_udev() -> u32 {
|
||||||
state.detected_devices = Self::detected_capture_devices();
|
let Ok(mut enumerator) = udev::Enumerator::new() else {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
let _ = enumerator.match_subsystem("video4linux");
|
||||||
|
let Ok(devices) = enumerator.scan_devices() else {
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
devices
|
||||||
|
.filter(|device| {
|
||||||
|
device
|
||||||
|
.attribute_value("index")
|
||||||
|
.and_then(|value| value.to_str())
|
||||||
|
== Some("0")
|
||||||
|
&& device
|
||||||
|
.property_value("ID_VENDOR_ID")
|
||||||
|
.and_then(|value| value.to_str())
|
||||||
|
== Some("07ca")
|
||||||
|
&& device
|
||||||
|
.property_value("ID_MODEL_ID")
|
||||||
|
.and_then(|value| value.to_str())
|
||||||
|
== Some("3311")
|
||||||
|
})
|
||||||
|
.count()
|
||||||
|
.min(2) as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn active_eye_source_count(&self) -> u32 {
|
||||||
|
self.eye_hubs
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(key, hub)| {
|
||||||
|
hub.running
|
||||||
|
.load(Ordering::Relaxed)
|
||||||
|
.then_some(key.source_id)
|
||||||
|
})
|
||||||
|
.collect::<HashSet<_>>()
|
||||||
|
.len()
|
||||||
|
.min(2) as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn with_detected_capture_devices(&self, mut state: CapturePowerState) -> CapturePowerState {
|
||||||
|
state.detected_devices = Self::detected_capture_devices_from_udev()
|
||||||
|
.max(Self::detected_capture_devices_from_symlinks())
|
||||||
|
.max(self.active_eye_source_count().await);
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,12 +340,12 @@ impl Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_capture_power_reply(&self) -> Result<Response<CapturePowerState>, Status> {
|
async fn get_capture_power_reply(&self) -> Result<Response<CapturePowerState>, Status> {
|
||||||
self.capture_power
|
let state = self
|
||||||
|
.capture_power
|
||||||
.snapshot()
|
.snapshot()
|
||||||
.await
|
.await
|
||||||
.map(Self::with_detected_capture_devices)
|
.map_err(|e| Status::internal(format!("{e:#}")))?;
|
||||||
.map(Response::new)
|
Ok(Response::new(self.with_detected_capture_devices(state).await))
|
||||||
.map_err(|e| Status::internal(format!("{e:#}")))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_capture_power_reply(
|
async fn set_capture_power_reply(
|
||||||
@ -316,10 +361,8 @@ impl Handler {
|
|||||||
CapturePowerCommand::ForceOff => self.capture_power.set_manual(false).await,
|
CapturePowerCommand::ForceOff => self.capture_power.set_manual(false).await,
|
||||||
CapturePowerCommand::Unspecified => self.capture_power.set_manual(req.enabled).await,
|
CapturePowerCommand::Unspecified => self.capture_power.set_manual(req.enabled).await,
|
||||||
};
|
};
|
||||||
result
|
let state = result.map_err(|e| Status::internal(format!("{e:#}")))?;
|
||||||
.map(Self::with_detected_capture_devices)
|
Ok(Response::new(self.with_detected_capture_devices(state).await))
|
||||||
.map(Response::new)
|
|
||||||
.map_err(|e| Status::internal(format!("{e:#}")))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user