use FakeTemperatureSensor as an actor

This commit is contained in:
Jorge Aparicio 2022-06-07 11:51:59 +02:00
parent 5a3f27599e
commit d1145a138f
3 changed files with 36 additions and 12 deletions

View file

@ -1,6 +1,6 @@
use rtic_actor_traits::Post; use rtic_actor_traits::{Post, Receive};
use crate::TemperatureReadingCelsius; use crate::{DoTemperatureRead, TemperatureReadingCelsius};
pub struct FakeTemperatureSensor<P> pub struct FakeTemperatureSensor<P>
where where
@ -23,8 +23,13 @@ where
temperature: initial_temperature, temperature: initial_temperature,
} }
} }
}
pub fn read(&mut self) { impl<P> Receive<DoTemperatureRead> for FakeTemperatureSensor<P>
where
P: Post<TemperatureReadingCelsius>,
{
fn receive(&mut self, _: DoTemperatureRead) {
self.outbox self.outbox
.post(TemperatureReadingCelsius(self.temperature)) .post(TemperatureReadingCelsius(self.temperature))
.expect("OOM"); .expect("OOM");
@ -41,7 +46,10 @@ mod tests {
#[test] #[test]
fn on_read_it_posts_reading() { fn on_read_it_posts_reading() {
let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), 0, 0); let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), 0, 0);
sensor.read();
// manually send a message
let message = DoTemperatureRead;
sensor.receive(message);
let spy = sensor.outbox; let spy = sensor.outbox;
let posted_messages = spy.posted_messages::<TemperatureReadingCelsius>(); let posted_messages = spy.posted_messages::<TemperatureReadingCelsius>();
@ -52,7 +60,10 @@ mod tests {
fn reading_starts_at_initial_temperature() { fn reading_starts_at_initial_temperature() {
let initial_temperature = 1; let initial_temperature = 1;
let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), initial_temperature, 0); let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), initial_temperature, 0);
sensor.read();
// manually send a message
let message = DoTemperatureRead;
sensor.receive(message);
let spy = sensor.outbox; let spy = sensor.outbox;
let mut posted_messages = spy.posted_messages::<TemperatureReadingCelsius>(); let mut posted_messages = spy.posted_messages::<TemperatureReadingCelsius>();
@ -67,8 +78,11 @@ mod tests {
let initial_temperature = 42; let initial_temperature = 42;
let delta = 1; let delta = 1;
let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), initial_temperature, delta); let mut sensor = FakeTemperatureSensor::new(PostSpy::default(), initial_temperature, delta);
sensor.read();
sensor.read(); // manually send a message
let message = DoTemperatureRead;
sensor.receive(message);
sensor.receive(message);
let spy = sensor.outbox; let spy = sensor.outbox;
let mut posted_messages = spy.posted_messages::<TemperatureReadingCelsius>(); let mut posted_messages = spy.posted_messages::<TemperatureReadingCelsius>();

View file

@ -8,6 +8,9 @@ pub use fake_temperature_sensor::FakeTemperatureSensor;
pub use temperature_monitor::TemperatureMonitor; pub use temperature_monitor::TemperatureMonitor;
// Messages // Messages
#[derive(Clone, Copy, Debug)]
pub struct DoTemperatureRead;
pub struct TemperatureAlert; pub struct TemperatureAlert;
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]

View file

@ -6,7 +6,8 @@ use firmware as _;
#[rtic::app(device = nrf52840_hal::pac, dispatchers = [RADIO])] #[rtic::app(device = nrf52840_hal::pac, dispatchers = [RADIO])]
mod app { mod app {
use actors::{ use actors::{
FakeTemperatureSensor, TemperatureAlert, TemperatureMonitor, TemperatureReadingCelsius, DoTemperatureRead, FakeTemperatureSensor, TemperatureAlert, TemperatureMonitor,
TemperatureReadingCelsius,
}; };
use rtic_actor_traits::Receive; use rtic_actor_traits::Receive;
use systick_monotonic::*; use systick_monotonic::*;
@ -36,6 +37,9 @@ mod app {
#[actors] #[actors]
struct Actors { struct Actors {
#[subscribe(DoTemperatureRead)]
temperature_sensor: FakeTemperatureSensor<Poster>,
#[init(AlertHandler)] #[init(AlertHandler)]
#[subscribe(TemperatureAlert)] #[subscribe(TemperatureAlert)]
alert_handler: AlertHandler, alert_handler: AlertHandler,
@ -50,7 +54,7 @@ mod app {
#[local] #[local]
struct Local { struct Local {
temperature_sensor: FakeTemperatureSensor<Poster>, poster: Poster,
} }
#[monotonic(binds = SysTick, default = true)] #[monotonic(binds = SysTick, default = true)]
@ -71,17 +75,20 @@ mod app {
( (
Shared {}, Shared {},
Local { temperature_sensor }, Local { poster },
init::Monotonics(mono), init::Monotonics(mono),
Actors { Actors {
temperature_monitor, temperature_monitor,
temperature_sensor,
}, },
) )
} }
#[task(local = [temperature_sensor])] #[task(local = [poster])]
fn periodic(cx: periodic::Context) { fn periodic(cx: periodic::Context) {
cx.local.temperature_sensor.read(); // input to the actor network
cx.local.poster.post(DoTemperatureRead).expect("OOM");
periodic::spawn_after(1.secs()).expect("OOM"); periodic::spawn_after(1.secs()).expect("OOM");
} }