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::storage::{self, Session, Storage};
|
||||||
use crate::udp::UdpEvent;
|
use crate::udp::UdpEvent;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum ClAutoState {
|
||||||
|
Idle,
|
||||||
|
LsvRunning,
|
||||||
|
MeasureRunning,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum LsvDensityMode {
|
pub enum LsvDensityMode {
|
||||||
PtsPerMv,
|
PtsPerMv,
|
||||||
|
|
@ -109,6 +116,8 @@ pub enum Message {
|
||||||
ClMeasTChanged(String),
|
ClMeasTChanged(String),
|
||||||
ClRtiaSelected(LpRtia),
|
ClRtiaSelected(LpRtia),
|
||||||
StartCl,
|
StartCl,
|
||||||
|
StartClAuto,
|
||||||
|
ClToggleManual,
|
||||||
/* pH */
|
/* pH */
|
||||||
PhStabilizeChanged(String),
|
PhStabilizeChanged(String),
|
||||||
StartPh,
|
StartPh,
|
||||||
|
|
@ -238,6 +247,9 @@ pub struct App {
|
||||||
cl_meas_t: String,
|
cl_meas_t: String,
|
||||||
cl_rtia: LpRtia,
|
cl_rtia: LpRtia,
|
||||||
cl_data: text_editor::Content,
|
cl_data: text_editor::Content,
|
||||||
|
cl_manual_peaks: bool,
|
||||||
|
cl_auto_state: ClAutoState,
|
||||||
|
cl_auto_potentials: Option<crate::lsv_analysis::ClPotentials>,
|
||||||
|
|
||||||
/* pH */
|
/* pH */
|
||||||
ph_result: Option<PhResult>,
|
ph_result: Option<PhResult>,
|
||||||
|
|
@ -482,6 +494,9 @@ impl App {
|
||||||
cl_meas_t: "5000".into(),
|
cl_meas_t: "5000".into(),
|
||||||
cl_rtia: LpRtia::R10K,
|
cl_rtia: LpRtia::R10K,
|
||||||
cl_data: text_editor::Content::with_text(&fmt_cl(&[])),
|
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_result: None,
|
||||||
ph_stabilize: "30".into(),
|
ph_stabilize: "30".into(),
|
||||||
|
|
@ -702,6 +717,27 @@ impl App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.status = st;
|
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 } => {
|
EisMessage::AmpStart { v_hold } => {
|
||||||
self.amp_points.clear();
|
self.amp_points.clear();
|
||||||
|
|
@ -744,7 +780,23 @@ impl App {
|
||||||
if let Some(sid) = self.current_session {
|
if let Some(sid) = self.current_session {
|
||||||
self.save_cl(sid);
|
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) => {
|
EisMessage::PhResult(r) => {
|
||||||
if self.collecting_refs {
|
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,
|
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 */
|
/* pH */
|
||||||
Message::PhStabilizeChanged(s) => self.ph_stabilize = s,
|
Message::PhStabilizeChanged(s) => self.ph_stabilize = s,
|
||||||
Message::StartPh => {
|
Message::StartPh => {
|
||||||
|
|
@ -1650,51 +1713,89 @@ impl App {
|
||||||
.align_y(iced::Alignment::End)
|
.align_y(iced::Alignment::End)
|
||||||
.into(),
|
.into(),
|
||||||
|
|
||||||
Tab::Chlorine => row![
|
Tab::Chlorine => if self.cl_manual_peaks {
|
||||||
button(text("Start LSV").size(13))
|
row![
|
||||||
.style(style_action())
|
button(text("Start LSV").size(13))
|
||||||
.padding([6, 16])
|
.style(style_action())
|
||||||
.on_press(Message::StartLsv),
|
.padding([6, 16])
|
||||||
button(text(if self.lsv_manual_peaks { "Manual" } else { "Auto" }).size(13))
|
.on_press(Message::StartLsv),
|
||||||
.padding([6, 12])
|
button(text("Manual").size(13))
|
||||||
.on_press(Message::LsvToggleManual),
|
.padding([6, 12])
|
||||||
rule::Rule::vertical(1),
|
.on_press(Message::ClToggleManual),
|
||||||
column![
|
rule::Rule::vertical(1),
|
||||||
text("Cond mV").size(12),
|
column![
|
||||||
text_input("800", &self.cl_cond_v).on_input(Message::ClCondVChanged).width(70),
|
text("Cond mV").size(12),
|
||||||
].spacing(2),
|
text_input("800", &self.cl_cond_v).on_input(Message::ClCondVChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("Cond ms").size(12),
|
column![
|
||||||
text_input("2000", &self.cl_cond_t).on_input(Message::ClCondTChanged).width(70),
|
text("Cond ms").size(12),
|
||||||
].spacing(2),
|
text_input("2000", &self.cl_cond_t).on_input(Message::ClCondTChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("Free mV").size(12),
|
column![
|
||||||
text_input("100", &self.cl_free_v).on_input(Message::ClFreeVChanged).width(70),
|
text("Free mV").size(12),
|
||||||
].spacing(2),
|
text_input("100", &self.cl_free_v).on_input(Message::ClFreeVChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("Total mV").size(12),
|
column![
|
||||||
text_input("-200", &self.cl_total_v).on_input(Message::ClTotalVChanged).width(70),
|
text("Total mV").size(12),
|
||||||
].spacing(2),
|
text_input("-200", &self.cl_total_v).on_input(Message::ClTotalVChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("Settle ms").size(12),
|
column![
|
||||||
text_input("5000", &self.cl_dep_t).on_input(Message::ClDepTChanged).width(70),
|
text("Settle ms").size(12),
|
||||||
].spacing(2),
|
text_input("5000", &self.cl_dep_t).on_input(Message::ClDepTChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("Meas ms").size(12),
|
column![
|
||||||
text_input("5000", &self.cl_meas_t).on_input(Message::ClMeasTChanged).width(70),
|
text("Meas ms").size(12),
|
||||||
].spacing(2),
|
text_input("5000", &self.cl_meas_t).on_input(Message::ClMeasTChanged).width(70),
|
||||||
column![
|
].spacing(2),
|
||||||
text("RTIA").size(12),
|
column![
|
||||||
pick_list(LpRtia::ALL, Some(self.cl_rtia), Message::ClRtiaSelected).width(Length::Shrink),
|
text("RTIA").size(12),
|
||||||
].spacing(2),
|
pick_list(LpRtia::ALL, Some(self.cl_rtia), Message::ClRtiaSelected).width(Length::Shrink),
|
||||||
button(text("Measure").size(13))
|
].spacing(2),
|
||||||
.style(style_action())
|
button(text("Measure").size(13))
|
||||||
.padding([6, 16])
|
.style(style_action())
|
||||||
.on_press(Message::StartCl),
|
.padding([6, 16])
|
||||||
]
|
.on_press(Message::StartCl),
|
||||||
.spacing(8)
|
]
|
||||||
.align_y(iced::Alignment::End)
|
.spacing(8)
|
||||||
.into(),
|
.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![
|
Tab::Ph => row![
|
||||||
column![
|
column![
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue