refactor: abstract check battery locgic into mod
This commit is contained in:
parent
e25e4df3cf
commit
14c87b57c8
147
src/main.rs
147
src/main.rs
|
@ -1,154 +1,13 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use log::{error, info};
|
||||
use manager::DeviceManager;
|
||||
use watchman::Watchman;
|
||||
|
||||
mod controller;
|
||||
mod devices;
|
||||
mod manager;
|
||||
|
||||
const BATTERY_UPDATE_INTERVAL: u64 = 60; // seconds
|
||||
const DEVICE_FETCH_INTERVAL: u64 = 5; // seconds
|
||||
|
||||
struct MemoryDevice {
|
||||
name: String,
|
||||
#[allow(unused)]
|
||||
id: u32,
|
||||
battery_level: i32,
|
||||
old_battery_level: i32,
|
||||
is_charging: bool,
|
||||
}
|
||||
|
||||
impl MemoryDevice {
|
||||
fn new(name: String, id: u32) -> Self {
|
||||
MemoryDevice {
|
||||
name,
|
||||
id,
|
||||
battery_level: -1,
|
||||
old_battery_level: 50,
|
||||
is_charging: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct BatteryChecker {
|
||||
device_manager: Arc<Mutex<DeviceManager>>,
|
||||
devices: Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
}
|
||||
|
||||
impl BatteryChecker {
|
||||
fn new() -> Self {
|
||||
BatteryChecker {
|
||||
device_manager: Arc::new(Mutex::new(DeviceManager::new())),
|
||||
devices: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&self) {
|
||||
let devices = Arc::clone(&self.devices);
|
||||
let device_manager = Arc::clone(&self.device_manager);
|
||||
|
||||
// Device fetching thread
|
||||
thread::spawn(move || loop {
|
||||
let (removed_devices, connected_devices) = {
|
||||
let mut manager = device_manager.lock().unwrap();
|
||||
manager.fetch_devices()
|
||||
};
|
||||
|
||||
{
|
||||
let mut devices = devices.lock().unwrap();
|
||||
for id in removed_devices {
|
||||
if let Some(device) = devices.remove(&id) {
|
||||
info!("Device removed: {}", device.name);
|
||||
}
|
||||
}
|
||||
|
||||
for id in &connected_devices {
|
||||
if !devices.contains_key(id) {
|
||||
if let Some(name) = device_manager.lock().unwrap().get_device_name(*id) {
|
||||
devices.insert(*id, MemoryDevice::new(name.clone(), *id));
|
||||
info!("New device: {}", name);
|
||||
} else {
|
||||
error!("Failed to get device name for id: {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !connected_devices.is_empty() {
|
||||
Self::update(&devices, &device_manager, &connected_devices);
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_secs(DEVICE_FETCH_INTERVAL));
|
||||
});
|
||||
|
||||
// Battery check thread
|
||||
loop {
|
||||
let device_ids: Vec<u32> = {
|
||||
let devices = self.devices.lock().unwrap();
|
||||
devices.keys().cloned().collect()
|
||||
};
|
||||
Self::update(&self.devices, &self.device_manager, &device_ids);
|
||||
thread::sleep(Duration::from_secs(BATTERY_UPDATE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
fn update(
|
||||
devices: &Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
manager: &Arc<Mutex<DeviceManager>>,
|
||||
device_ids: &[u32],
|
||||
) {
|
||||
let mut devices = devices.lock().unwrap();
|
||||
let manager = manager.lock().unwrap();
|
||||
|
||||
for &id in device_ids {
|
||||
if let Some(device) = devices.get_mut(&id) {
|
||||
if let Some(battery_level) = manager.get_device_battery_level(id) {
|
||||
if let Some(is_charging) = manager.is_device_charging(id) {
|
||||
info!("{} battery level: {}%", device.name, battery_level);
|
||||
info!("{} charging status: {}", device.name, is_charging);
|
||||
|
||||
device.old_battery_level = device.battery_level;
|
||||
device.battery_level = battery_level;
|
||||
device.is_charging = is_charging;
|
||||
|
||||
Self::check_notify(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_notify(device: &MemoryDevice) {
|
||||
if device.battery_level == -1 {
|
||||
return;
|
||||
}
|
||||
|
||||
if !device.is_charging
|
||||
&& (device.battery_level <= 5
|
||||
|| (device.old_battery_level > 15 && device.battery_level <= 15))
|
||||
{
|
||||
info!("{}: Battery low ({}%)", device.name, device.battery_level);
|
||||
} else if device.old_battery_level <= 99
|
||||
&& device.battery_level == 100
|
||||
&& device.is_charging
|
||||
{
|
||||
info!(
|
||||
"{}: Battery fully charged ({}%)",
|
||||
device.name, device.battery_level
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
mod watchman;
|
||||
|
||||
fn main() {
|
||||
std::env::set_var("RUST_LOG", "trace");
|
||||
pretty_env_logger::init();
|
||||
let checker = BatteryChecker::new();
|
||||
let checker = Watchman::new();
|
||||
checker.run();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::manager::DeviceManager;
|
||||
use log::{error, info};
|
||||
|
||||
const BATTERY_UPDATE_INTERVAL: u64 = 60; // seconds
|
||||
const DEVICE_FETCH_INTERVAL: u64 = 5; // seconds
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct MemoryDevice {
|
||||
pub name: String,
|
||||
#[allow(unused)]
|
||||
pub id: u32,
|
||||
pub battery_level: i32,
|
||||
pub old_battery_level: i32,
|
||||
pub is_charging: bool,
|
||||
}
|
||||
|
||||
impl MemoryDevice {
|
||||
fn new(name: String, id: u32) -> Self {
|
||||
MemoryDevice {
|
||||
name,
|
||||
id,
|
||||
battery_level: -1,
|
||||
old_battery_level: 50,
|
||||
is_charging: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Watchman {
|
||||
device_manager: Arc<Mutex<DeviceManager>>,
|
||||
devices: Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
}
|
||||
|
||||
impl Watchman {
|
||||
pub fn new() -> Self {
|
||||
Watchman {
|
||||
device_manager: Arc::new(Mutex::new(DeviceManager::new())),
|
||||
devices: Arc::new(Mutex::new(HashMap::new())),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run(&self) {
|
||||
let devices = Arc::clone(&self.devices);
|
||||
let device_manager = Arc::clone(&self.device_manager);
|
||||
|
||||
// Device fetching thread
|
||||
thread::spawn(move || loop {
|
||||
let (removed_devices, connected_devices) = {
|
||||
let mut manager = device_manager.lock().unwrap();
|
||||
manager.fetch_devices()
|
||||
};
|
||||
|
||||
{
|
||||
let mut devices = devices.lock().unwrap();
|
||||
for id in removed_devices {
|
||||
if let Some(device) = devices.remove(&id) {
|
||||
info!("Device removed: {}", device.name);
|
||||
}
|
||||
}
|
||||
|
||||
for id in &connected_devices {
|
||||
if !devices.contains_key(id) {
|
||||
if let Some(name) = device_manager.lock().unwrap().get_device_name(*id) {
|
||||
devices.insert(*id, MemoryDevice::new(name.clone(), *id));
|
||||
info!("New device: {}", name);
|
||||
} else {
|
||||
error!("Failed to get device name for id: {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !connected_devices.is_empty() {
|
||||
Self::update(&devices, &device_manager, &connected_devices);
|
||||
}
|
||||
|
||||
thread::sleep(Duration::from_secs(DEVICE_FETCH_INTERVAL));
|
||||
});
|
||||
|
||||
// Battery check thread
|
||||
loop {
|
||||
let device_ids: Vec<u32> = {
|
||||
let devices = self.devices.lock().unwrap();
|
||||
devices.keys().cloned().collect()
|
||||
};
|
||||
Self::update(&self.devices, &self.device_manager, &device_ids);
|
||||
thread::sleep(Duration::from_secs(BATTERY_UPDATE_INTERVAL));
|
||||
}
|
||||
}
|
||||
|
||||
fn update(
|
||||
devices: &Arc<Mutex<HashMap<u32, MemoryDevice>>>,
|
||||
manager: &Arc<Mutex<DeviceManager>>,
|
||||
device_ids: &[u32],
|
||||
) {
|
||||
let mut devices = devices.lock().unwrap();
|
||||
let manager = manager.lock().unwrap();
|
||||
|
||||
for &id in device_ids {
|
||||
if let Some(device) = devices.get_mut(&id) {
|
||||
if let Some(battery_level) = manager.get_device_battery_level(id) {
|
||||
if let Some(is_charging) = manager.is_device_charging(id) {
|
||||
info!("{} battery level: {}%", device.name, battery_level);
|
||||
info!("{} charging status: {}", device.name, is_charging);
|
||||
|
||||
device.old_battery_level = device.battery_level;
|
||||
device.battery_level = battery_level;
|
||||
device.is_charging = is_charging;
|
||||
|
||||
Self::check_notify(device);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_notify(device: &MemoryDevice) {
|
||||
if device.battery_level == -1 {
|
||||
return;
|
||||
}
|
||||
|
||||
if !device.is_charging
|
||||
&& (device.battery_level <= 5
|
||||
|| (device.old_battery_level > 15 && device.battery_level <= 15))
|
||||
{
|
||||
info!("{}: Battery low ({}%)", device.name, device.battery_level);
|
||||
} else if device.old_battery_level <= 99
|
||||
&& device.battery_level == 100
|
||||
&& device.is_charging
|
||||
{
|
||||
info!(
|
||||
"{}: Battery fully charged ({}%)",
|
||||
device.name, device.battery_level
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue