From 49284eaf9a57f1756f4893dc30dce81d470f0fd3 Mon Sep 17 00:00:00 2001 From: Serguey Parkhomovsky Date: Mon, 9 Mar 2026 15:01:32 -0700 Subject: Connect to bambu printers --- Cargo.lock | 112 +++--------------------------------------------------------- Cargo.toml | 4 ++- src/lib.rs | 12 ++++++- src/main.rs | 65 +++++++++++++++++++++++++++++------ 4 files changed, 74 insertions(+), 119 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 143f59c..2c84093 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,28 +14,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "aws-lc-rs" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" -dependencies = [ - "aws-lc-sys", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - [[package]] name = "base64" version = "0.22.1" @@ -67,8 +45,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", - "jobserver", - "libc", "shlex", ] @@ -78,15 +54,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" -[[package]] -name = "cmake" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" -dependencies = [ - "cc", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -124,12 +91,6 @@ dependencies = [ "syn", ] -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - [[package]] name = "encoding_rs" version = "0.8.35" @@ -220,12 +181,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - [[package]] name = "futures-channel" version = "0.3.32" @@ -286,18 +241,6 @@ dependencies = [ "wasi", ] -[[package]] -name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasip2", -] - [[package]] name = "getrandom" version = "0.4.1" @@ -611,16 +554,6 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" -[[package]] -name = "jobserver" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.4", - "libc", -] - [[package]] name = "js-sys" version = "0.3.89" @@ -830,9 +763,11 @@ dependencies = [ name = "printstats" version = "0.1.0" dependencies = [ + "native-tls", "reqwest", "rumqttc", "serde", + "serde_json", "tokio", "toml", ] @@ -937,12 +872,10 @@ dependencies = [ "flume", "futures-util", "log", - "rustls-native-certs", - "rustls-pemfile", - "rustls-webpki 0.102.8", + "native-tls", "thiserror", "tokio", - "tokio-rustls", + "tokio-native-tls", "tokio-stream", "tokio-util", ] @@ -966,36 +899,13 @@ version = "0.23.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c665f33d38cea657d9614f766881e4d510e0eda4239891eea56b4cadcf01801b" dependencies = [ - "aws-lc-rs", - "log", "once_cell", "rustls-pki-types", - "rustls-webpki 0.103.9", + "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-native-certs" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" -dependencies = [ - "openssl-probe", - "rustls-pki-types", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - [[package]] name = "rustls-pki-types" version = "1.14.0" @@ -1005,24 +915,12 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-webpki" -version = "0.102.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - [[package]] name = "rustls-webpki" version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ - "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", diff --git a/Cargo.toml b/Cargo.toml index 4acf5e5..67188d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,9 @@ edition = "2024" [dependencies] reqwest = { version = "0.12", features = ["blocking", "json"] } -rumqttc = "0.25.1" +rumqttc = { version = "0.25.1", default-features = false, features = ["use-native-tls"] } +native-tls = "0.2" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.49.0", features = ["full"] } toml = "0.8" +serde_json = "1.0.149" diff --git a/src/lib.rs b/src/lib.rs index 9d85c3e..5dc4925 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,21 @@ use serde::Deserialize; -#[derive(Debug)] +#[derive(Debug, Default)] pub struct PrinterState { pub name: String, pub bed_temp: f32, } +#[derive(Deserialize)] +pub struct BambuState { + pub bed_temper: f32, +} + +#[derive(Deserialize)] +pub struct BambuMessage { + pub print: BambuState, +} + #[derive(Debug, Deserialize)] pub struct Config { // This allows you to have a list of different printer types diff --git a/src/main.rs b/src/main.rs index 3b1c7f4..11a2e43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,7 @@ +use native_tls::TlsConnector; use printstats::*; -use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS}; +use reqwest::Client; +use rumqttc::{AsyncClient, Event, MqttOptions, Packet, QoS, Transport}; use std::collections::HashMap; use std::fs; use std::sync::Arc; @@ -14,20 +16,50 @@ async fn main() { for printer in config.printers { match printer { - Printer::Prusa { name, host, .. } => { - println!("Found Prusa: {} at {}", name, host); + 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::() + .await + .unwrap(); + let mut lock = state_clone.lock().await; + println!("{:?}", &response); + /* + if let Ok(msg) = serde_json::from_slice::(&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); + } + */ + println!("Found Prusa: {} at {}", name, host); + }); } Printer::Bambu { name, host, serial_number, - .. + access_code, } => { println!("Found Bambu: {} at {}", name, host); let state_clone = Arc::clone(&state); tokio::spawn(async move { - let mut mqttoptions = MqttOptions::new(name, host, 1883); + let mut mqttoptions = MqttOptions::new(&name, &host, 8883); mqttoptions.set_keep_alive(Duration::from_secs(5)); + mqttoptions.set_credentials("bblp", &access_code); + + // Bambu printers use TLS with a self-signed certificate + let connector = TlsConnector::builder() + .danger_accept_invalid_certs(true) + .build() + .unwrap(); + mqttoptions.set_transport(Transport::tls_with_config(connector.into())); let (client, mut eventloop) = AsyncClient::new(mqttoptions, 10); client @@ -41,11 +73,17 @@ async fn main() { 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); + println!("{:?}", &p.payload); + if let Ok(msg) = serde_json::from_slice::(&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); + } } } - Err(_) => { + Err(e) => { + eprintln!("MQTT error: {:?}", e); tokio::time::sleep(Duration::from_secs(5)).await; // Simple retry } } @@ -56,8 +94,15 @@ async fn main() { } loop { - print!("\x1B[2J\x1B[1;1H"); // clear screen + let state_clone = Arc::clone(&state); + println!("-- PRINTER STATE --"); + + let lock = state_clone.lock().await; + + for (key, value) in lock.iter() { + println!("{}: {:?}", key, value); + } - std::thread::sleep(Duration::from_secs(5)); + tokio::time::sleep(Duration::from_secs(1)).await; } } -- cgit v1.2.3