diff --git a/central_backend/src/energy/relay_state_history.rs b/central_backend/src/energy/relay_state_history.rs index ac22b1a..0eafaf4 100644 --- a/central_backend/src/energy/relay_state_history.rs +++ b/central_backend/src/energy/relay_state_history.rs @@ -64,6 +64,11 @@ impl RelayStateHistory { Ok(((relative_time / 8) as usize, (relative_time % 8) as u8)) } + /// Check if a time is contained in this history + pub fn contains_time(&self, time: u64) -> bool { + self.resolve_offset(time).is_ok() + } + /// Set new state of relay pub fn set_state(&mut self, time: u64, on: bool) -> anyhow::Result<()> { let (idx, offset) = self.resolve_offset(time)?; @@ -93,10 +98,31 @@ impl RelayStateHistory { } } +/// Get the total runtime of a relay during a given time window +pub fn relay_total_runtime(device_id: DeviceRelayID, from: u64, to: u64) -> anyhow::Result { + let mut total = 0; + let mut file = RelayStateHistory::open(device_id, from)?; + let mut curr_time = from; + + while curr_time < to { + if !file.contains_time(curr_time) { + file = RelayStateHistory::open(device_id, curr_time)?; + } + + if file.get_state(curr_time)? { + total += TIME_INTERVAL; + } + + curr_time += TIME_INTERVAL as u64; + } + + Ok(total) +} + #[cfg(test)] mod tests { use crate::devices::device::DeviceRelayID; - use crate::energy::relay_state_history::RelayStateHistory; + use crate::energy::relay_state_history::{relay_total_runtime, RelayStateHistory}; #[test] fn test_relay_state_history() { @@ -138,4 +164,12 @@ mod tests { assert!(history.get_state(8989898).is_err()); } + + #[test] + fn test_relay_total_runtime() { + assert_eq!( + relay_total_runtime(DeviceRelayID::default(), 50, 3600 * 24 * 60 + 500).unwrap(), + 0 + ); + } }