From e008298187c3dc57f37e9511763e9e35d7dca80b Mon Sep 17 00:00:00 2001 From: Serguey Parkhomovsky Date: Sat, 21 Mar 2026 17:33:46 -0700 Subject: Separate some fields into prusa and bambu structs --- TODO.md | 12 ++++++++++++ src/lib.rs | 58 ++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 50 insertions(+), 20 deletions(-) diff --git a/TODO.md b/TODO.md index 4640904..5a213c7 100644 --- a/TODO.md +++ b/TODO.md @@ -1 +1,13 @@ # TODO + +Example requests: + +2026-03-21T23:55:38.281622Z DEBUG printstats: Received Bambu payload payload=b"{\"print\":{\"upgrade_state\":{\"sequence_id\":0,\"progress\":\"\",\"status\":\"IDLE\",\"consistency_request\":false,\"dis_state\":0,\"err_code\":0,\"force_upgrade\":false,\"message\":\"0%, 0B/s\",\"module\":\"\",\"new_version_state\":0,\"cur_state_code\":1,\"idx2\":2259839987,\"new_ver_list\":[]},\"ipcam\":{\"ipcam_dev\":\"1\",\"ipcam_record\":\"enable\",\"timelapse\":\"enable\",\"resolution\":\"\",\"tutk_server\":\"disable\",\"mode_bits\":3},\"upload\":{\"status\":\"idle\",\"progress\":0,\"message\":\"\"},\"net\":{\"conf\":0,\"info\":[{\"ip\":1090627776,\"mask\":16777215}]},\"nozzle_temper\":109.125,\"nozzle_target_temper\":80,\"bed_temper\":65.03125,\"bed_target_temper\":65,\"chamber_temper\":5,\"mc_print_stage\":\"3\",\"heatbreak_fan_speed\":\"15\",\"cooling_fan_speed\":\"15\",\"big_fan1_speed\":\"12\",\"big_fan2_speed\":\"8\",\"mc_percent\":45,\"mc_remaining_time\":24,\"ams_status\":768,\"ams_rfid_status\":0,\"hw_switch_state\":0,\"spd_mag\":50,\"spd_lvl\":1,\"print_error\":50364420,\"lifecycle\":\"product\",\"wifi_signal\":\"-90dBm\",\"gcode_state\":\"PAUSE\",\"gcode_file_prepare_percent\":\"0\",\"queue_number\":0,\"queue_total\":0,\"queue_est\":0,\"queue_sts\":0,\"project_id\":\"0\",\"profile_id\":\"0\",\"task_id\":\"0\",\"subtask_id\":\"0\",\"subtask_name\":\"calicat\",\"gcode_file\":\"calicat.gcode.3mf\",\"stg\":[2,14,1],\"stg_cur\":0,\"print_type\":\"local\",\"home_flag\":6505751,\"mc_print_line_number\":\"0\",\"mc_print_sub_stage\":0,\"sdcard\":true,\"force_upgrade\":false,\"mess_production_state\":\"active\",\"layer_num\":33,\"total_layer_num\":173,\"s_obj\":[],\"filam_bak\":[],\"fan_gear\":9885695,\"nozzle_diameter\":\"0.4\",\"nozzle_type\":\"hardened_steel\",\"cali_version\":0,\"k\":\"0.0200\",\"flag3\":8843,\"hms\":[],\"online\":{\"ahb\":false,\"rfid\":false,\"version\":1459095491},\"ams\":{\"ams\":[],\"ams_exist_bits\":\"0\",\"tray_exist_bits\":\"0\",\"tray_is_bbl_bits\":\"0\",\"tray_tar\":\"254\",\"tray_now\":\"255\",\"tray_pre\":\"255\",\"tray_read_done_bits\":\"0\",\"tray_reading_bits\":\"0\",\"version\":2,\"insert_flag\":true,\"power_on_flag\":false},\"vt_tray\":{\"id\":\"254\",\"tag_uid\":\"0000000000000000\",\"tray_id_name\":\"\",\"tray_info_idx\":\"GFL99\",\"tray_type\":\"PLA\",\"tray_sub_brands\":\"\",\"tray_color\":\"F98C36FF\",\"tray_weight\":\"0\",\"tray_diameter\":\"0.00\",\"tray_temp\":\"0\",\"tray_time\":\"0\",\"bed_temp_type\":\"0\",\"bed_temp\":\"0\",\"nozzle_temp_max\":\"240\",\"nozzle_temp_min\":\"190\",\"xcam_info\":\"000000000000000000000000\",\"tray_uuid\":\"00000000000000000000000000000000\",\"remain\":0,\"k\":0.019999999552965164,\"n\":1,\"cali_idx\":-1},\"lights_report\":[{\"node\":\"chamber_light\",\"mode\":\"on\"}],\"command\":\"push_status\",\"msg\":0,\"sequence_id\":\"3768\"}}" + +{"job":{"id":1063,"progress":4.00,"time_remaining":0,"time_printing":213},"storage":{"path":"/usb/","name":"usb","read_only":false},"printer":{"state":"PRINTING","temp_bed":60.0,"target_bed":60.0,"temp_nozzle":232.5,"target_nozzle":230.0,"axis_z":15.0,"flow":100,"speed":100,"fan_hotend":3255,"fan_print":0}} + +{"id":1064,"state":"PRINTING","progress":17.00,"time_remaining":2520,"time_printing":530,"file":{"refs":{"icon":"/thumb/s/usb/theo/3DBENC~1.GCO","thumbnail":"/thumb/l/usb/theo/3DBENC~1.GCO","download":"/usb/theo/3DBENC~1.GCO"},"name":"3DBENC~1.GCO","display_name":"3DBenchy_0.2mm_PLA_Prusa MK4_51m1s.gcode","path":"/usb/theo","size":4027041,"m_timestamp":1774137908}} + +- [ ] Prusa outputs time in seconds, while bambu outputs time in minutes +- [ ] Grab the job information for Prusa from job endpoint +- [ ] Grab job info for Bambu too diff --git a/src/lib.rs b/src/lib.rs index ce2d40a..b704849 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,22 @@ pub trait UpdateFrom { fn update_from(&mut self, source: &T); } +#[derive(Debug, Default, Serialize, Clone)] +pub struct BambuPrinterState { + pub layer_num: u32, + pub total_layer_num: u32, + pub print_speed: Option, +} + +#[derive(Debug, Default, Serialize, Clone)] +pub struct PrusaPrinterState { + pub flow: u32, + pub speed: u32, + pub fan_hotend: u32, + pub fan_print: u32, + pub time_printing: u32, +} + #[derive(Debug, Default, Serialize, Clone)] pub struct PrinterState { pub status: PrintStatus, @@ -26,16 +42,10 @@ pub struct PrinterState { pub target_bed_temp: f32, pub nozzle_temp: f32, pub target_nozzle_temp: f32, - pub flow: u32, - pub speed: u32, - pub fan_hotend: u32, - pub fan_print: u32, pub progress: f32, pub time_remaining: u32, - pub time_printing: u32, - pub layer_num: u32, - pub total_layer_num: u32, - pub print_speed: Option, + pub prusa: Option, + pub bambu: Option, } #[derive(Debug, Deserialize)] @@ -105,14 +115,16 @@ impl UpdateFrom for PrinterState { self.target_bed_temp = p.target_bed; self.nozzle_temp = p.temp_nozzle; self.target_nozzle_temp = p.target_nozzle; - self.flow = p.flow; - self.speed = p.speed; - self.fan_hotend = p.fan_hotend; - self.fan_print = p.fan_print; + self.prusa = Some(PrusaPrinterState { + flow: p.flow, + speed: p.speed, + fan_hotend: p.fan_hotend, + fan_print: p.fan_print, + time_printing: status.job.as_ref().map_or(0, |j| j.time_printing), + }); if let Some(job) = &status.job { self.progress = job.progress; self.time_remaining = job.time_remaining; - self.time_printing = job.time_printing; } } } @@ -155,15 +167,21 @@ impl UpdateFrom for PrinterState { self.progress = v as f32; } if let Some(v) = print.mc_remaining_time { - self.time_remaining = v; - } - if let Some(v) = print.layer_num { - self.layer_num = v; + // Bambu remaining time is in minutes + self.time_remaining = v * 60; } - if let Some(v) = print.total_layer_num { - self.total_layer_num = v; + if print.layer_num.is_some() || print.total_layer_num.is_some() || print.print_speed.is_some() { + let bambu = self.bambu.get_or_insert_with(BambuPrinterState::default); + if let Some(v) = print.layer_num { + bambu.layer_num = v; + } + if let Some(v) = print.total_layer_num { + bambu.total_layer_num = v; + } + if print.print_speed.is_some() { + bambu.print_speed = print.print_speed.clone(); + } } - self.print_speed = print.print_speed.clone(); if let Some(gcode_state) = &print.gcode_state { self.status = match gcode_state { BambuState::Prepare => PrintStatus::Prepare, -- cgit v1.2.3