use printstats::*; use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS}; use std::collections::HashMap; use std::fs; use std::sync::Arc; use std::time::Duration; use tokio::sync::Mutex; #[tokio::main] async fn main() { let content = fs::read_to_string("config.toml").expect("Couldn't read config.toml"); let config: Config = toml::from_str(&content).expect("Couldn't parse config.toml"); let state = Arc::new(Mutex::new(HashMap::::new())); for printer in &config.printers { match printer { Printer::Prusa { name, host, .. } => { println!("Found Prusa: {} at {}", name, host); } Printer::Bambu { name, host, serial_number, .. } => { println!("Found Bambu: {} at {}", name, host); let state_clone = Arc::clone(&state); tokio::spawn(async move { let mut mqttoptions = MqttOptions::new(name, host, 1883); mqttoptions.set_keep_alive(Duration::from_secs(5)); let (client, mut eventloop) = AsyncClient::new(mqttoptions, 10); client .subscribe(format!("device/{}/report", serial_number), QoS::AtMostOnce) .await .unwrap(); loop { // eventloop.poll() yields back to Tokio when there's no data match eventloop.poll().await { Ok(notification) => { if let Event::Incoming(Packet::Publish(p)) = notification { let mut lock = state_clone.lock().await; // TODO - Update struct println!("Updated state from {:?}", p.payload); } } Err(_) => { tokio::time::sleep(Duration::from_secs(5)).await; // Simple retry } } } }); } } } loop { print!("\x1B[2J\x1B[1;1H"); // clear screen std::thread::sleep(Duration::from_secs(5)); } }