/ src / hardware / sensor.rs
sensor.rs
 1  /// BME680 sensor operations
 2  use anyhow::Result;
 3  use bme680::Bme680;
 4  use esp_idf_hal::delay::FreeRtos;
 5  use esp_idf_hal::i2c::I2cDriver;
 6  use serde::Serialize;
 7  
 8  use crate::settings::BME680_MEASUREMENT_DELAY_MS;
 9  
10  #[derive(Debug, Serialize)]
11  pub struct BmeMetrics {
12      pub temp_c: f32,
13      pub humidity_percent: f32,
14      pub pressure_hpa: f32,
15      pub gas_resistance_ohm: u32,
16      pub gas_kohm: f32,
17      pub gas_valid: bool,
18      pub heat_stable: bool,
19  }
20  
21  /// Wrapper for BME680 sensor operations
22  pub struct SensorReader;
23  
24  impl SensorReader {
25      /// Read temperature, humidity, and gas resistance (optimized for automation)
26      pub fn read_quick(bme: &mut Bme680<I2cDriver, FreeRtos>) -> Result<(f32, f32, f32)> {
27          let mut delay = FreeRtos;
28          bme.set_sensor_mode(&mut delay, bme680::PowerMode::ForcedMode)
29              .map_err(|e| anyhow::anyhow!("BME680 mode error: {:?}", e))?;
30  
31          // Use constant delay for BME680 measurement (150ms for gas heater stability)
32          FreeRtos::delay_ms(BME680_MEASUREMENT_DELAY_MS);
33  
34          let (data, _) = bme
35              .get_sensor_data(&mut delay)
36              .map_err(|e| anyhow::anyhow!("BME680 read error: {:?}", e))?;
37  
38          Ok((
39              data.temperature_celsius(),
40              data.humidity_percent(),
41              data.gas_resistance_ohm() as f32 / 1000.0, // Convert to kohm
42          ))
43      }
44  
45      /// Read full metrics for MQTT publishing
46      pub fn read_full_metrics(bme: &mut Bme680<I2cDriver, FreeRtos>) -> Result<BmeMetrics> {
47          let mut delay = FreeRtos;
48          bme.set_sensor_mode(&mut delay, bme680::PowerMode::ForcedMode)
49              .map_err(|e| anyhow::anyhow!("BME680 mode error: {:?}", e))?;
50  
51          // Use constant delay for BME680 measurement (150ms for gas heater stability)
52          FreeRtos::delay_ms(BME680_MEASUREMENT_DELAY_MS);
53  
54          let (data, _) = bme
55              .get_sensor_data(&mut delay)
56              .map_err(|e| anyhow::anyhow!("BME680 read error: {:?}", e))?;
57  
58          Ok(BmeMetrics {
59              temp_c: data.temperature_celsius(),
60              humidity_percent: data.humidity_percent(),
61              pressure_hpa: data.pressure_hpa(),
62              gas_resistance_ohm: data.gas_resistance_ohm(),
63              gas_kohm: data.gas_resistance_ohm() as f32 / 1000.0,
64              gas_valid: data.gas_valid(),
65              heat_stable: data.heat_stable(),
66          })
67      }
68  }