use crate::{error::DataError, util::check_deserialization};
#[derive(Debug, PartialEq)]
pub struct Measurement {
pub pm1_0: f32,
pub pm2_5: f32,
pub pm4_0: f32,
pub pm10_0: f32,
pub relative_humidity: f32,
pub temperature: f32,
pub voc_index: f32,
pub nox_index: f32,
pub co2: u16,
}
impl TryFrom<&[u8]> for Measurement {
type Error = DataError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
check_deserialization(data, 27)?;
Ok(Self {
pm1_0: u16::from_be_bytes([data[0], data[1]]) as f32 / 10.,
pm2_5: u16::from_be_bytes([data[3], data[4]]) as f32 / 10.,
pm4_0: u16::from_be_bytes([data[6], data[7]]) as f32 / 10.,
pm10_0: u16::from_be_bytes([data[9], data[10]]) as f32 / 10.,
relative_humidity: i16::from_be_bytes([data[12], data[13]]) as f32 / 100.,
temperature: i16::from_be_bytes([data[15], data[16]]) as f32 / 200.,
voc_index: i16::from_be_bytes([data[18], data[19]]) as f32 / 10.,
nox_index: i16::from_be_bytes([data[21], data[22]]) as f32 / 10.,
co2: u16::from_be_bytes([data[24], data[25]]),
})
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for Measurement {
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"PM1.0: {} ug/m³
PM2.5: {} ug/m³
PM4.0: {} ug/m³
PM10.0: {} ug/m³
RH: {} %
Temp: {} °C
VOC Index: {} / 1
NOx Index: {} / 100
CO2: {} ppm",
self.pm1_0,
self.pm2_5,
self.pm4_0,
self.pm10_0,
self.relative_humidity,
self.temperature,
self.voc_index,
self.nox_index,
self.co2
)
}
}
#[derive(Debug, PartialEq)]
pub struct RawMeasurement {
pub relative_humidity: f32,
pub temperature: f32,
pub voc: u16,
pub nox: u16,
pub co2: u16,
}
impl TryFrom<&[u8]> for RawMeasurement {
type Error = DataError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
check_deserialization(data, 15)?;
Ok(Self {
relative_humidity: i16::from_be_bytes([data[0], data[1]]) as f32 / 100.,
temperature: i16::from_be_bytes([data[3], data[4]]) as f32 / 200.,
voc: u16::from_be_bytes([data[6], data[7]]),
nox: u16::from_be_bytes([data[9], data[10]]),
co2: u16::from_be_bytes([data[12], data[13]]),
})
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for RawMeasurement {
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"RH: {} %
Temp: {} °C
VOC: {} ticks
NOx: {} ticks
CO2: {} ppm",
self.relative_humidity,
self.temperature,
self.voc,
self.nox,
self.co2
)
}
}
#[derive(Debug, PartialEq)]
pub struct Concentrations {
pub pm0_5: f32,
pub pm1_0: f32,
pub pm2_5: f32,
pub pm4_0: f32,
pub pm10_0: f32,
}
impl TryFrom<&[u8]> for Concentrations {
type Error = DataError;
fn try_from(data: &[u8]) -> Result<Self, Self::Error> {
check_deserialization(data, 15)?;
Ok(Self {
pm0_5: u16::from_be_bytes([data[0], data[1]]) as f32 / 10.,
pm1_0: u16::from_be_bytes([data[3], data[4]]) as f32 / 10.,
pm2_5: u16::from_be_bytes([data[6], data[7]]) as f32 / 10.,
pm4_0: u16::from_be_bytes([data[9], data[10]]) as f32 / 10.,
pm10_0: u16::from_be_bytes([data[12], data[13]]) as f32 / 10.,
})
}
}
#[cfg(feature = "defmt")]
impl defmt::Format for Concentrations {
fn format(&self, f: defmt::Formatter) {
defmt::write!(
f,
"PM0.5: {} p/cm³
PM1.0: {} p/cm³
PM2.5: {} p/cm³
PM4.0: {} p/cm³
PM10.0: {} p/cm³",
self.pm0_5,
self.pm1_0,
self.pm2_5,
self.pm4_0,
self.pm10_0
)
}
}