use std::{net::IpAddr, str::FromStr, sync::LazyLock};
use airtouch5::{types::status::StatusSet, AirTouch5};
use simplelog::TermLogger;
const USAGE_STR: &str = "Usage: status <ip>";
static UNNAMED_ZONE: LazyLock<String> = LazyLock::new(|| "<unknown>".to_string());
fn cls() {
print!("\x1b[2J\x1b[;H");
}
async fn prefill(controller: &AirTouch5) {
tokio::try_join!(
controller.ac_status(),
controller.zone_status(),
)
.expect("could not prefill status");
}
#[tokio::main(flavor = "current_thread")]
pub async fn main() {
TermLogger::init(
log::LevelFilter::Info,
simplelog::Config::default(),
simplelog::TerminalMode::Mixed,
simplelog::ColorChoice::Auto,
)
.expect("could non init logger");
let addr = IpAddr::from_str(&std::env::args().nth(1).expect(USAGE_STR)).expect(USAGE_STR);
let controller = AirTouch5::with_ipaddr(addr)
.await
.expect("could not connect");
let names = controller
.zone_names()
.await
.expect("could not get zone names");
let w = names.by_index().map(|(_, z)| z.len()).max().unwrap_or(0);
prefill(&controller).await;
let mut watch = controller.subscribe_status().expect("could not subscribe");
loop {
let status = watch.borrow_and_update();
cls();
for ac in status.acs().values() {
println!("{}", ac);
}
println!();
for (idx, zone) in status.zones().iter() {
println!(
"{:>w$}: {}",
names.zones.get(idx).unwrap_or(&UNNAMED_ZONE),
zone
);
}
drop(status);
watch.changed().await.expect("sender was dropped");
}
}