diff --git a/cue/src/app.rs b/cue/src/app.rs index 4a5ffba..643372b 100644 --- a/cue/src/app.rs +++ b/cue/src/app.rs @@ -98,6 +98,8 @@ pub enum Message { CalBleachChanged(String), CalTempChanged(String), CalComputeK, + ClCalKnownPpmChanged(String), + ClSetFactor, /* Global */ PollTemp, NativeMenuTick, @@ -227,6 +229,8 @@ pub struct App { cal_bleach_pct: String, cal_temp_c: String, cal_cell_constant: Option, + cl_factor: Option, + cl_cal_known_ppm: String, /* Global */ temp_c: f32, @@ -457,6 +461,8 @@ impl App { cal_bleach_pct: "7.825".into(), cal_temp_c: "40".into(), cal_cell_constant: None, + cl_factor: None, + cl_cal_known_ppm: String::from("5"), temp_c: 25.0, conn_gen: 0, @@ -561,6 +567,7 @@ impl App { self.connected = true; self.send_cmd(&protocol::build_sysex_get_config()); self.send_cmd(&protocol::build_sysex_get_cell_k()); + self.send_cmd(&protocol::build_sysex_get_cl_factor()); } Message::DeviceStatus(s) => { if s.contains("Reconnecting") || s.contains("Connecting") { @@ -734,6 +741,10 @@ impl App { self.cal_cell_constant = Some(k); self.status = format!("Device cell constant: {:.4} cm-1", k); } + EisMessage::ClFactor(f) => { + self.cl_factor = Some(f); + self.status = format!("Device Cl factor: {:.6}", f); + } }, Message::TabSelected(t) => { if t == Tab::Browse { @@ -951,6 +962,19 @@ impl App { self.status = "No valid EIS data for Rs extraction".into(); } } + Message::ClCalKnownPpmChanged(s) => { self.cl_cal_known_ppm = s; } + Message::ClSetFactor => { + let known_ppm = self.cl_cal_known_ppm.parse::().unwrap_or(0.0); + if let Some(r) = &self.cl_result { + let peak = r.i_free_ua.abs(); + if peak > 0.0 { + let factor = known_ppm / peak; + self.cl_factor = Some(factor); + self.send_cmd(&protocol::build_sysex_set_cl_factor(factor)); + self.status = format!("Cl factor: {:.6} ppm/uA", factor); + } + } + } /* Clean */ Message::CleanVChanged(s) => self.clean_v = s, Message::CleanDurChanged(s) => self.clean_dur = s, @@ -1538,6 +1562,10 @@ impl App { "Free: {:.3} uA | Total: {:.3} uA | Combined: {:.3} uA", r.i_free_ua, r.i_total_ua, r.i_total_ua - r.i_free_ua )); + if let (Some(f), Some(r)) = (self.cl_factor, &self.cl_result) { + let ppm = f * r.i_free_ua.abs(); + result_parts.push(format!("Free Cl: {:.2} ppm", ppm)); + } if let Some((_, ref_r)) = &self.cl_ref { let df = r.i_free_ua - ref_r.i_free_ua; let dt = r.i_total_ua - ref_r.i_total_ua; @@ -1645,6 +1673,28 @@ impl App { .on_press(Message::CalComputeK); results = results.push(compute_btn); + results = results.push(iced::widget::horizontal_rule(1)); + results = results.push(text("Chlorine Calibration").size(16)); + if let Some(f) = self.cl_factor { + results = results.push(text(format!("Cl factor: {:.6} ppm/uA", f)).size(14)); + } + if let Some(r) = &self.cl_result { + results = results.push(text(format!("Last free Cl peak: {:.3} uA", r.i_free_ua)).size(14)); + } + results = results.push( + row![ + column![ + text("Known Cl ppm").size(12), + text_input("5", &self.cl_cal_known_ppm) + .on_input(Message::ClCalKnownPpmChanged).width(80), + ].spacing(2), + button(text("Set Cl Factor").size(13)) + .style(style_action()) + .padding([6, 16]) + .on_press(Message::ClSetFactor), + ].spacing(10).align_y(iced::Alignment::End) + ); + row![ container(inputs).width(Length::FillPortion(2)), iced::widget::vertical_rule(1),