add auto-mode chlorine flow to desktop
This commit is contained in:
parent
c6bbaa5bc4
commit
03d10ab678
193
cue/src/app.rs
193
cue/src/app.rs
|
|
@ -17,6 +17,13 @@ use crate::protocol::{
|
|||
use crate::storage::{self, Session, Storage};
|
||||
use crate::udp::UdpEvent;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum ClAutoState {
|
||||
Idle,
|
||||
LsvRunning,
|
||||
MeasureRunning,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum LsvDensityMode {
|
||||
PtsPerMv,
|
||||
|
|
@ -109,6 +116,8 @@ pub enum Message {
|
|||
ClMeasTChanged(String),
|
||||
ClRtiaSelected(LpRtia),
|
||||
StartCl,
|
||||
StartClAuto,
|
||||
ClToggleManual,
|
||||
/* pH */
|
||||
PhStabilizeChanged(String),
|
||||
StartPh,
|
||||
|
|
@ -238,6 +247,9 @@ pub struct App {
|
|||
cl_meas_t: String,
|
||||
cl_rtia: LpRtia,
|
||||
cl_data: text_editor::Content,
|
||||
cl_manual_peaks: bool,
|
||||
cl_auto_state: ClAutoState,
|
||||
cl_auto_potentials: Option<crate::lsv_analysis::ClPotentials>,
|
||||
|
||||
/* pH */
|
||||
ph_result: Option<PhResult>,
|
||||
|
|
@ -482,6 +494,9 @@ impl App {
|
|||
cl_meas_t: "5000".into(),
|
||||
cl_rtia: LpRtia::R10K,
|
||||
cl_data: text_editor::Content::with_text(&fmt_cl(&[])),
|
||||
cl_manual_peaks: false,
|
||||
cl_auto_state: ClAutoState::Idle,
|
||||
cl_auto_potentials: None,
|
||||
|
||||
ph_result: None,
|
||||
ph_stabilize: "30".into(),
|
||||
|
|
@ -702,6 +717,27 @@ impl App {
|
|||
}
|
||||
}
|
||||
self.status = st;
|
||||
|
||||
if self.cl_auto_state == ClAutoState::LsvRunning {
|
||||
let pots = crate::lsv_analysis::derive_cl_potentials(&self.lsv_points);
|
||||
self.cl_free_v = format!("{:.0}", pots.v_free);
|
||||
self.cl_total_v = format!("{:.0}", pots.v_total);
|
||||
self.cl_auto_potentials = Some(pots);
|
||||
self.cl_auto_state = ClAutoState::MeasureRunning;
|
||||
|
||||
let v_cond = self.cl_cond_v.parse::<f32>().unwrap_or(800.0);
|
||||
let t_cond = self.cl_cond_t.parse::<f32>().unwrap_or(2000.0);
|
||||
let t_dep = self.cl_dep_t.parse::<f32>().unwrap_or(5000.0);
|
||||
let t_meas = self.cl_meas_t.parse::<f32>().unwrap_or(5000.0);
|
||||
self.send_cmd(&protocol::build_sysex_get_temp());
|
||||
self.send_cmd(&protocol::build_sysex_start_cl(
|
||||
v_cond, t_cond, pots.v_free, pots.v_total, t_dep, t_meas, self.cl_rtia,
|
||||
));
|
||||
self.status = format!(
|
||||
"Auto Cl: measuring (free={:.0}, total={:.0})",
|
||||
pots.v_free, pots.v_total
|
||||
);
|
||||
}
|
||||
}
|
||||
EisMessage::AmpStart { v_hold } => {
|
||||
self.amp_points.clear();
|
||||
|
|
@ -744,7 +780,23 @@ impl App {
|
|||
if let Some(sid) = self.current_session {
|
||||
self.save_cl(sid);
|
||||
}
|
||||
self.status = format!("Chlorine complete: {} points", self.cl_points.len());
|
||||
if self.cl_auto_state == ClAutoState::MeasureRunning {
|
||||
self.cl_auto_state = ClAutoState::Idle;
|
||||
if let Some(pots) = &self.cl_auto_potentials {
|
||||
self.status = format!(
|
||||
"Auto Cl complete: {} pts (free={:.0}{}, total={:.0}{})",
|
||||
self.cl_points.len(),
|
||||
pots.v_free,
|
||||
if pots.v_free_detected { "" } else { " dflt" },
|
||||
pots.v_total,
|
||||
if pots.v_total_detected { "" } else { " dflt" },
|
||||
);
|
||||
} else {
|
||||
self.status = format!("Chlorine complete: {} points", self.cl_points.len());
|
||||
}
|
||||
} else {
|
||||
self.status = format!("Chlorine complete: {} points", self.cl_points.len());
|
||||
}
|
||||
}
|
||||
EisMessage::PhResult(r) => {
|
||||
if self.collecting_refs {
|
||||
|
|
@ -932,6 +984,17 @@ impl App {
|
|||
v_cond, t_cond, v_free, v_total, t_dep, t_meas, self.cl_rtia,
|
||||
));
|
||||
}
|
||||
Message::StartClAuto => {
|
||||
self.cl_auto_state = ClAutoState::LsvRunning;
|
||||
self.cl_auto_potentials = None;
|
||||
let density = self.lsv_density.parse::<f32>().unwrap_or(1.0);
|
||||
let n = lsv_calc_points(-1100.0, 1100.0, 50.0, density, self.lsv_density_mode);
|
||||
self.send_cmd(&protocol::build_sysex_start_lsv(-1100.0, 1100.0, 50.0, self.lsv_rtia, n));
|
||||
self.status = "Auto Cl: running LSV sweep...".into();
|
||||
}
|
||||
Message::ClToggleManual => {
|
||||
self.cl_manual_peaks = !self.cl_manual_peaks;
|
||||
}
|
||||
/* pH */
|
||||
Message::PhStabilizeChanged(s) => self.ph_stabilize = s,
|
||||
Message::StartPh => {
|
||||
|
|
@ -1650,51 +1713,89 @@ impl App {
|
|||
.align_y(iced::Alignment::End)
|
||||
.into(),
|
||||
|
||||
Tab::Chlorine => row![
|
||||
button(text("Start LSV").size(13))
|
||||
.style(style_action())
|
||||
.padding([6, 16])
|
||||
.on_press(Message::StartLsv),
|
||||
button(text(if self.lsv_manual_peaks { "Manual" } else { "Auto" }).size(13))
|
||||
.padding([6, 12])
|
||||
.on_press(Message::LsvToggleManual),
|
||||
rule::Rule::vertical(1),
|
||||
column![
|
||||
text("Cond mV").size(12),
|
||||
text_input("800", &self.cl_cond_v).on_input(Message::ClCondVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Cond ms").size(12),
|
||||
text_input("2000", &self.cl_cond_t).on_input(Message::ClCondTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Free mV").size(12),
|
||||
text_input("100", &self.cl_free_v).on_input(Message::ClFreeVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Total mV").size(12),
|
||||
text_input("-200", &self.cl_total_v).on_input(Message::ClTotalVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Settle ms").size(12),
|
||||
text_input("5000", &self.cl_dep_t).on_input(Message::ClDepTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Meas ms").size(12),
|
||||
text_input("5000", &self.cl_meas_t).on_input(Message::ClMeasTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("RTIA").size(12),
|
||||
pick_list(LpRtia::ALL, Some(self.cl_rtia), Message::ClRtiaSelected).width(Length::Shrink),
|
||||
].spacing(2),
|
||||
button(text("Measure").size(13))
|
||||
.style(style_action())
|
||||
.padding([6, 16])
|
||||
.on_press(Message::StartCl),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Alignment::End)
|
||||
.into(),
|
||||
Tab::Chlorine => if self.cl_manual_peaks {
|
||||
row![
|
||||
button(text("Start LSV").size(13))
|
||||
.style(style_action())
|
||||
.padding([6, 16])
|
||||
.on_press(Message::StartLsv),
|
||||
button(text("Manual").size(13))
|
||||
.padding([6, 12])
|
||||
.on_press(Message::ClToggleManual),
|
||||
rule::Rule::vertical(1),
|
||||
column![
|
||||
text("Cond mV").size(12),
|
||||
text_input("800", &self.cl_cond_v).on_input(Message::ClCondVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Cond ms").size(12),
|
||||
text_input("2000", &self.cl_cond_t).on_input(Message::ClCondTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Free mV").size(12),
|
||||
text_input("100", &self.cl_free_v).on_input(Message::ClFreeVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Total mV").size(12),
|
||||
text_input("-200", &self.cl_total_v).on_input(Message::ClTotalVChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Settle ms").size(12),
|
||||
text_input("5000", &self.cl_dep_t).on_input(Message::ClDepTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("Meas ms").size(12),
|
||||
text_input("5000", &self.cl_meas_t).on_input(Message::ClMeasTChanged).width(70),
|
||||
].spacing(2),
|
||||
column![
|
||||
text("RTIA").size(12),
|
||||
pick_list(LpRtia::ALL, Some(self.cl_rtia), Message::ClRtiaSelected).width(Length::Shrink),
|
||||
].spacing(2),
|
||||
button(text("Measure").size(13))
|
||||
.style(style_action())
|
||||
.padding([6, 16])
|
||||
.on_press(Message::StartCl),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Alignment::End)
|
||||
.into()
|
||||
} else {
|
||||
let auto_btn = {
|
||||
let b = button(text("Start Auto").size(13))
|
||||
.style(style_action())
|
||||
.padding([6, 16]);
|
||||
if self.cl_auto_state == ClAutoState::Idle {
|
||||
b.on_press(Message::StartClAuto)
|
||||
} else {
|
||||
b
|
||||
}
|
||||
};
|
||||
let pot_text = if let Some(pots) = &self.cl_auto_potentials {
|
||||
format!(
|
||||
"free={:.0}{} total={:.0}{}",
|
||||
pots.v_free,
|
||||
if pots.v_free_detected { "" } else { "?" },
|
||||
pots.v_total,
|
||||
if pots.v_total_detected { "" } else { "?" },
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
row![
|
||||
auto_btn,
|
||||
button(text("Auto").size(13))
|
||||
.padding([6, 12])
|
||||
.on_press(Message::ClToggleManual),
|
||||
column![
|
||||
text("RTIA").size(12),
|
||||
pick_list(LpRtia::ALL, Some(self.cl_rtia), Message::ClRtiaSelected).width(Length::Shrink),
|
||||
].spacing(2),
|
||||
text(pot_text).size(12),
|
||||
]
|
||||
.spacing(8)
|
||||
.align_y(iced::Alignment::End)
|
||||
.into()
|
||||
},
|
||||
|
||||
Tab::Ph => row![
|
||||
column![
|
||||
|
|
|
|||
Loading…
Reference in New Issue