More error handling.

This commit is contained in:
lennard
2023-06-10 12:18:06 +02:00
parent 729b903c31
commit 06015646e9
3 changed files with 54 additions and 40 deletions

View File

@@ -4,20 +4,27 @@ use ksni::{Tray, MenuItem, menu::{StandardItem}, ToolTip};
pub struct BatteryTray { pub struct BatteryTray {
battery_level: u8, battery_level: u8,
charging: bool, charging: bool,
device_found: bool,
} }
impl BatteryTray { impl BatteryTray {
pub fn new(battery_level: u8, charging: bool) -> Self { pub fn new() -> Self {
BatteryTray { BatteryTray {
battery_level, battery_level: 0,
charging, charging: false,
device_found: false,
} }
} }
pub fn update(&mut self, battery_level: u8, charging: bool) { pub fn update(&mut self, battery_level: u8, charging: bool) {
self.device_found = true;
self.battery_level = battery_level; self.battery_level = battery_level;
self.charging = charging; self.charging = charging;
} }
pub fn no_device_found(&mut self) {
self.device_found = false;
}
} }
impl Tray for BatteryTray { impl Tray for BatteryTray {
@@ -36,11 +43,14 @@ impl Tray for BatteryTray {
] ]
} }
fn tool_tip(&self) -> ToolTip { fn tool_tip(&self) -> ToolTip {
let description = if self.charging { let description =
format!("Battery level: {}%\nCharging", self.battery_level) if !self.device_found {
} else { "No device found".to_string()
format!("Battery level: {}%\nNot charging", self.battery_level) } else if self.charging {
}; format!("Battery level: {}%\nCharging", self.battery_level)
} else {
format!("Battery level: {}%\nNot charging", self.battery_level)
};
ToolTip { ToolTip {
title: "HyperX Cloud II".to_string(), title: "HyperX Cloud II".to_string(),
description: description, description: description,

View File

@@ -26,8 +26,8 @@ pub enum DeviceError {
NoDeviceFound(), NoDeviceFound(),
#[error("Error: No response. Is the headset turned on?")] #[error("Error: No response. Is the headset turned on?")]
HeadSetOff(), HeadSetOff(),
#[error("Error: Unknown response.")] #[error("Error: Unknown response: {0:?}")]
UnknownResponse(), UnknownResponse([u8; 8]),
} }
pub struct Device { pub struct Device {
@@ -50,17 +50,17 @@ impl Device {
pub fn get_battery_level(&self) -> Result<(u8, bool), DeviceError> { pub fn get_battery_level(&self) -> Result<(u8, bool), DeviceError> {
self.hid_device.write(&BATTERY_PACKET)?; self.hid_device.write(&BATTERY_PACKET)?;
let mut buf = [0u8; 8]; let mut buf = [0u8; 8];
let res = self.hid_device.read_timeout(&mut buf[..], 1000)?; let res = self.hid_device.read_timeout(&mut buf[..], 800)?;
if res == 0 { if res == 0 {
return Err(DeviceError::HeadSetOff()); return Err(DeviceError::HeadSetOff());
} }
if !buf.starts_with(&PREAMBLE) { if !buf.starts_with(&PREAMBLE) {
return Err(DeviceError::UnknownResponse()); return Err(DeviceError::UnknownResponse(buf));
} }
let charging = match buf[CHARGING_INDEX] { let charging = match buf[CHARGING_INDEX] {
CHARGING_STATE => true, CHARGING_STATE => true,
NOT_CHARGING_STATE => false, NOT_CHARGING_STATE => false,
_ => return Err(DeviceError::UnknownResponse()), _ => return Err(DeviceError::UnknownResponse(buf)),
}; };
Ok((buf[BATTERY_LEVEL_INDEX], charging)) Ok((buf[BATTERY_LEVEL_INDEX], charging))
} }

View File

@@ -1,46 +1,50 @@
use hyper_x_cloud_ii_wireless::Device; use hyper_x_cloud_ii_wireless::{Device, DeviceError};
use ksni::TrayService; use ksni::TrayService;
use battery_tray::BatteryTray;
mod battery_tray; mod battery_tray;
use battery_tray::BatteryTray;
fn pair_device() -> Device {
loop {
match Device::new() {
Ok(device) => break device,
Err(error) => {
eprintln!("{error}");
}
};
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
fn main() { fn main() {
let device = match Device::new() { let service = TrayService::new(BatteryTray::new());
Ok(device) => device,
Err(error) => {
eprintln!("{error}");
std::process::exit(1);
}
};
let (battery_level, charging) = match device.get_battery_level() {
Ok(t) => t,
Err(error) => {
eprintln!("{error}");
std::process::exit(1);
}
};
println!("Battery level: {}%", battery_level);
if charging {
println!("Charging");
} else {
println!("Not charging");
}
let service = TrayService::new(BatteryTray::new(battery_level, charging));
let handle = service.handle(); let handle = service.handle();
service.spawn(); service.spawn();
let mut device = pair_device();
// Run loop // Run loop
loop { loop {
std::thread::sleep(std::time::Duration::from_secs(1)); std::thread::sleep(std::time::Duration::from_secs(1));
let (battery_level, charging) = match device.get_battery_level() { let (battery_level, charging) = match device.get_battery_level() {
Ok(t) => t, Ok(t) => t,
Err(DeviceError::HidError(hidapi::HidError::HidApiError { message })) => {
eprintln!("Error: {message}");
if message == "No such device" {
handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); });
device = pair_device();
}
continue;
}
Err(DeviceError::NoDeviceFound()) => {
eprintln!("Error: {}", DeviceError::NoDeviceFound());
handle.update(|tray: &mut BatteryTray| { tray.no_device_found(); });
continue;
}
Err(error) => { Err(error) => {
eprintln!("{error}"); eprintln!("{error}");
continue; continue;
} }
}; };
handle.update(|tray: &mut BatteryTray| { handle.update(|tray: &mut BatteryTray| { tray.update(battery_level, charging); });
tray.update(battery_level, charging);
});
} }
} }