From fabd8a2fcaa77ab32c014a4547f398f7817cf218 Mon Sep 17 00:00:00 2001 From: David Beechey Date: Tue, 14 Jan 2025 21:46:41 +0000 Subject: [PATCH] SNS - Sensor Bounds Checking (#59) --- Cargo.lock | 14 +-- boards/stm32f767zi/Cargo.lock | 1 + boards/stm32f767zi/Cargo.toml | 1 + boards/stm32f767zi/src/tasks/temperature.rs | 19 ++- boards/stm32l432kc/Cargo.lock | 125 +++++++++----------- boards/stm32l476rg/Cargo.lock | 1 + boards/stm32l476rg/Cargo.toml | 1 + boards/stm32l476rg/src/bin/mux_test.rs | 19 ++- boards/stm32l476rg/src/tasks/temperature.rs | 19 ++- lib/sensors/src/lib.rs | 11 ++ lib/sensors/src/temperature.rs | 48 ++++++-- 11 files changed, 162 insertions(+), 97 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 59007414..e6782893 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,7 +96,7 @@ dependencies = [ "defmt", "document-features", "embassy-net-driver", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "embassy-time", "embedded-io-async", "embedded-nal-async", @@ -128,8 +128,8 @@ dependencies = [ [[package]] name = "embassy-sync" -version = "0.6.0" -source = "git+https://github.com/embassy-rs/embassy#8d8cd78f634b2f435e3a997f7f8f3ac0b8ca300c" +version = "0.6.1" +source = "git+https://github.com/embassy-rs/embassy#4b0e20315bddbb15aaee0e0b96548de405694c7b" dependencies = [ "cfg-if", "critical-section", @@ -298,7 +298,7 @@ dependencies = [ name = "hyped_adc" version = "0.1.0" dependencies = [ - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy)", + "embassy-sync 0.6.1", "heapless", ] @@ -334,7 +334,7 @@ dependencies = [ name = "hyped_i2c" version = "0.1.0" dependencies = [ - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "heapless", ] @@ -351,7 +351,7 @@ dependencies = [ name = "hyped_sensors" version = "0.1.0" dependencies = [ - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "heapless", "hyped_core", "hyped_gpio_input", @@ -362,7 +362,7 @@ dependencies = [ name = "hyped_spi" version = "0.1.0" dependencies = [ - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "heapless", ] diff --git a/boards/stm32f767zi/Cargo.lock b/boards/stm32f767zi/Cargo.lock index 57b3f5de..4c37f5b5 100644 --- a/boards/stm32f767zi/Cargo.lock +++ b/boards/stm32f767zi/Cargo.lock @@ -572,6 +572,7 @@ dependencies = [ "embedded-storage", "hyped_adc", "hyped_adc_derive", + "hyped_core", "hyped_gpio_input", "hyped_gpio_input_derive", "hyped_i2c", diff --git a/boards/stm32f767zi/Cargo.toml b/boards/stm32f767zi/Cargo.toml index 3aac42ec..8839fa0f 100644 --- a/boards/stm32f767zi/Cargo.toml +++ b/boards/stm32f767zi/Cargo.toml @@ -23,6 +23,7 @@ critical-section = "1.1" embedded-storage = "0.3.1" static_cell = "2" +hyped_core = { path = "../../lib/core" } hyped_sensors = { path = "../../lib/sensors" } hyped_adc = { path = "../../lib/io/hyped_adc" } diff --git a/boards/stm32f767zi/src/tasks/temperature.rs b/boards/stm32f767zi/src/tasks/temperature.rs index de6bb966..7f6ee215 100644 --- a/boards/stm32f767zi/src/tasks/temperature.rs +++ b/boards/stm32f767zi/src/tasks/temperature.rs @@ -4,7 +4,10 @@ use defmt_rtt as _; use embassy_stm32::time::Hertz; use embassy_stm32::{i2c::I2c, mode::Blocking}; use embassy_sync::blocking_mutex::{raw::NoopRawMutex, Mutex}; -use hyped_sensors::temperature::{Status, Temperature, TemperatureAddresses}; +use hyped_sensors::{ + temperature::{Status, Temperature, TemperatureAddresses}, + SensorValueRange::*, +}; use static_cell::StaticCell; type I2c1Bus = Mutex>>; @@ -42,9 +45,17 @@ pub async fn read_temp() -> ! { } match temperature_sensor.read() { - Some(temperature) => { - defmt::info!("Temperature: {:?}", temperature); - } + Some(temperature) => match temperature { + Safe(temp) => { + defmt::info!("Temperature: {}°C (safe)", temp); + } + Warning(temp) => { + defmt::warn!("Temperature: {}°C (unsafe)", temp); + } + Critical(temp) => { + defmt::error!("Temperature: {}°C (critical)", temp); + } + }, None => { defmt::info!("Failed to read temperature."); } diff --git a/boards/stm32l432kc/Cargo.lock b/boards/stm32l432kc/Cargo.lock index c739d60c..b7bacccb 100644 --- a/boards/stm32l432kc/Cargo.lock +++ b/boards/stm32l432kc/Cargo.lock @@ -43,9 +43,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" [[package]] name = "byteorder" @@ -89,7 +89,7 @@ checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -119,7 +119,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.87", + "syn", ] [[package]] @@ -130,14 +130,14 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.87", + "syn", ] [[package]] name = "defmt" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -145,22 +145,22 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.3.9" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" dependencies = [ "defmt-parser", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] name = "defmt-parser" -version = "0.3.4" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" dependencies = [ "thiserror", ] @@ -191,7 +191,7 @@ source = "git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f70631 dependencies = [ "defmt", "embassy-futures", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "embassy-time", "embedded-hal 0.2.7", "embedded-hal 1.0.0", @@ -223,7 +223,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -250,7 +250,7 @@ dependencies = [ "defmt", "document-features", "embassy-net-driver", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "embassy-time", "embedded-io-async", "embedded-nal-async", @@ -273,7 +273,7 @@ version = "0.1.0" source = "git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7#1c466b81e6af6b34b1f706318cc0870a459550b7" dependencies = [ "bit_field", - "bitflags 2.6.0", + "bitflags 2.7.0", "cfg-if", "cortex-m", "cortex-m-rt", @@ -284,7 +284,7 @@ dependencies = [ "embassy-futures", "embassy-hal-internal", "embassy-net-driver", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "embassy-time", "embassy-time-driver", "embassy-usb-driver", @@ -326,8 +326,8 @@ dependencies = [ [[package]] name = "embassy-sync" -version = "0.6.0" -source = "git+https://github.com/embassy-rs/embassy#46f91151693c68c074293ddc4daf0c94058f9587" +version = "0.6.1" +source = "git+https://github.com/embassy-rs/embassy#4b0e20315bddbb15aaee0e0b96548de405694c7b" dependencies = [ "cfg-if", "critical-section", @@ -383,7 +383,7 @@ version = "0.1.0" source = "git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7#1c466b81e6af6b34b1f706318cc0870a459550b7" dependencies = [ "critical-section", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy?rev=1c466b81e6af6b34b1f706318cc0870a459550b7)", + "embassy-sync 0.6.0", "embassy-usb-driver", ] @@ -557,7 +557,7 @@ dependencies = [ "embassy-futures", "embassy-net", "embassy-stm32", - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy)", + "embassy-sync 0.6.1", "embassy-time", "embedded-hal 0.2.7", "embedded-storage", @@ -591,7 +591,7 @@ dependencies = [ name = "hyped_i2c" version = "0.1.0" dependencies = [ - "embassy-sync 0.6.0 (git+https://github.com/embassy-rs/embassy)", + "embassy-sync 0.6.0", "heapless", ] @@ -599,6 +599,7 @@ dependencies = [ name = "hyped_sensors" version = "0.1.0" dependencies = [ + "embassy-sync 0.6.0", "heapless", "hyped_core", "hyped_gpio_input", @@ -665,9 +666,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -677,48 +678,46 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.109", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -774,22 +773,22 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] @@ -853,19 +852,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.87" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -874,29 +863,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.69" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.69" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn", ] [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "vcell" @@ -904,12 +893,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "void" version = "1.0.2" diff --git a/boards/stm32l476rg/Cargo.lock b/boards/stm32l476rg/Cargo.lock index e533b6d2..c20347e1 100644 --- a/boards/stm32l476rg/Cargo.lock +++ b/boards/stm32l476rg/Cargo.lock @@ -572,6 +572,7 @@ dependencies = [ "embedded-storage", "hyped_adc", "hyped_adc_derive", + "hyped_core", "hyped_gpio_input", "hyped_gpio_input_derive", "hyped_i2c", diff --git a/boards/stm32l476rg/Cargo.toml b/boards/stm32l476rg/Cargo.toml index b572e82f..ee3c6640 100644 --- a/boards/stm32l476rg/Cargo.toml +++ b/boards/stm32l476rg/Cargo.toml @@ -23,6 +23,7 @@ critical-section = "1.1" embedded-storage = "0.3.1" static_cell = "2" +hyped_core ={ path = "../../lib/core" } hyped_sensors = { path = "../../lib/sensors" } hyped_adc = { path = "../../lib/io/hyped_adc" } diff --git a/boards/stm32l476rg/src/bin/mux_test.rs b/boards/stm32l476rg/src/bin/mux_test.rs index ce4490bc..ed798ec5 100644 --- a/boards/stm32l476rg/src/bin/mux_test.rs +++ b/boards/stm32l476rg/src/bin/mux_test.rs @@ -10,7 +10,10 @@ use embassy_sync::blocking_mutex::Mutex; use embassy_time::{Duration, Timer}; use hyped_boards_stm32l476rg::io::Stm32l476rgI2c; use hyped_i2c::i2c_mux::I2cMux; -use hyped_sensors::temperature::{Temperature, TemperatureAddresses}; +use hyped_sensors::{ + temperature::{Temperature, TemperatureAddresses}, + SensorValueRange::*, +}; use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; @@ -51,9 +54,17 @@ async fn read_temperature_from_mux( loop { match temperature_sensor.read() { - Some(temperature) => { - defmt::info!("Temperature ({:?}): {:?}", channel, temperature); - } + Some(temperature) => match temperature { + Safe(temp) => { + defmt::info!("Temperature: {}°C (safe)", temp); + } + Warning(temp) => { + defmt::warn!("Temperature: {}°C (warning)", temp); + } + Critical(temp) => { + defmt::error!("Temperature: {}°C (critical)", temp); + } + }, None => { defmt::info!("Failed to read temperature."); } diff --git a/boards/stm32l476rg/src/tasks/temperature.rs b/boards/stm32l476rg/src/tasks/temperature.rs index 227761ce..cb68b4ee 100644 --- a/boards/stm32l476rg/src/tasks/temperature.rs +++ b/boards/stm32l476rg/src/tasks/temperature.rs @@ -4,7 +4,10 @@ use defmt_rtt as _; use embassy_stm32::time::Hertz; use embassy_stm32::{i2c::I2c, mode::Blocking}; use embassy_sync::blocking_mutex::{raw::NoopRawMutex, Mutex}; -use hyped_sensors::temperature::{Status, Temperature, TemperatureAddresses}; +use hyped_sensors::{ + temperature::{Status, Temperature, TemperatureAddresses}, + SensorValueRange::*, +}; use static_cell::StaticCell; type I2c1Bus = Mutex>>; @@ -42,9 +45,17 @@ pub async fn read_temp() -> ! { } match temperature_sensor.read() { - Some(temperature) => { - defmt::info!("Temperature: {:?}", temperature); - } + Some(temperature) => match temperature { + Safe(temp) => { + defmt::info!("Temperature: {}°C (safe)", temp); + } + Warning(temp) => { + defmt::warn!("Temperature: {}°C (warning)", temp); + } + Critical(temp) => { + defmt::error!("Temperature: {}°C (critical)", temp); + } + }, None => { defmt::info!("Failed to read temperature."); } diff --git a/lib/sensors/src/lib.rs b/lib/sensors/src/lib.rs index bf4b49cf..38b578a5 100644 --- a/lib/sensors/src/lib.rs +++ b/lib/sensors/src/lib.rs @@ -2,3 +2,14 @@ pub mod keyence; pub mod temperature; + +#[must_use] +#[derive(PartialEq, Debug)] +pub enum SensorValueRange { + /// This is the normal range of values for the sensor. + Safe(T), + /// Sensor values are outwith the normal range, but not yet critical. + Warning(T), + /// This is the range of values that are considered critical and will trigger an emergency. + Critical(T), +} diff --git a/lib/sensors/src/temperature.rs b/lib/sensors/src/temperature.rs index a5ecb5a1..dbb6c3ee 100644 --- a/lib/sensors/src/temperature.rs +++ b/lib/sensors/src/temperature.rs @@ -1,5 +1,7 @@ use hyped_i2c::{HypedI2c, I2cError}; +use crate::SensorValueRange; + /// Temperature implements the logic to read the temperature from the STTS22H temperature sensor /// using the I2C peripheral provided by the HypedI2c trait. /// @@ -10,6 +12,7 @@ use hyped_i2c::{HypedI2c, I2cError}; pub struct Temperature<'a, T: HypedI2c> { i2c: &'a mut T, device_address: u8, + calculate_bounds: fn(f32) -> SensorValueRange, } impl<'a, T: HypedI2c> Temperature<'a, T> { @@ -17,6 +20,15 @@ impl<'a, T: HypedI2c> Temperature<'a, T> { pub fn new( i2c: &'a mut T, device_address: TemperatureAddresses, + ) -> Result { + Self::new_with_bounds(i2c, device_address, default_calculate_bounds) + } + + /// Create a new instance of the temperature sensor with the specified bounds and attempt to configure it + pub fn new_with_bounds( + i2c: &'a mut T, + device_address: TemperatureAddresses, + calculate_bounds: fn(f32) -> SensorValueRange, ) -> Result { // Set up the temperature sensor by sending the configuration settings to the STTS22H_CTRL register let device_address = device_address as u8; @@ -24,13 +36,16 @@ impl<'a, T: HypedI2c> Temperature<'a, T> { Ok(_) => Ok(Self { i2c, device_address, + calculate_bounds, }), Err(e) => Err(TemperatureError::I2cError(e)), } } - /// Read the temperature from the sensor and return it as a floating point value in degrees Celsius - pub fn read(&mut self) -> Option { + /// Read the temperature from the sensor and return it as a floating point value in degrees Celsius. + /// Returns None if there was an error reading the temperature, otherwise returns the temperature + /// wrapped in a SensorValueRange enum to indicate if the temperature is safe, warning, or critical. + pub fn read(&mut self) -> Option> { // Read the high and low bytes of the temperature and combine them to get the temperature let temperature_high_byte = self .i2c @@ -42,12 +57,17 @@ impl<'a, T: HypedI2c> Temperature<'a, T> { let combined: f32 = ((temperature_high_byte as u16) << 8 | temperature_low_byte as u16) as f32; + // Check if the temperature is negative if combined >= TWO_POWER_15 { // Convert the temperature to a negative value - return Some((combined - TWO_POWER_16) * STTS22H_TEMP_SCALING_FACTOR); + return Some((self.calculate_bounds)( + (combined - TWO_POWER_16) * STTS22H_TEMP_SCALING_FACTOR, + )); } - Some(combined * STTS22H_TEMP_SCALING_FACTOR) + Some((self.calculate_bounds)( + combined * STTS22H_TEMP_SCALING_FACTOR, + )) } /// Check the status of the temperature sensor @@ -98,6 +118,20 @@ impl Status { } } +/// Default calculation of the bounds for the temperature sensor. The bounds are set to: +/// - Safe: 20.0 to 80.0 degrees Celsius +/// - Warning: 0.0 to 20.0 and 80.0 to 100.0 degrees Celsius +/// - Critical: Below 0.0 and above 100.0 degrees Celsius +pub fn default_calculate_bounds(value: f32) -> SensorValueRange { + if value <= 0.0 || value >= 100.0 { + SensorValueRange::Critical(value) + } else if value <= 20.0 || value >= 80.0 { + SensorValueRange::Warning(value) + } else { + SensorValueRange::Safe(value) + } +} + // Registers for the STTS22H temperature sensor const STTS22H_CTRL: u8 = 0x04; const STTS22H_DATA_TEMP_L: u8 = 0x06; @@ -152,7 +186,7 @@ mod tests { let i2c_values = Mutex::new(RefCell::new(i2c_values)); let mut i2c = MockI2c::new(&i2c_values); let mut temperature = Temperature::new(&mut i2c, TemperatureAddresses::Address3f).unwrap(); - assert_eq!(temperature.read(), Some(0.0)); + assert_eq!(temperature.read(), Some(SensorValueRange::Critical(0.0))); } #[test] @@ -169,7 +203,7 @@ mod tests { let i2c_values = Mutex::new(RefCell::new(i2c_values)); let mut i2c = MockI2c::new(&i2c_values); let mut temperature = Temperature::new(&mut i2c, TemperatureAddresses::Address3f).unwrap(); - assert_eq!(temperature.read(), Some(25.0)); + assert_eq!(temperature.read(), Some(SensorValueRange::Safe(25.0))); } #[test] @@ -186,7 +220,7 @@ mod tests { let i2c_values = Mutex::new(RefCell::new(i2c_values)); let mut i2c = MockI2c::new(&i2c_values); let mut temperature = Temperature::new(&mut i2c, TemperatureAddresses::Address3f).unwrap(); - assert_eq!(temperature.read(), Some(-10.0)); + assert_eq!(temperature.read(), Some(SensorValueRange::Critical(-10.0))); } #[test]