Skip to content

Commit 230c581

Browse files
douglascghCopilot
andauthored
Add set function blocking version consolidate with test (#41)
Certain functionalities are only defined as async traits and not available in blocking. Expanding the relevant function so the macro also generates blocking version so it can be adopted to an environment where async support is not available such as driver running in Zephyr. The macro that generates async function has been expanded to also generate blocking function for traits that is relevant for both blocking and async. The patch also expands the current set to cover the newly added blocking traits. --------- Co-authored-by: Copilot <[email protected]>
1 parent deeabe0 commit 230c581

File tree

9 files changed

+409
-64
lines changed

9 files changed

+409
-64
lines changed

Cargo.lock

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

embedded-sensors-async/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "MIT"
99
name = "embedded-sensors-hal-async"
1010
readme = "README.md"
1111
repository = "https://github.com/OpenDevicePartnership/embedded-sensors"
12-
version = "0.3.0"
12+
version = "0.4.0"
1313

1414
[features]
1515
defmt = ["dep:defmt", "embedded-sensors-hal/defmt"]

embedded-sensors-async/src/humidity.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,7 @@
8282
//! }
8383
//! ```
8484
85-
use crate::decl_threshold_traits;
86-
use crate::sensor::ErrorType;
85+
use crate::sensor::{decl_threshold_traits, ErrorType};
8786
pub use embedded_sensors_hal::humidity::Percentage;
8887

8988
/// Async Relative Humidity Sensor methods.
@@ -99,7 +98,22 @@ impl<T: RelativeHumiditySensor + ?Sized> RelativeHumiditySensor for &mut T {
9998
}
10099
}
101100

101+
// This macro generates the following async threshold traits:
102+
//
103+
// pub trait RelativeHumidityThresholdSet: RelativeHumiditySensor {
104+
// async fn set_relative_humidity_threshold_low(&mut self, threshold: Percentage) -> Result<(), Self::Error>;
105+
// async fn set_relative_humidity_threshold_high(&mut self, threshold: Percentage) -> Result<(), Self::Error>;
106+
// }
107+
//
108+
// pub trait RelativeHumidityHysteresis: RelativeHumidityThresholdSet {
109+
// async fn set_relative_humidity_threshold_hysteresis(&mut self, hysteresis: Percentage) -> Result<(), Self::Error>;
110+
// }
111+
//
112+
// pub trait RelativeHumidityThresholdWait: RelativeHumidityThresholdSet {
113+
// async fn wait_for_relative_humidity_threshold(&mut self) -> Result<Percentage, Self::Error>;
114+
// }
102115
decl_threshold_traits!(
116+
async,
103117
RelativeHumidity,
104118
RelativeHumiditySensor,
105119
Percentage,

embedded-sensors-async/src/sensor.rs

Lines changed: 4 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,59 +2,11 @@
22
//!
33
//! This module contains traits generic to all sensors.
44
//!
5-
//! Please see specific sensor-type modules for addtional example usage
5+
//! Please see specific sensor-type modules for additional example usage
66
//! (e.g. see temperature.rs for TemperatureSensor examples).
77
88
pub use embedded_sensors_hal::sensor::{Error, ErrorKind, ErrorType};
99

10-
/// Generates threshold traits for the specified sensor type.
11-
#[macro_export]
12-
macro_rules! decl_threshold_traits {
13-
($SensorName:ident, $SensorTrait:ident, $SampleType:ty, $unit:expr) => {
14-
paste::paste! {
15-
#[doc = concat!(" Asynchronously set ", stringify!($SensorName), " thresholds.")]
16-
pub trait [<$SensorName ThresholdSet>]: $SensorTrait {
17-
#[doc = concat!(" Set lower ", stringify!($SensorName), " threshold (in ", $unit, ").")]
18-
async fn [<set_ $SensorName:snake _threshold_low>](&mut self, threshold: $SampleType) -> Result<(), Self::Error>;
19-
20-
#[doc = concat!(" Set upper ", stringify!($SensorName), " threshold (in ", $unit, ").")]
21-
async fn [<set_ $SensorName:snake _threshold_high>](&mut self, threshold: $SampleType) -> Result<(), Self::Error>;
22-
}
23-
24-
#[doc = concat!(" Asynchronously wait for ", stringify!($SensorName), " measurements to exceed specified thresholds.")]
25-
pub trait [<$SensorName ThresholdWait>]: [<$SensorName ThresholdSet>] {
26-
#[doc = concat!(" Wait for ", stringify!($SensorName), " to be measured above or below the previously set high and low thresholds.")]
27-
#[doc = concat!(" Returns the measured ", stringify!($SensorName), " at time threshold is exceeded (in ", $unit, ").")]
28-
async fn [<wait_for_ $SensorName:snake _threshold>](&mut self) -> Result<$SampleType, Self::Error>;
29-
}
30-
31-
#[doc = concat!(" Asynchronously set ", stringify!($SensorName), " threshold hysteresis.")]
32-
pub trait [<$SensorName Hysteresis>]: [<$SensorName ThresholdSet>] {
33-
#[doc = concat!(" Set ", stringify!($SensorName), " threshold hysteresis (in ", $unit, ").")]
34-
async fn [<set_ $SensorName:snake _threshold_hysteresis>](&mut self, hysteresis: $SampleType) -> Result<(), Self::Error>;
35-
}
36-
37-
impl<T: [<$SensorName ThresholdSet>] + ?Sized> [<$SensorName ThresholdSet>] for &mut T {
38-
async fn [<set_ $SensorName:snake _threshold_low>](&mut self, threshold: $SampleType) -> Result<(), Self::Error> {
39-
T::[<set_ $SensorName:snake _threshold_low>](self, threshold).await
40-
}
41-
42-
async fn [<set_ $SensorName:snake _threshold_high>](&mut self, threshold: $SampleType) -> Result<(), Self::Error> {
43-
T::[<set_ $SensorName:snake _threshold_high>](self, threshold).await
44-
}
45-
}
46-
47-
impl<T: [<$SensorName ThresholdWait>] + ?Sized> [<$SensorName ThresholdWait>] for &mut T {
48-
async fn [<wait_for_ $SensorName:snake _threshold>](&mut self) -> Result<$SampleType, Self::Error> {
49-
T::[<wait_for_ $SensorName:snake _threshold>](self).await
50-
}
51-
}
52-
53-
impl<T: [<$SensorName Hysteresis>] + ?Sized> [<$SensorName Hysteresis>] for &mut T {
54-
async fn [<set_ $SensorName:snake _threshold_hysteresis>](&mut self, hysteresis: $SampleType) -> Result<(), Self::Error> {
55-
T::[<set_ $SensorName:snake _threshold_hysteresis>](self, hysteresis).await
56-
}
57-
}
58-
}
59-
};
60-
}
10+
// Re-export the unified threshold traits macro from the blocking crate.
11+
// The async crate uses the `async` mode to generate async versions of the traits.
12+
pub use embedded_sensors_hal::decl_threshold_traits;

embedded-sensors-async/src/temperature.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@
8181
//! }
8282
//! ```
8383
84-
use crate::decl_threshold_traits;
85-
use crate::sensor::ErrorType;
84+
use crate::sensor::{decl_threshold_traits, ErrorType};
8685
pub use embedded_sensors_hal::temperature::DegreesCelsius;
8786

8887
/// Async Temperature Sensor methods.
@@ -98,7 +97,22 @@ impl<T: TemperatureSensor + ?Sized> TemperatureSensor for &mut T {
9897
}
9998
}
10099

100+
// This macro generates the following async threshold traits:
101+
//
102+
// pub trait TemperatureThresholdSet: TemperatureSensor {
103+
// async fn set_temperature_threshold_low(&mut self, threshold: DegreesCelsius) -> Result<(), Self::Error>;
104+
// async fn set_temperature_threshold_high(&mut self, threshold: DegreesCelsius) -> Result<(), Self::Error>;
105+
// }
106+
//
107+
// pub trait TemperatureHysteresis: TemperatureThresholdSet {
108+
// async fn set_temperature_threshold_hysteresis(&mut self, hysteresis: DegreesCelsius) -> Result<(), Self::Error>;
109+
// }
110+
//
111+
// pub trait TemperatureThresholdWait: TemperatureThresholdSet {
112+
// async fn wait_for_temperature_threshold(&mut self) -> Result<DegreesCelsius, Self::Error>;
113+
// }
101114
decl_threshold_traits!(
115+
async,
102116
Temperature,
103117
TemperatureSensor,
104118
DegreesCelsius,

embedded-sensors/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@ license = "MIT"
99
name = "embedded-sensors-hal"
1010
readme = "README.md"
1111
repository = "https://github.com/OpenDevicePartnership/embedded-sensors"
12-
version = "0.1.0"
12+
version = "0.1.1"
1313

1414
[features]
1515
defmt = ["dep:defmt"]
1616

1717
[dependencies]
1818
defmt = { package = "defmt", version = "1.0.0", optional = true }
19+
paste = "1.0.15"
1920

2021
[dev-dependencies]
2122
assert_approx_eq = "1.1.0"

embedded-sensors/src/humidity.rs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
//! }
4141
//! ```
4242
43+
use crate::decl_threshold_traits;
4344
use crate::sensor::ErrorType;
4445

4546
/// Associates the units relative humidity (RH) samples are measured in with the underlying data type.
@@ -58,6 +59,24 @@ impl<T: RelativeHumiditySensor + ?Sized> RelativeHumiditySensor for &mut T {
5859
}
5960
}
6061

62+
// This macro generates the following blocking threshold traits:
63+
//
64+
// pub trait RelativeHumidityThresholdSet: RelativeHumiditySensor {
65+
// fn set_relative_humidity_threshold_low(&mut self, threshold: Percentage) -> Result<(), Self::Error>;
66+
// fn set_relative_humidity_threshold_high(&mut self, threshold: Percentage) -> Result<(), Self::Error>;
67+
// }
68+
//
69+
// pub trait RelativeHumidityHysteresis: RelativeHumidityThresholdSet {
70+
// fn set_relative_humidity_threshold_hysteresis(&mut self, hysteresis: Percentage) -> Result<(), Self::Error>;
71+
// }
72+
decl_threshold_traits!(
73+
blocking,
74+
RelativeHumidity,
75+
RelativeHumiditySensor,
76+
Percentage,
77+
"percentage"
78+
);
79+
6180
#[cfg(test)]
6281
mod tests {
6382
use super::*;
@@ -78,6 +97,9 @@ mod tests {
7897

7998
struct MockHumiditySensor {
8099
value: Percentage,
100+
threshold_low: Option<Percentage>,
101+
threshold_high: Option<Percentage>,
102+
hysteresis: Option<Percentage>,
81103
}
82104

83105
impl crate::sensor::ErrorType for MockHumiditySensor {
@@ -90,10 +112,41 @@ mod tests {
90112
}
91113
}
92114

115+
impl RelativeHumidityThresholdSet for MockHumiditySensor {
116+
fn set_relative_humidity_threshold_low(
117+
&mut self,
118+
threshold: Percentage,
119+
) -> Result<(), Self::Error> {
120+
self.threshold_low = Some(threshold);
121+
Ok(())
122+
}
123+
124+
fn set_relative_humidity_threshold_high(
125+
&mut self,
126+
threshold: Percentage,
127+
) -> Result<(), Self::Error> {
128+
self.threshold_high = Some(threshold);
129+
Ok(())
130+
}
131+
}
132+
133+
impl RelativeHumidityHysteresis for MockHumiditySensor {
134+
fn set_relative_humidity_threshold_hysteresis(
135+
&mut self,
136+
hysteresis: Percentage,
137+
) -> Result<(), Self::Error> {
138+
self.hysteresis = Some(hysteresis);
139+
Ok(())
140+
}
141+
}
142+
93143
#[test]
94144
fn test_humidity_sensor_trait() {
95145
let mut sensor = MockHumiditySensor {
96146
value: TEST_HUMIDITY,
147+
threshold_low: None,
148+
threshold_high: None,
149+
hysteresis: None,
97150
};
98151
let result = sensor.relative_humidity();
99152
assert!(result.is_ok());
@@ -104,11 +157,93 @@ mod tests {
104157
fn test_humidity_sensor_trait_mut_ref() {
105158
let mut sensor = MockHumiditySensor {
106159
value: TEST_HUMIDITY,
160+
threshold_low: None,
161+
threshold_high: None,
162+
hysteresis: None,
107163
};
108164
let mut_ref = &mut sensor;
109165
let result = mut_ref.relative_humidity();
110166
assert!(result.is_ok());
111167
let value = result.unwrap();
112168
assert_approx_eq!(value, TEST_HUMIDITY);
113169
}
170+
171+
#[test]
172+
fn test_humidity_threshold_set_low() {
173+
let mut sensor = MockHumiditySensor {
174+
value: TEST_HUMIDITY,
175+
threshold_low: None,
176+
threshold_high: None,
177+
hysteresis: None,
178+
};
179+
let threshold = 50.0;
180+
let result = sensor.set_relative_humidity_threshold_low(threshold);
181+
assert!(result.is_ok());
182+
assert_approx_eq!(sensor.threshold_low.unwrap(), threshold);
183+
}
184+
185+
#[test]
186+
fn test_humidity_threshold_set_high() {
187+
let mut sensor = MockHumiditySensor {
188+
value: TEST_HUMIDITY,
189+
threshold_low: None,
190+
threshold_high: None,
191+
hysteresis: None,
192+
};
193+
let threshold = 80.0;
194+
let result = sensor.set_relative_humidity_threshold_high(threshold);
195+
assert!(result.is_ok());
196+
assert_approx_eq!(sensor.threshold_high.unwrap(), threshold);
197+
}
198+
199+
#[test]
200+
fn test_humidity_threshold_set_mut_ref() {
201+
let mut sensor = MockHumiditySensor {
202+
value: TEST_HUMIDITY,
203+
threshold_low: None,
204+
threshold_high: None,
205+
hysteresis: None,
206+
};
207+
let mut_ref = &mut sensor;
208+
let low_threshold = 40.0;
209+
let high_threshold = 90.0;
210+
211+
let result_low = mut_ref.set_relative_humidity_threshold_low(low_threshold);
212+
assert!(result_low.is_ok());
213+
214+
let result_high = mut_ref.set_relative_humidity_threshold_high(high_threshold);
215+
assert!(result_high.is_ok());
216+
217+
assert_approx_eq!(sensor.threshold_low.unwrap(), low_threshold);
218+
assert_approx_eq!(sensor.threshold_high.unwrap(), high_threshold);
219+
}
220+
221+
#[test]
222+
fn test_humidity_hysteresis() {
223+
let mut sensor = MockHumiditySensor {
224+
value: TEST_HUMIDITY,
225+
threshold_low: None,
226+
threshold_high: None,
227+
hysteresis: None,
228+
};
229+
let hyst = 5.0;
230+
let result = sensor.set_relative_humidity_threshold_hysteresis(hyst);
231+
assert!(result.is_ok());
232+
assert_approx_eq!(sensor.hysteresis.unwrap(), hyst);
233+
}
234+
235+
#[test]
236+
fn test_humidity_hysteresis_mut_ref() {
237+
let mut sensor = MockHumiditySensor {
238+
value: TEST_HUMIDITY,
239+
threshold_low: None,
240+
threshold_high: None,
241+
hysteresis: None,
242+
};
243+
let mut_ref = &mut sensor;
244+
let hyst = 3.0;
245+
let result = mut_ref.set_relative_humidity_threshold_hysteresis(hyst);
246+
assert!(result.is_ok());
247+
assert_approx_eq!(sensor.hysteresis.unwrap(), hyst);
248+
}
114249
}

0 commit comments

Comments
 (0)