use postcard_rpc::{ header::VarSeqKind, host_client::{HostClient, HostErr}, standard_icd::{WireError, ERROR_PATH}, }; use std::convert::Infallible; use bioz_icd_rs::{ PingEndpoint, GetUniqueIdEndpoint, SetGreenLedEndpoint, StartImpedance, StartImpedanceEndpoint, StopImpedanceEndpoint, }; #[derive(Debug)] pub struct WorkbookClient { pub client: HostClient, } #[derive(Debug)] pub enum WorkbookError { Comms(HostErr), Endpoint(E), } impl From> for WorkbookError { fn from(value: HostErr) -> Self { Self::Comms(value) } } trait FlattenErr { type Good; type Bad; fn flatten(self) -> Result>; } impl FlattenErr for Result { type Good = T; type Bad = E; fn flatten(self) -> Result> { self.map_err(WorkbookError::Endpoint) } } // --- impl WorkbookClient { pub fn new() -> Self { let client = HostClient::new_raw_nusb( |d| d.product_string() == Some("Bioz Amplifier"), ERROR_PATH, 8, VarSeqKind::Seq2, ); Self { client } } pub fn new_serial(port: &str) -> Self { let client = HostClient::new_serial_cobs(port, ERROR_PATH, 8, 9600, VarSeqKind::Seq2); Self { client } } pub async fn wait_closed(&self) { self.client.wait_closed().await; } pub async fn ping(&self, id: u32) -> Result> { let val = self.client.send_resp::(&id).await?; Ok(val) } pub async fn get_id(&self) -> Result<[u8; 12], WorkbookError> { let id = self.client.send_resp::(&()).await?; Ok(id) } pub async fn set_green_led( &self, frequency: f32, ) -> Result<(), WorkbookError> { self.client.send_resp::(&frequency).await?; Ok(()) } pub async fn start_impedancemeter( &self, frequency: f32, ) -> Result<(), WorkbookError> { self.client .send_resp::(&StartImpedance { update_frequency: 60, sinus_frequency: frequency }) .await?; Ok(()) } pub async fn stop_impedancemeter(&self) -> Result> { let res = self .client .send_resp::(&()) .await?; Ok(res) } } impl Default for WorkbookClient { fn default() -> Self { Self::new() } }