diff --git a/Cargo.lock b/Cargo.lock index defe0e6..8302691 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,9 +230,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.15" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" dependencies = [ "proc-macro2", "quote", diff --git a/src/main.rs b/src/main.rs index 69cb58e..b1c4fa3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ mod obd2; use obd2::Obd2Device; +use std::time; + fn main() { env_logger::init(); let mut device: obd2::Obd2 = obd2::Obd2::default(); @@ -20,4 +22,10 @@ fn main() { } } } + + let state = time::Instant::now(); + while state.elapsed() < time::Duration::from_secs(5) { + println!("RPM: {:?}", device.get_rpm()); + println!("Speed: {:?}", device.get_speed()); + } } diff --git a/src/obd2/accessors.rs b/src/obd2/accessors.rs index 37ff5d5..006779e 100644 --- a/src/obd2/accessors.rs +++ b/src/obd2/accessors.rs @@ -6,6 +6,33 @@ pub trait Obd2Device { fn obd_command(&mut self, mode: u8, pid: u8) -> Result>>; fn obd_mode_command(&mut self, mode: u8) -> Result>>; + fn obd_command_len( + &mut self, + mode: u8, + pid: u8, + ) -> Result> { + self.obd_command(mode, pid)? + .into_iter() + .map(|v| { + let l = v.len(); + v.try_into() + .map_err(|_| Error::IncorrectResponseLength("length", RESPONSE_LENGTH, l)) + }) + .collect() + } + + fn obd_command_cnt_len( + &mut self, + mode: u8, + pid: u8, + ) -> Result<[[u8; RESPONSE_LENGTH]; RESPONSE_COUNT]> { + let result = self.obd_command_len::(mode, pid)?; + let count = result.len(); + result + .try_into() + .map_err(|_| Error::IncorrectResponseLength("count", RESPONSE_COUNT, count)) + } + fn get_vin(&mut self) -> Result { let mut result = self.obd_command(0x09, 0x02)?.pop().unwrap(); result.remove(0); // do not know what this byte is @@ -74,6 +101,15 @@ pub trait Obd2Device { }) .collect::>>>() } + + fn get_rpm(&mut self) -> Result { + let result = self.obd_command_cnt_len::<1, 2>(0x01, 0x0C)?[0]; + Ok(f32::from(u16::from_be_bytes(result)) / 4.0) + } + + fn get_speed(&mut self) -> Result { + Ok(self.obd_command_cnt_len::<1, 1>(0x01, 0x0C)?[0][0]) + } } #[allow(dead_code)] @@ -108,15 +144,20 @@ impl fmt::Display for Dtc { #[derive(thiserror::Error, Debug)] pub enum Error { - #[error("Communication error: `{0:?}`")] - Communication(super::device::Error), + #[error("Device error: `{0:?}`")] + Device(DeviceError), #[error("Other OBD2 error: `{0}`")] Other(String), + #[error("Incorrect length (`{0}`): expected `{1}`, got `{2}`")] + IncorrectResponseLength(&'static str, usize, usize), } +#[derive(Debug)] +pub struct DeviceError(super::device::Error); + impl From for Error { fn from(e: super::device::Error) -> Self { - Error::Communication(e) + Error::Device(DeviceError(e)) } }