summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSerguey Parkhomovsky <xindigo@gmail.com>2026-03-14 10:41:23 -0700
committerSerguey Parkhomovsky <xindigo@gmail.com>2026-03-14 10:41:23 -0700
commit79b4c239b61f2b130f8876eaba7a20fdf43a1a44 (patch)
tree2c4080a34e298ba2fcd2dadd00e99d8ec2af63de /src
parent49284eaf9a57f1756f4893dc30dce81d470f0fd3 (diff)
Prusa working
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs89
-rw-r--r--src/main.rs82
2 files changed, 104 insertions, 67 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 5dc4925..6c63733 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;
}
}