diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 89 | ||||
| -rw-r--r-- | src/main.rs | 82 |
2 files changed, 104 insertions, 67 deletions
@@ -1,9 +1,62 @@ use serde::Deserialize; #[derive(Debug, Default)] +pub enum PrintStatus { + #[default] + Idle, + Printing, + Paused, + Finished, +} + +#[derive(Debug, Default)] pub struct PrinterState { pub name: String, pub bed_temp: f32, + pub status: PrintStatus, +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "SCREAMING_SNAKE_CASE")] +pub enum PrusaState { + Idle, + Printing, + Paused, + Finished, + Stopped, + Error, + Attention, + Busy, +} + +#[derive(Debug, Deserialize)] +pub struct PrusaJob { + pub id: u32, + pub progress: f32, + pub time_remaining: u32, + pub time_printing: u32, +} + +#[derive(Debug, Deserialize)] +pub struct PrusaPrinterInfo { + pub state: PrusaState, + pub temp_nozzle: f32, + pub target_nozzle: f32, + pub temp_bed: f32, + pub target_bed: f32, + pub axis_x: f32, + pub axis_y: f32, + pub axis_z: f32, + pub flow: u32, + pub speed: u32, + pub fan_hotend: u32, + pub fan_print: u32, +} + +#[derive(Debug, Deserialize)] +pub struct PrusaStatus { + pub job: Option<PrusaJob>, + pub printer: PrusaPrinterInfo, } #[derive(Deserialize)] @@ -43,39 +96,3 @@ pub enum Printer { serial_number: String, }, } - -pub fn prusa_fetch(client: &reqwest::blocking::Client, printer: &Printer) { - let Printer::Prusa { - name, - host, - api_key, - } = printer - else { - panic!("Expected a Prusa printer, but received a different variant!"); - }; - - let url = format!("http://{}/api/v1/status", host); - - let mut req = client.get(&url); - req = req.header("X-Api-Key", api_key); - - match req.send() { - Err(e) => { - eprintln!("Could not reach Prusa printer {} at {}: {}", name, host, e); - return; - } - Ok(resp) => { - if !resp.status().is_success() { - eprintln!("HTTP {}: {}", resp.status(), url); - if resp.status().as_u16() == 403 { - eprintln!("Invalid PrusaLink key for {}.", name); - } - return; - } - match resp.text() { - Err(e) => eprintln!("Failed to parse response for Prusa printer {}: {}", host, e), - Ok(text) => println!("{}", text), - } - } - } -} diff --git a/src/main.rs b/src/main.rs index 11a2e43..6c353e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,29 +16,40 @@ async fn main() { for printer in config.printers { match printer { - Printer::Prusa { name, host, api_key, .. } => { + Printer::Prusa { + name, + host, + api_key, + .. + } => { let state_clone = state.clone(); tokio::spawn(async move { - let client = Client::new(); - let response = client.get(format!("http://{}", host)) - .header("X-Api-Key", api_key) - .send() - .await - .unwrap() - .json::<serde_json::Value>() - .await - .unwrap(); - let mut lock = state_clone.lock().await; - println!("{:?}", &response); - /* - if let Ok(msg) = serde_json::from_slice::<BambuMessage>(&p.payload) { - lock.entry(name.clone()) - .and_modify(|prs| prs.bed_temp = msg.print.bed_temper) - .or_insert_with(|| PrinterState { name: name.clone(), bed_temp: msg.print.bed_temper, ..Default::default() }); - println!("Updated state for {}: {:?}", &name, p.payload); + loop { + let result: Result<(), Box<dyn std::error::Error + Send + Sync>> = async { + let client = Client::new(); + let response = client + .get(format!("http://{}/api/v1/status", host)) + .header("X-Api-Key", &api_key) + .send() + .await? + .json::<PrusaStatus>() + .await?; + let mut lock = state_clone.lock().await; + lock.entry(name.clone()) + .and_modify(|prs| prs.bed_temp = response.printer.temp_bed) + .or_insert_with(|| PrinterState { + name: name.clone(), + bed_temp: response.printer.temp_bed, + ..Default::default() + }); + Ok(()) + } + .await; + if let Err(e) = result { + eprintln!("Error polling Prusa printer {}: {}", name, e); + } + tokio::time::sleep(Duration::from_secs(5)).await; } - */ - println!("Found Prusa: {} at {}", name, host); }); } Printer::Bambu { @@ -74,10 +85,16 @@ async fn main() { if let Event::Incoming(Packet::Publish(p)) = notification { let mut lock = state_clone.lock().await; println!("{:?}", &p.payload); - if let Ok(msg) = serde_json::from_slice::<BambuMessage>(&p.payload) { + if let Ok(msg) = + serde_json::from_slice::<BambuMessage>(&p.payload) + { lock.entry(name.clone()) .and_modify(|prs| prs.bed_temp = msg.print.bed_temper) - .or_insert_with(|| PrinterState { name: name.clone(), bed_temp: msg.print.bed_temper, ..Default::default() }); + .or_insert_with(|| PrinterState { + name: name.clone(), + bed_temp: msg.print.bed_temper, + ..Default::default() + }); println!("Updated state for {}: {:?}", &name, p.payload); } } @@ -94,15 +111,18 @@ async fn main() { } loop { - let state_clone = Arc::clone(&state); - println!("-- PRINTER STATE --"); - - let lock = state_clone.lock().await; - - for (key, value) in lock.iter() { - println!("{}: {:?}", key, value); + tokio::select! { + _ = tokio::signal::ctrl_c() => { + println!("Shutting down..."); + break; + } + _ = tokio::time::sleep(Duration::from_secs(1)) => { + println!("-- PRINTER STATE --"); + let lock = state.lock().await; + for (key, value) in lock.iter() { + println!("{}: {:?}", key, value); + } + } } - - tokio::time::sleep(Duration::from_secs(1)).await; } } |
