use std::{hash::Hash, sync::Arc};
use num_enum::{IntoPrimitive, TryFromPrimitive};
use crate::{
channel::HidppChannel,
feature::{CreatableFeature, Feature, FeatureEndpoint},
protocol::v20::Hidpp20Error,
};
pub struct BatteryStatusFeature {
endpoint: FeatureEndpoint,
}
impl CreatableFeature for BatteryStatusFeature {
const ID: u16 = 0x1000;
const STARTING_VERSION: u8 = 0;
fn new(chan: Arc<HidppChannel>, device_index: u8, feature_index: u8) -> Self {
Self {
endpoint: FeatureEndpoint::new(chan, device_index, feature_index),
}
}
}
impl Feature for BatteryStatusFeature {}
impl BatteryStatusFeature {
pub async fn get_battery_level_status(&self) -> Result<LegacyBatteryInfo, Hidpp20Error> {
let payload = self.endpoint.call(0, [0; 3]).await?.extend_payload();
Ok(LegacyBatteryInfo {
discharge_level: payload[0],
next_level: payload[1],
status: LegacyBatteryStatus::try_from(payload[2])
.map_err(|_| Hidpp20Error::UnsupportedResponse)?,
})
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub struct LegacyBatteryInfo {
pub discharge_level: u8,
pub next_level: u8,
pub status: LegacyBatteryStatus,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, IntoPrimitive, TryFromPrimitive)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
#[repr(u8)]
pub enum LegacyBatteryStatus {
Discharging = 0,
Recharging = 1,
AlmostFull = 2,
Full = 3,
SlowRecharge = 4,
InvalidBattery = 5,
ThermalError = 6,
Other = 7,
}