decode esp_timestamp and meas_id in desktop Rust parser

This commit is contained in:
jess 2026-04-03 07:02:50 -07:00
parent 8297773827
commit 1ba6772738
2 changed files with 44 additions and 13 deletions

View File

@ -646,7 +646,7 @@ impl App {
self.status = s; self.status = s;
} }
Message::DeviceData(msg) => match msg { Message::DeviceData(msg) => match msg {
EisMessage::SweepStart { num_points, freq_start, freq_stop } => { EisMessage::SweepStart { num_points, freq_start, freq_stop, .. } => {
if self.collecting_refs { if self.collecting_refs {
/* ref collection: clear temp buffer */ /* ref collection: clear temp buffer */
self.eis_points.clear(); self.eis_points.clear();
@ -691,7 +691,7 @@ impl App {
self.electrode = cfg.electrode; self.electrode = cfg.electrode;
self.status = "Config received".into(); self.status = "Config received".into();
} }
EisMessage::LsvStart { num_points, v_start, v_stop } => { EisMessage::LsvStart { num_points, v_start, v_stop, .. } => {
self.lsv_points.clear(); self.lsv_points.clear();
self.lsv_total = num_points; self.lsv_total = num_points;
self.lsv_data = text_editor::Content::with_text(&fmt_lsv(&self.lsv_points)); self.lsv_data = text_editor::Content::with_text(&fmt_lsv(&self.lsv_points));
@ -739,7 +739,7 @@ impl App {
); );
} }
} }
EisMessage::AmpStart { v_hold } => { EisMessage::AmpStart { v_hold, .. } => {
self.amp_points.clear(); self.amp_points.clear();
self.amp_running = true; self.amp_running = true;
self.amp_data = text_editor::Content::with_text(&fmt_amp(&self.amp_points)); self.amp_data = text_editor::Content::with_text(&fmt_amp(&self.amp_points));
@ -758,7 +758,7 @@ impl App {
} }
self.status = format!("Amp complete: {} points", self.amp_points.len()); self.status = format!("Amp complete: {} points", self.amp_points.len());
} }
EisMessage::ClStart { num_points } => { EisMessage::ClStart { num_points, .. } => {
self.cl_points.clear(); self.cl_points.clear();
self.cl_result = None; self.cl_result = None;
self.cl_total = num_points; self.cl_total = num_points;
@ -798,7 +798,7 @@ impl App {
self.status = format!("Chlorine complete: {} points", self.cl_points.len()); self.status = format!("Chlorine complete: {} points", self.cl_points.len());
} }
} }
EisMessage::PhResult(r) => { EisMessage::PhResult(r, _, _) => {
if self.collecting_refs { if self.collecting_refs {
self.ph_ref = Some(r); self.ph_ref = Some(r);
} else { } else {

View File

@ -244,21 +244,23 @@ pub struct EisConfig {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum EisMessage { pub enum EisMessage {
SweepStart { num_points: u16, freq_start: f32, freq_stop: f32 }, SweepStart { num_points: u16, freq_start: f32, freq_stop: f32,
esp_timestamp: Option<u32>, meas_id: Option<u16> },
DataPoint { _index: u16, point: EisPoint }, DataPoint { _index: u16, point: EisPoint },
SweepEnd, SweepEnd,
Config(EisConfig), Config(EisConfig),
LsvStart { num_points: u16, v_start: f32, v_stop: f32 }, LsvStart { num_points: u16, v_start: f32, v_stop: f32,
esp_timestamp: Option<u32>, meas_id: Option<u16> },
LsvPoint { _index: u16, point: LsvPoint }, LsvPoint { _index: u16, point: LsvPoint },
LsvEnd, LsvEnd,
AmpStart { v_hold: f32 }, AmpStart { v_hold: f32, esp_timestamp: Option<u32>, meas_id: Option<u16> },
AmpPoint { _index: u16, point: AmpPoint }, AmpPoint { _index: u16, point: AmpPoint },
AmpEnd, AmpEnd,
ClStart { num_points: u16 }, ClStart { num_points: u16, esp_timestamp: Option<u32>, meas_id: Option<u16> },
ClPoint { _index: u16, point: ClPoint }, ClPoint { _index: u16, point: ClPoint },
ClResult(ClResult), ClResult(ClResult),
ClEnd, ClEnd,
PhResult(PhResult), PhResult(PhResult, Option<u32>, Option<u16>),
Temperature(f32), Temperature(f32),
RefFrame { mode: u8, rtia_idx: u8 }, RefFrame { mode: u8, rtia_idx: u8 },
RefLpRange { mode: u8, low_idx: u8, high_idx: u8 }, RefLpRange { mode: u8, low_idx: u8, high_idx: u8 },
@ -285,6 +287,16 @@ fn decode_float(data: &[u8]) -> f32 {
f32::from_le_bytes([b0, b1, b2, b3]) f32::from_le_bytes([b0, b1, b2, b3])
} }
fn decode_u32(data: &[u8]) -> u32 {
let b = [
data[1] | ((data[0] & 1) << 7),
data[2] | ((data[0] & 2) << 6),
data[3] | ((data[0] & 4) << 5),
data[4] | ((data[0] & 8) << 4),
];
u32::from_le_bytes(b)
}
fn encode_float(val: f32) -> [u8; 5] { fn encode_float(val: f32) -> [u8; 5] {
let p = val.to_le_bytes(); let p = val.to_le_bytes();
[ [
@ -303,10 +315,14 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
match data[1] { match data[1] {
RSP_SWEEP_START if data.len() >= 15 => { RSP_SWEEP_START if data.len() >= 15 => {
let p = &data[2..]; let p = &data[2..];
let (ts, mid) = if p.len() >= 21 {
(Some(decode_u32(&p[13..18])), Some(decode_u16(&p[18..21])))
} else { (None, None) };
Some(EisMessage::SweepStart { Some(EisMessage::SweepStart {
num_points: decode_u16(&p[0..3]), num_points: decode_u16(&p[0..3]),
freq_start: decode_float(&p[3..8]), freq_start: decode_float(&p[3..8]),
freq_stop: decode_float(&p[8..13]), freq_stop: decode_float(&p[8..13]),
esp_timestamp: ts, meas_id: mid,
}) })
} }
RSP_DATA_POINT if data.len() >= 30 => { RSP_DATA_POINT if data.len() >= 30 => {
@ -342,10 +358,14 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
} }
RSP_LSV_START if data.len() >= 15 => { RSP_LSV_START if data.len() >= 15 => {
let p = &data[2..]; let p = &data[2..];
let (ts, mid) = if p.len() >= 21 {
(Some(decode_u32(&p[13..18])), Some(decode_u16(&p[18..21])))
} else { (None, None) };
Some(EisMessage::LsvStart { Some(EisMessage::LsvStart {
num_points: decode_u16(&p[0..3]), num_points: decode_u16(&p[0..3]),
v_start: decode_float(&p[3..8]), v_start: decode_float(&p[3..8]),
v_stop: decode_float(&p[8..13]), v_stop: decode_float(&p[8..13]),
esp_timestamp: ts, meas_id: mid,
}) })
} }
RSP_LSV_POINT if data.len() >= 15 => { RSP_LSV_POINT if data.len() >= 15 => {
@ -361,7 +381,11 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
RSP_LSV_END => Some(EisMessage::LsvEnd), RSP_LSV_END => Some(EisMessage::LsvEnd),
RSP_AMP_START if data.len() >= 7 => { RSP_AMP_START if data.len() >= 7 => {
let p = &data[2..]; let p = &data[2..];
Some(EisMessage::AmpStart { v_hold: decode_float(&p[0..5]) }) let (ts, mid) = if p.len() >= 13 {
(Some(decode_u32(&p[5..10])), Some(decode_u16(&p[10..13])))
} else { (None, None) };
Some(EisMessage::AmpStart { v_hold: decode_float(&p[0..5]),
esp_timestamp: ts, meas_id: mid })
} }
RSP_AMP_POINT if data.len() >= 15 => { RSP_AMP_POINT if data.len() >= 15 => {
let p = &data[2..]; let p = &data[2..];
@ -376,7 +400,11 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
RSP_AMP_END => Some(EisMessage::AmpEnd), RSP_AMP_END => Some(EisMessage::AmpEnd),
RSP_CL_START if data.len() >= 5 => { RSP_CL_START if data.len() >= 5 => {
let p = &data[2..]; let p = &data[2..];
Some(EisMessage::ClStart { num_points: decode_u16(&p[0..3]) }) let (ts, mid) = if p.len() >= 11 {
(Some(decode_u32(&p[3..8])), Some(decode_u16(&p[8..11])))
} else { (None, None) };
Some(EisMessage::ClStart { num_points: decode_u16(&p[0..3]),
esp_timestamp: ts, meas_id: mid })
} }
RSP_CL_POINT if data.len() >= 16 => { RSP_CL_POINT if data.len() >= 16 => {
let p = &data[2..]; let p = &data[2..];
@ -403,11 +431,14 @@ pub fn parse_sysex(data: &[u8]) -> Option<EisMessage> {
} }
RSP_PH_RESULT if data.len() >= 17 => { RSP_PH_RESULT if data.len() >= 17 => {
let p = &data[2..]; let p = &data[2..];
let (ts, mid) = if p.len() >= 23 {
(Some(decode_u32(&p[15..20])), Some(decode_u16(&p[20..23])))
} else { (None, None) };
Some(EisMessage::PhResult(PhResult { Some(EisMessage::PhResult(PhResult {
v_ocp_mv: decode_float(&p[0..5]), v_ocp_mv: decode_float(&p[0..5]),
ph: decode_float(&p[5..10]), ph: decode_float(&p[5..10]),
temp_c: decode_float(&p[10..15]), temp_c: decode_float(&p[10..15]),
})) }, ts, mid))
} }
RSP_REF_FRAME if data.len() >= 4 => { RSP_REF_FRAME if data.len() >= 4 => {
Some(EisMessage::RefFrame { mode: data[2], rtia_idx: data[3] }) Some(EisMessage::RefFrame { mode: data[2], rtia_idx: data[3] })