//! # DBus interface proxy for: `org.freedesktop.UPower.Device` //! //! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data. //! Source: `Interface '/org/freedesktop/UPower/devices/DisplayDevice' from service 'org.freedesktop.UPower' on system bus`. use cosmic::iced::{ self, futures::{SinkExt, StreamExt}, subscription, }; use std::{fmt::Debug, hash::Hash}; use zbus::dbus_proxy; use crate::upower::UPowerProxy; #[dbus_proxy( default_service = "org.freedesktop.UPower", interface = "org.freedesktop.UPower.Device" )] trait Device { /// GetHistory method fn get_history( &self, type_: &str, timespan: u32, resolution: u32, ) -> zbus::Result>; /// GetStatistics method fn get_statistics(&self, type_: &str) -> zbus::Result>; /// Refresh method fn refresh(&self) -> zbus::Result<()>; /// BatteryLevel property #[dbus_proxy(property)] fn battery_level(&self) -> zbus::Result; /// Capacity property #[dbus_proxy(property)] fn capacity(&self) -> zbus::Result; /// ChargeCycles property #[dbus_proxy(property)] fn charge_cycles(&self) -> zbus::Result; /// Energy property #[dbus_proxy(property)] fn energy(&self) -> zbus::Result; /// EnergyEmpty property #[dbus_proxy(property)] fn energy_empty(&self) -> zbus::Result; /// EnergyFull property #[dbus_proxy(property)] fn energy_full(&self) -> zbus::Result; /// EnergyFullDesign property #[dbus_proxy(property)] fn energy_full_design(&self) -> zbus::Result; /// EnergyRate property #[dbus_proxy(property)] fn energy_rate(&self) -> zbus::Result; /// HasHistory property #[dbus_proxy(property)] fn has_history(&self) -> zbus::Result; /// HasStatistics property #[dbus_proxy(property)] fn has_statistics(&self) -> zbus::Result; /// IconName property #[dbus_proxy(property)] fn icon_name(&self) -> zbus::Result; /// IsPresent property #[dbus_proxy(property)] fn is_present(&self) -> zbus::Result; /// IsRechargeable property #[dbus_proxy(property)] fn is_rechargeable(&self) -> zbus::Result; /// Luminosity property #[dbus_proxy(property)] fn luminosity(&self) -> zbus::Result; /// Model property #[dbus_proxy(property)] fn model(&self) -> zbus::Result; /// NativePath property #[dbus_proxy(property)] fn native_path(&self) -> zbus::Result; /// Online property #[dbus_proxy(property)] fn online(&self) -> zbus::Result; /// Percentage property #[dbus_proxy(property)] fn percentage(&self) -> zbus::Result; /// PowerSupply property #[dbus_proxy(property)] fn power_supply(&self) -> zbus::Result; /// Serial property #[dbus_proxy(property)] fn serial(&self) -> zbus::Result; /// State property #[dbus_proxy(property)] fn state(&self) -> zbus::Result; /// Technology property #[dbus_proxy(property)] fn technology(&self) -> zbus::Result; /// Temperature property #[dbus_proxy(property)] fn temperature(&self) -> zbus::Result; /// TimeToEmpty property #[dbus_proxy(property)] fn time_to_empty(&self) -> zbus::Result; /// TimeToFull property #[dbus_proxy(property)] fn time_to_full(&self) -> zbus::Result; /// Type property #[dbus_proxy(property)] fn type_(&self) -> zbus::Result; /// UpdateTime property #[dbus_proxy(property)] fn update_time(&self) -> zbus::Result; /// Vendor property #[dbus_proxy(property)] fn vendor(&self) -> zbus::Result; /// Voltage property #[dbus_proxy(property)] fn voltage(&self) -> zbus::Result; /// WarningLevel property #[dbus_proxy(property)] fn warning_level(&self) -> zbus::Result; } pub fn device_subscription( id: I, ) -> iced::Subscription { subscription::channel(id, 50, move |mut output| async move { let mut state = State::Ready; loop { state = start_listening(state, &mut output).await; } }) } #[derive(Debug)] pub enum State { Ready, Waiting(UPowerProxy<'static>, DeviceProxy<'static>), Finished, } async fn display_device() -> zbus::Result<(UPowerProxy<'static>, DeviceProxy<'static>)> { let connection = zbus::Connection::system().await?; let upower: UPowerProxy<'_> = UPowerProxy::new(&connection).await?; let device_path = upower.get_display_device().await?; DeviceProxy::builder(&connection) .path(device_path)? .cache_properties(zbus::CacheProperties::Yes) .build() .await .map(|dp| (upower, dp)) } async fn start_listening( state: State, output: &mut futures::channel::mpsc::Sender, ) -> State { match state { State::Ready => { if let Ok((upower, device)) = display_device().await { _ = output .send(DeviceDbusEvent::Update { on_battery: upower .cached_on_battery() .unwrap_or_default() .unwrap_or_default(), percent: device .cached_percentage() .unwrap_or_default() .unwrap_or_default(), time_to_empty: device .cached_time_to_empty() .unwrap_or_default() .unwrap_or_default(), }) .await; return State::Waiting(upower, device); } State::Finished } State::Waiting(upower, device) => { let mut stream = futures::stream_select!( upower.receive_on_battery_changed().await.map(|_| ()), device.receive_percentage_changed().await.map(|_| ()), device.receive_time_to_empty_changed().await.map(|_| ()), ); match stream.next().await { Some(_) => { _ = output .send(DeviceDbusEvent::Update { on_battery: upower .cached_on_battery() .unwrap_or_default() .unwrap_or_default(), percent: device .cached_percentage() .unwrap_or_default() .unwrap_or_default(), time_to_empty: device .cached_time_to_empty() .unwrap_or_default() .unwrap_or_default(), }) .await; State::Waiting(upower, device) } None => State::Finished, } } State::Finished => iced::futures::future::pending().await, } } #[derive(Debug, Clone)] pub enum DeviceDbusEvent { Update { on_battery: bool, percent: f64, time_to_empty: i64, }, }