Skip to content

Commit

Permalink
Add BME280 logic
Browse files Browse the repository at this point in the history
  • Loading branch information
liamadamson committed Nov 24, 2023
1 parent 2ce0b88 commit 0874297
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 4 deletions.
10 changes: 9 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@
name = "room-monitor"
version = "0.1.0"

[dependencies]
[dependencies]
anyhow = "1.0.75"
env_logger = "0.10.1"
log = "0.4.20"
mockall = "0.11.4"

[target.'cfg(target_os = "linux")'.dependencies]
bme280 = "0.4.4"
linux-embedded-hal = "0.4.0-alpha.2"
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FROM rust:1.67 as builder
FROM rust:latest as builder
WORKDIR /usr/src/myapp
COPY . .
RUN cargo install --path .

FROM debian:bullseye-slim
FROM debian
COPY --from=builder /usr/local/cargo/bin/room-monitor /usr/local/bin/room-monitor
CMD ["room-monitor"]
36 changes: 36 additions & 0 deletions src/driver/linux.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
extern crate bme280;
extern crate linux_embedded_hal as hal;

use super::{BME280Driver, Readings};

pub struct LinuxBME280Driver {
bme280: bme280::i2c::BME280<hal::I2cdev>,
}

impl LinuxBME280Driver {
pub fn new() -> anyhow::Result<Self> {
match hal::I2cdev::new("/dev/i2c-1") {
Ok(i2c_bus) => {
let mut bme280 = bme280::i2c::BME280::new_primary(i2c_bus);
match bme280.init(&mut hal::Delay) {
Ok(_) => Ok(Self { bme280 }),
Err(_) => Err(anyhow::anyhow!("Failed to init BME280.")),
}
}
Err(_) => Err(anyhow::anyhow!("Failed to open I2C bus.")),
}
}
}

impl BME280Driver for LinuxBME280Driver {
fn read(&mut self) -> anyhow::Result<Readings> {
match self.bme280.measure(&mut hal::Delay) {
Ok(measurements) => Ok(Readings {
temperature: measurements.temperature,
pressure: measurements.pressure,
humidity: measurements.humidity,
}),
Err(_) => Err(anyhow::anyhow!("Failed to read measurements.")),
}
}
}
32 changes: 32 additions & 0 deletions src/driver/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#[cfg(target_os = "linux")]
pub mod linux;

#[cfg(target_os = "linux")]
pub fn get_bme280_driver() -> anyhow::Result<impl BME280Driver> {
Ok(linux::LinuxBME280Driver::new()?)
}

#[cfg(not(target_os = "linux"))]
pub fn get_bme280_driver() -> anyhow::Result<impl BME280Driver> {
let mut driver = MockBME280Driver::new();
driver.expect_read().returning(|| {
Ok(Readings {
temperature: 18.5,
pressure: 1013.25,
humidity: 45.0,
})
});

Ok(driver)
}

pub struct Readings {
pub temperature: f32,
pub pressure: f32,
pub humidity: f32,
}

#[mockall::automock]
pub trait BME280Driver {
fn read(&mut self) -> anyhow::Result<Readings>;
}
58 changes: 57 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,59 @@
pub mod driver;

use driver::{get_bme280_driver, BME280Driver};
use std::thread::sleep;
use std::time::Duration;

const LOOP_RATE_S: u64 = 1;

fn main() {
println!("Hello, world!");
setup_logging();

log::info!("Application started");

let driver = get_bme280_driver().expect("Failed to get BME280 driver");
let mut runner = Runner::new(driver);

loop {
if let Err(e) = runner.step() {
log::error!("Error steppinf runner: {}", e);
}

sleep(Duration::from_secs(LOOP_RATE_S));
}
}

fn setup_logging() {
let mut builder = env_logger::Builder::from_default_env();
builder
.filter_level(log::LevelFilter::Debug)
.target(env_logger::Target::Stdout)
.init();
}

struct Runner<T>
where
T: BME280Driver,
{
driver: T,
}

impl<T> Runner<T>
where
T: BME280Driver,
{
fn new(driver: T) -> Self {
Self { driver }
}

fn step(&mut self) -> anyhow::Result<()> {
let readings = self.driver.read()?;
log::info!(
"{} degC,\t {} hPa,\t {} %",
readings.temperature,
readings.pressure,
readings.humidity
);
Ok(())
}
}

0 comments on commit 0874297

Please sign in to comment.