From 42b38ae15f1d44220723d81b9b176aac87d4c261 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 06:15:23 -0800 Subject: [PATCH 01/12] Added `DateTime` argument to `Sensor::get_event()` --- src/device.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/device.rs b/src/device.rs index a1ae198..cc790d6 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,6 +1,6 @@ /// Provide Low-level Device Functionality -use chrono::{Duration, Utc}; +use chrono::{DateTime, Duration, Utc}; use std::fmt::Formatter; use crate::io; @@ -46,9 +46,9 @@ pub trait Device { pub trait Sensor: Device { fn read(&self) -> T; - fn get_event(&self) -> io::IOEvent where Self: Sized { + fn get_event(&self, dt: DateTime) -> io::IOEvent { io::IOEvent::create(self, - Utc::now(), + dt, self.read()) } } From e58c70019250c32546ae8285cb955f64f1090c41 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 06:17:15 -0800 Subject: [PATCH 02/12] Created rudimentary polling class --- src/device.rs | 2 +- src/io.rs | 2 +- src/lib.rs | 3 ++- src/main.rs | 1 + src/polling.rs | 35 +++++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/polling.rs diff --git a/src/device.rs b/src/device.rs index cc790d6..aa9f17c 100644 --- a/src/device.rs +++ b/src/device.rs @@ -97,7 +97,7 @@ pub struct DeviceMetadata { max_value: T, resolution: T, - min_delay: Duration, + pub min_delay: Duration, } impl DeviceMetadata { diff --git a/src/io.rs b/src/io.rs index d1213a2..99f4c9b 100644 --- a/src/io.rs +++ b/src/io.rs @@ -81,7 +81,7 @@ impl IOEvent { /// ``` /// /// ``` - pub fn create( device: &impl device::Device, timestamp: DateTime, value: T ) -> Self { + pub fn create( device: &(impl device::Device + ?Sized), timestamp: DateTime, value: T ) -> Self { let info = device.get_metadata(); let version_id = info.version_id; let sensor_id = info.sensor_id; diff --git a/src/lib.rs b/src/lib.rs index 15c1ab1..8147ef4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,4 +5,5 @@ pub mod units; pub mod io; pub mod device; pub mod settings; -pub mod container; \ No newline at end of file +pub mod container; +pub mod polling; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 69a9da4..be8ad40 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod io; mod settings; mod sensors; mod units; +mod polling; use chrono::Duration; diff --git a/src/polling.rs b/src/polling.rs new file mode 100644 index 0000000..8375763 --- /dev/null +++ b/src/polling.rs @@ -0,0 +1,35 @@ +use std::hash::Hash; +use chrono::{Duration, DateTime, Utc}; + +use crate::container::{Collection, Container}; +use crate::device::Sensor; +use crate::io::IOEvent; + + +/// Mediator that polls a `Container` of `Sensors` and populates another container with `IOEvent` objects. +/// TODO: multithreaded polling +pub struct Poller { + interval: Duration, + last_execution: DateTime, + sensors: &'static Container>, K>, + log: &'static mut Container, DateTime> +} + +impl Poller { + + /// Iterate through container once. Call `get_event()` on each value. + /// Update according to the lowest rate. + fn poll(&mut self) { + for sensor in self.sensors._inner().values() { + let timer: Duration = sensor.get_metadata().min_delay; + let next_execution = self.last_execution + timer; + + if next_execution <= Utc::now() { + self.last_execution = next_execution; + let event = sensor.get_event(next_execution); + self.log.add(next_execution, event); + } + + } + } +} \ No newline at end of file From e955dfe85460df7bf20c0ec72240989fbe4a08d8 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 06:20:01 -0800 Subject: [PATCH 03/12] Ran `rustfmt` --- src/container.rs | 12 +++++------ src/device.rs | 52 +++++++++++++++++++++++++++++++---------------- src/io.rs | 20 ++++++++++-------- src/lib.rs | 10 ++++----- src/main.rs | 19 +++++------------ src/polling.rs | 9 +++----- src/sensors/ph.rs | 15 ++++++-------- src/settings.rs | 2 +- src/units.rs | 2 +- 9 files changed, 73 insertions(+), 68 deletions(-) diff --git a/src/container.rs b/src/container.rs index 201d00d..25eb5f4 100644 --- a/src/container.rs +++ b/src/container.rs @@ -18,11 +18,9 @@ /// store a collection of objects of a specific type `T`, and identified by a specific key type `K`. The relationship /// between `Containerized` and `Container` is that `Containerized` defines how the `Container` should be created /// and used for a specific type, while `Container` actually holds the collection of objects. - use std::collections::HashMap; use std::hash::Hash; - /// A trait for creating a specialized `Container` instance /// /// # Notes @@ -73,7 +71,8 @@ use std::hash::Hash; /// ``` pub trait Containerized - where K: Eq + Hash +where + K: Eq + Hash, { // TODO: add type /// Returns a new instance of the `Container` struct for storing objects of type T @@ -81,7 +80,6 @@ pub trait Containerized fn container() -> Container; } - /// Define a basic interface to interact with underlying data. /// T is the data type being stored and K is the key type to access stored data. pub trait Collection { @@ -109,10 +107,11 @@ pub trait Collection { /// The key only needs to be hashable. #[derive(Debug)] pub struct Container - where K: Eq + Hash +where + K: Eq + Hash, { // The inner field is a HashMap with key type K and value type T - inner: HashMap + inner: HashMap, } impl Container { @@ -130,7 +129,6 @@ impl Container { /// Implement the `Collection` interface for `Container` impl Collection for Container { - /// Add a key-value pair to the collection and return a boolean indicating if the value has been added to the collection. /// Using `entry` method on the inner HashMap to check if the key already exists in the HashMap /// - If the key already exists, the returned value is `std::collections::hash_map::Entry::Occupied`, which returns false. diff --git a/src/device.rs b/src/device.rs index aa9f17c..e303128 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,11 +1,9 @@ /// Provide Low-level Device Functionality - use chrono::{DateTime, Duration, Utc}; use std::fmt::Formatter; -use crate::io; use crate::container::{Container, Containerized}; - +use crate::io; /// Basic interface for GPIO device metadata pub trait Device { @@ -14,7 +12,6 @@ pub trait Device { fn id(&self) -> i32; } - /// Interface for an input device /// It is used as a trait object and can be stored in a container using the `Containerized` trait. /// @@ -47,19 +44,22 @@ pub trait Sensor: Device { fn read(&self) -> T; fn get_event(&self, dt: DateTime) -> io::IOEvent { - io::IOEvent::create(self, - dt, - self.read()) + io::IOEvent::create(self, dt, self.read()) } } impl std::fmt::Debug for dyn Sensor { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Sensor {{ name: {}, id: {}, info: {}", self.name(), self.id(), self.get_metadata()) + write!( + f, + "Sensor {{ name: {}, id: {}, info: {}", + self.name(), + self.id(), + self.get_metadata() + ) } } - /// Defines an interface for an input device that needs to be calibrated pub trait Calibrated { /// Initiate the calibration procedures for a specific device instance. @@ -117,11 +117,24 @@ impl DeviceMetadata { /// # Returns /// /// A new instance with given specified parameters - pub fn new(name: String, version_id: i32, sensor_id: i32, kind: io::IOKind, - min_value: T, max_value: T, resolution: T, min_delay: Duration) -> Self { + pub fn new( + name: String, + version_id: i32, + sensor_id: i32, + kind: io::IOKind, + min_value: T, + max_value: T, + resolution: T, + min_delay: Duration, + ) -> Self { DeviceMetadata { - name, version_id, sensor_id, kind, - min_value, max_value, resolution, + name, + version_id, + sensor_id, + kind, + min_value, + max_value, + resolution, min_delay, } } @@ -129,16 +142,21 @@ impl DeviceMetadata { impl std::fmt::Display for DeviceMetadata { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "Device Info {{ Kind: {}, Min. Delay: {} }}", self.kind, self.min_delay.to_string()) + write!( + f, + "Device Info {{ Kind: {}, Min. Delay: {} }}", + self.kind, + self.min_delay.to_string() + ) } } - /// Returns a new instance of `Container` for storing objects which implement the `Sensor` trait which are accessed `` /// Objects are stored as `Box>` impl Containerized>, K> for dyn Sensor - where T: std::fmt::Debug, - K: std::hash::Hash + Eq +where + T: std::fmt::Debug, + K: std::hash::Hash + Eq, { fn container() -> Container>, K> { Container::>, K>::new() diff --git a/src/io.rs b/src/io.rs index 99f4c9b..843835a 100644 --- a/src/io.rs +++ b/src/io.rs @@ -1,9 +1,9 @@ /// Encapsulate IO for devices +use chrono::{DateTime, Utc}; use std::fmt::Formatter; -use chrono::{Utc, DateTime}; -use crate::device; use crate::container::{Container, Containerized}; +use crate::device; /// Defines sensor type. Used to classify data along with `IOData`. #[derive(Debug, Clone, Copy, PartialEq)] @@ -53,7 +53,7 @@ impl std::fmt::Display for IOKind { /// Encapsulates sensor data. Provides a unified data type for returning data. pub struct IOData { pub kind: IOKind, - pub data: T + pub data: T, } /// Encapsulates `IOData` alongside of timestamp and device data @@ -81,27 +81,31 @@ impl IOEvent { /// ``` /// /// ``` - pub fn create( device: &(impl device::Device + ?Sized), timestamp: DateTime, value: T ) -> Self { + pub fn create( + device: &(impl device::Device + ?Sized), + timestamp: DateTime, + value: T, + ) -> Self { let info = device.get_metadata(); let version_id = info.version_id; let sensor_id = info.sensor_id; let data = IOData { kind: info.kind.clone(), - data: value + data: value, }; IOEvent { version_id, sensor_id, timestamp, - data + data, } } } - /// Return a new instance of `Container` with for storing `IOEvent` which are accessed by `DateTime` as keys impl Containerized, DateTime> for IOEvent - where T: std::fmt::Debug +where + T: std::fmt::Debug, { fn container() -> Container, DateTime> { Container::, DateTime>::new() diff --git a/src/lib.rs b/src/lib.rs index 8147ef4..0d08f52 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ extern crate chrono; -pub mod sensors; -pub mod units; -pub mod io; +pub mod container; pub mod device; +pub mod io; +pub mod polling; +pub mod sensors; pub mod settings; -pub mod container; -pub mod polling; \ No newline at end of file +pub mod units; diff --git a/src/main.rs b/src/main.rs index be8ad40..3acb89a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,10 +3,10 @@ extern crate chrono; mod container; mod device; mod io; -mod settings; +mod polling; mod sensors; +mod settings; mod units; -mod polling; use chrono::Duration; @@ -16,21 +16,12 @@ use crate::sensors::ph::MockPhSensor; use crate::settings::Settings; use crate::units::Ph; - fn main() { let _settings = Settings::initialize(); - let s0 = MockPhSensor::new( - "test name".to_string(), - 0, - Duration::seconds(5), - ); - let s1 = MockPhSensor::new( - "second sensor".to_string(), - 1, - Duration::seconds(10), - ); - let mut container: Container>, i32> = >::container(); + let s0 = MockPhSensor::new("test name".to_string(), 0, Duration::seconds(5)); + let s1 = MockPhSensor::new("second sensor".to_string(), 1, Duration::seconds(10)); + let mut container: Container>, i32> = >::container(); container.add(0, Box::new(s0)); container.add(1, Box::new(s1)); dbg!(container._inner()); diff --git a/src/polling.rs b/src/polling.rs index 8375763..12b66a5 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -1,22 +1,20 @@ +use chrono::{DateTime, Duration, Utc}; use std::hash::Hash; -use chrono::{Duration, DateTime, Utc}; use crate::container::{Collection, Container}; use crate::device::Sensor; use crate::io::IOEvent; - /// Mediator that polls a `Container` of `Sensors` and populates another container with `IOEvent` objects. /// TODO: multithreaded polling pub struct Poller { interval: Duration, last_execution: DateTime, sensors: &'static Container>, K>, - log: &'static mut Container, DateTime> + log: &'static mut Container, DateTime>, } impl Poller { - /// Iterate through container once. Call `get_event()` on each value. /// Update according to the lowest rate. fn poll(&mut self) { @@ -29,7 +27,6 @@ impl Poller { let event = sensor.get_event(next_execution); self.log.add(next_execution, event); } - } } -} \ No newline at end of file +} diff --git a/src/sensors/ph.rs b/src/sensors/ph.rs index b4f4570..5341210 100644 --- a/src/sensors/ph.rs +++ b/src/sensors/ph.rs @@ -4,7 +4,7 @@ use crate::{device, io, units::Ph}; #[derive(Debug, Clone)] pub struct MockPhSensor { - metadata: device::DeviceMetadata + metadata: device::DeviceMetadata, } /** Represents a mock pH sensor. @@ -26,17 +26,14 @@ impl MockPhSensor { let max_value = Ph(14.0); let resolution = Ph(0.1); - let metadata: device::DeviceMetadata = device::DeviceMetadata::new(name, version_id, sensor_id, - kind, min_value, max_value, resolution, - min_delay); + let metadata: device::DeviceMetadata = device::DeviceMetadata::new( + name, version_id, sensor_id, kind, min_value, max_value, resolution, min_delay, + ); - MockPhSensor { - metadata - } + MockPhSensor { metadata } } } - // Implement traits impl device::Device for MockPhSensor { fn get_metadata(&self) -> &device::DeviceMetadata { @@ -55,4 +52,4 @@ impl device::Sensor for MockPhSensor { fn read(&self) -> Ph { Ph::new(1.2).unwrap() } -} \ No newline at end of file +} diff --git a/src/settings.rs b/src/settings.rs index ce478f9..5baa5c3 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -3,7 +3,7 @@ use dotenv::dotenv; const VERSION: &str = "0.0.1-alpha"; pub struct Settings { - pub version: String + pub version: String, } impl Settings { diff --git a/src/units.rs b/src/units.rs index 12eccaa..df68a54 100644 --- a/src/units.rs +++ b/src/units.rs @@ -38,6 +38,6 @@ impl From for Ph { impl From for f64 { fn from(value: Ph) -> Self { - value.0 + value.0 } } From 278353d4b229240c123da1e7ceee7381a7b2594a Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 12:00:18 -0800 Subject: [PATCH 04/12] Implemented `Poller.interval` --- src/polling.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/polling.rs b/src/polling.rs index 12b66a5..db8e4d0 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -10,6 +10,8 @@ use crate::io::IOEvent; pub struct Poller { interval: Duration, last_execution: DateTime, + + // internal containers sensors: &'static Container>, K>, log: &'static mut Container, DateTime>, } @@ -18,11 +20,10 @@ impl Poller { /// Iterate through container once. Call `get_event()` on each value. /// Update according to the lowest rate. fn poll(&mut self) { - for sensor in self.sensors._inner().values() { - let timer: Duration = sensor.get_metadata().min_delay; - let next_execution = self.last_execution + timer; + let next_execution = self.last_execution + self.interval; - if next_execution <= Utc::now() { + if next_execution <= Utc::now() { + for sensor in self.sensors._inner().values() { self.last_execution = next_execution; let event = sensor.get_event(next_execution); self.log.add(next_execution, event); From d2617cc9fa83f029ab60da867fe43a297c19b141 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 16:49:51 -0800 Subject: [PATCH 05/12] Update `Settings` to include interval --- src/settings.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/settings.rs b/src/settings.rs index 5baa5c3..30f06f6 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,9 +1,14 @@ +use chrono::Duration; use dotenv::dotenv; +/// Default values const VERSION: &str = "0.0.1-alpha"; +const INTERVAL: i32 = 10; +/// Struct containing settings loaded from ".env" pub struct Settings { pub version: String, + pub interval: Duration, } impl Settings { @@ -11,6 +16,7 @@ impl Settings { pub fn initialize() -> Self { dotenv().ok(); let version = std::env::var("VERSION").unwrap_or_else(|_| VERSION.to_string()); - Settings { version } + let interval = Duration::seconds(i64::from(std::env::var("INTERVAL").unwrap_or(INTERVAL.to_string()))); + Settings { version, interval } } } From a907757becbb2b613e41673eca00e14b1a17e523 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 16:50:55 -0800 Subject: [PATCH 06/12] Implemented `Poller.interval` --- src/main.rs | 20 +++++++++++++++++--- src/polling.rs | 12 +++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 3acb89a..80428c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,21 +8,35 @@ mod sensors; mod settings; mod units; -use chrono::Duration; +use chrono::{DateTime, Duration, Utc}; use crate::container::{Collection, Container, Containerized}; use crate::device::Sensor; +use crate::polling::Poller; use crate::sensors::ph::MockPhSensor; use crate::settings::Settings; use crate::units::Ph; fn main() { - let _settings = Settings::initialize(); + static SETTINGS: Settings = Settings::initialize(); + unsafe { + static mut SENSORS: Container>, i32> = >::container(); + static mut LOG: Container, DateTime> = >::container(); + static mut POLLER: Poller = Poller::new( + &settings.interval, + Utc::now() - settings.interval, + &mut SENSORS, + &mut LOG + ); + } + let s0 = MockPhSensor::new("test name".to_string(), 0, Duration::seconds(5)); let s1 = MockPhSensor::new("second sensor".to_string(), 1, Duration::seconds(10)); - let mut container: Container>, i32> = >::container(); + container.add(0, Box::new(s0)); container.add(1, Box::new(s1)); + dbg!(container._inner()); + } diff --git a/src/polling.rs b/src/polling.rs index db8e4d0..e1b1533 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -8,18 +8,18 @@ use crate::io::IOEvent; /// Mediator that polls a `Container` of `Sensors` and populates another container with `IOEvent` objects. /// TODO: multithreaded polling pub struct Poller { - interval: Duration, + interval: &'static Duration, last_execution: DateTime, // internal containers - sensors: &'static Container>, K>, + sensors: &'static mut Container>, K>, log: &'static mut Container, DateTime>, } impl Poller { /// Iterate through container once. Call `get_event()` on each value. /// Update according to the lowest rate. - fn poll(&mut self) { + pub fn poll(&mut self) { let next_execution = self.last_execution + self.interval; if next_execution <= Utc::now() { @@ -30,4 +30,10 @@ impl Poller { } } } + + pub fn new( interval: &'static Duration, last_execution: DateTime, + sensors: &'static mut Container>, K>, + log: &'static mut Container, DateTime> ) -> Self { + Self { interval, last_execution, sensors, log } + } } From d7292081c4f162c64f2fce10c13749fd27a56888 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 18:35:08 -0800 Subject: [PATCH 07/12] Moved ownership of containers to `Poller` --- src/main.rs | 20 +++++--------------- src/polling.rs | 18 +++++++++--------- src/settings.rs | 9 ++++++--- 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/main.rs b/src/main.rs index 80428c3..db63b42 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,25 +18,15 @@ use crate::settings::Settings; use crate::units::Ph; fn main() { - static SETTINGS: Settings = Settings::initialize(); - unsafe { - static mut SENSORS: Container>, i32> = >::container(); - static mut LOG: Container, DateTime> = >::container(); - static mut POLLER: Poller = Poller::new( - &settings.interval, - Utc::now() - settings.interval, - &mut SENSORS, - &mut LOG - ); - } - + let settings: Settings = Settings::initialize(); + let mut poller: Poller = Poller::new(settings.interval, Utc::now() - settings.interval); let s0 = MockPhSensor::new("test name".to_string(), 0, Duration::seconds(5)); let s1 = MockPhSensor::new("second sensor".to_string(), 1, Duration::seconds(10)); - container.add(0, Box::new(s0)); - container.add(1, Box::new(s1)); + poller.sensors.add(0, Box::new(s0)); + poller.sensors.add(1, Box::new(s1)); - dbg!(container._inner()); + dbg!(poller.sensors._inner()); } diff --git a/src/polling.rs b/src/polling.rs index e1b1533..75251f3 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -1,22 +1,22 @@ use chrono::{DateTime, Duration, Utc}; use std::hash::Hash; -use crate::container::{Collection, Container}; +use crate::container::{Collection, Container, Containerized}; use crate::device::Sensor; use crate::io::IOEvent; /// Mediator that polls a `Container` of `Sensors` and populates another container with `IOEvent` objects. /// TODO: multithreaded polling -pub struct Poller { - interval: &'static Duration, +pub struct Poller { + interval: Duration, last_execution: DateTime, // internal containers - sensors: &'static mut Container>, K>, - log: &'static mut Container, DateTime>, + pub sensors: Container>, K>, + pub log: Container, DateTime>, } -impl Poller { +impl Poller { /// Iterate through container once. Call `get_event()` on each value. /// Update according to the lowest rate. pub fn poll(&mut self) { @@ -31,9 +31,9 @@ impl Poller { } } - pub fn new( interval: &'static Duration, last_execution: DateTime, - sensors: &'static mut Container>, K>, - log: &'static mut Container, DateTime> ) -> Self { + pub fn new( interval: Duration, last_execution: DateTime ) -> Self { + let sensors: Container>, K> = >::container(); + let log: Container, DateTime> = >::container(); Self { interval, last_execution, sensors, log } } } diff --git a/src/settings.rs b/src/settings.rs index 30f06f6..38cdc8a 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,9 +1,10 @@ use chrono::Duration; use dotenv::dotenv; +use std::env::var; /// Default values const VERSION: &str = "0.0.1-alpha"; -const INTERVAL: i32 = 10; +const INTERVAL: i64 = 10; /// Struct containing settings loaded from ".env" pub struct Settings { @@ -15,8 +16,10 @@ impl Settings { /// Read settings from .env file pub fn initialize() -> Self { dotenv().ok(); - let version = std::env::var("VERSION").unwrap_or_else(|_| VERSION.to_string()); - let interval = Duration::seconds(i64::from(std::env::var("INTERVAL").unwrap_or(INTERVAL.to_string()))); + let version = var("VERSION").unwrap_or_else(|_| VERSION.to_string()); + let interval = Duration::seconds( + var("INTERVAL").unwrap_or(INTERVAL.to_string()).parse::().unwrap()); + Settings { version, interval } } } From 43660a0e3f9925c5419c34d2b5853c6e6a725f0a Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 19:27:44 -0800 Subject: [PATCH 08/12] `Container::_inner()` should return `Iter` --- src/container.rs | 5 +++-- src/polling.rs | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/container.rs b/src/container.rs index 25eb5f4..a442951 100644 --- a/src/container.rs +++ b/src/container.rs @@ -1,3 +1,4 @@ +use std::collections::hash_map::Iter; /// Data structures and interfaces to store data /// /// The main workhorses that provide functionality are `Containerized` and `Container`. The `Containerized` @@ -122,8 +123,8 @@ impl Container { } /// Return a readonly reference to stored HashMap - pub fn _inner(&self) -> &HashMap { - &self.inner + pub fn _inner(&self) -> Iter<'_, K, T> { + self.inner.iter() } } diff --git a/src/polling.rs b/src/polling.rs index 75251f3..1f2a8f1 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -23,10 +23,11 @@ impl Poller { let next_execution = self.last_execution + self.interval; if next_execution <= Utc::now() { - for sensor in self.sensors._inner().values() { + for (_, sensor) in self.sensors._inner() { self.last_execution = next_execution; let event = sensor.get_event(next_execution); self.log.add(next_execution, event); + dbg!(sensor); } } } From ad0e9af7e265e2542007f9b7d27742d5b38058c6 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 21:40:10 -0800 Subject: [PATCH 09/12] Rename `Container::_inner()` to `::iter()` --- src/container.rs | 2 +- src/main.rs | 2 +- src/polling.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/container.rs b/src/container.rs index a442951..91b9717 100644 --- a/src/container.rs +++ b/src/container.rs @@ -123,7 +123,7 @@ impl Container { } /// Return a readonly reference to stored HashMap - pub fn _inner(&self) -> Iter<'_, K, T> { + pub fn iter(&self) -> Iter<'_, K, T> { self.inner.iter() } } diff --git a/src/main.rs b/src/main.rs index db63b42..9d34ef1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,6 @@ fn main() { poller.sensors.add(0, Box::new(s0)); poller.sensors.add(1, Box::new(s1)); - dbg!(poller.sensors._inner()); + dbg!(poller.sensors.iter()); } diff --git a/src/polling.rs b/src/polling.rs index 1f2a8f1..01a9708 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -23,7 +23,7 @@ impl Poller { let next_execution = self.last_execution + self.interval; if next_execution <= Utc::now() { - for (_, sensor) in self.sensors._inner() { + for (_, sensor) in self.sensors.iter() { self.last_execution = next_execution; let event = sensor.get_event(next_execution); self.log.add(next_execution, event); From 11dba3a19ed1b100eec7f7f7c06e85cdd9b63f30 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Fri, 27 Jan 2023 21:40:59 -0800 Subject: [PATCH 10/12] Add documentation to "polling.rs" --- src/polling.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/polling.rs b/src/polling.rs index 01a9708..0eb79bd 100644 --- a/src/polling.rs +++ b/src/polling.rs @@ -5,8 +5,15 @@ use crate::container::{Collection, Container, Containerized}; use crate::device::Sensor; use crate::io::IOEvent; -/// Mediator that polls a `Container` of `Sensors` and populates another container with `IOEvent` objects. -/// TODO: multithreaded polling +/// Mediator to periodically poll sensors of various types, and store the resulting `IOEvent` objects in a `Container`. +/// +/// `poll()` is the primary callable and iterates through the `Sensor` container to call `get_event()` on each sensor. +/// Resulting `IOEvent` objects are then added to the `log` container. +/// +/// The `interval` field indicates the duration between each poll and the `last_execution` field indicates the last time the poll method was executed +/// +/// TODO: multithreaded polling. Implement `RwLock` or `Mutex` to synchronize access to the sensors and +/// log containers in order to make the poll() function thread-safe. pub struct Poller { interval: Duration, last_execution: DateTime, @@ -32,6 +39,8 @@ impl Poller { } } + /// Constructor for `Poller` struct. + /// Internal containers are instantiated as empty. pub fn new( interval: Duration, last_execution: DateTime ) -> Self { let sensors: Container>, K> = >::container(); let log: Container, DateTime> = >::container(); From 71761f6ae09743f403c16534892a8d656985f24a Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Sat, 28 Jan 2023 03:01:58 -0800 Subject: [PATCH 11/12] Add section headers to "main.py" --- src/main.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main.rs b/src/main.rs index 9d34ef1..7680379 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,10 @@ use crate::settings::Settings; use crate::units::Ph; fn main() { + /// # Load Settings let settings: Settings = Settings::initialize(); + + /// # Setup Poller let mut poller: Poller = Poller::new(settings.interval, Utc::now() - settings.interval); let s0 = MockPhSensor::new("test name".to_string(), 0, Duration::seconds(5)); From a21429dbebbe3d8f52f909022d3aa2f779bef0b6 Mon Sep 17 00:00:00 2001 From: Josue Figueroa Date: Sat, 28 Jan 2023 03:15:27 -0800 Subject: [PATCH 12/12] Implemented polling --- src/io.rs | 2 ++ src/main.rs | 6 +++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/io.rs b/src/io.rs index 843835a..cef7ef0 100644 --- a/src/io.rs +++ b/src/io.rs @@ -51,12 +51,14 @@ impl std::fmt::Display for IOKind { // TODO: enum for `IODirection` when implementing control system /// Encapsulates sensor data. Provides a unified data type for returning data. +#[derive(Debug)] pub struct IOData { pub kind: IOKind, pub data: T, } /// Encapsulates `IOData` alongside of timestamp and device data +#[derive(Debug)] pub struct IOEvent { pub version_id: i32, pub sensor_id: i32, diff --git a/src/main.rs b/src/main.rs index 7680379..441e8e0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,10 @@ fn main() { poller.sensors.add(0, Box::new(s0)); poller.sensors.add(1, Box::new(s1)); - dbg!(poller.sensors.iter()); + loop { + poller.poll(); + std::thread::sleep(std::time::Duration::from_secs(1)); + dbg!(&poller.log) + } }