Can set forced state to relays
This commit is contained in:
@@ -25,19 +25,56 @@ impl DeviceState {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum RelayForcedState {
|
||||
#[default]
|
||||
None,
|
||||
Off {
|
||||
until: u64,
|
||||
},
|
||||
On {
|
||||
until: u64,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct RelayState {
|
||||
on: bool,
|
||||
since: usize,
|
||||
forced_state: RelayForcedState,
|
||||
}
|
||||
|
||||
impl RelayState {
|
||||
/// Get actual forced state (returns None if state is expired)
|
||||
pub fn actual_forced_state(&self) -> RelayForcedState {
|
||||
match self.forced_state {
|
||||
RelayForcedState::Off { until } if until > time_secs() => {
|
||||
RelayForcedState::Off { until }
|
||||
}
|
||||
RelayForcedState::On { until } if until > time_secs() => RelayForcedState::On { until },
|
||||
_ => RelayForcedState::None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_on(&self) -> bool {
|
||||
self.on
|
||||
let forced_state = self.actual_forced_state();
|
||||
(self.on || matches!(forced_state, RelayForcedState::On { .. }))
|
||||
&& !matches!(forced_state, RelayForcedState::Off { .. })
|
||||
}
|
||||
|
||||
fn is_off(&self) -> bool {
|
||||
!self.on
|
||||
!self.is_on()
|
||||
}
|
||||
|
||||
/// Check if relay state is enforced
|
||||
pub fn is_forced(&self) -> bool {
|
||||
self.actual_forced_state() != RelayForcedState::None
|
||||
}
|
||||
|
||||
pub fn set_forced(&mut self, s: RelayForcedState) {
|
||||
self.since = time_secs() as usize;
|
||||
self.forced_state = s;
|
||||
}
|
||||
|
||||
pub fn state_for(&self) -> usize {
|
||||
@@ -146,7 +183,11 @@ impl EnergyEngine {
|
||||
r.name,
|
||||
r.consumption,
|
||||
format!("{} / {}", r.minimal_downtime, r.minimal_uptime),
|
||||
status.is_on().to_string(),
|
||||
status.is_on().to_string()
|
||||
+ match status.is_forced() {
|
||||
true => " (Forced)",
|
||||
false => "",
|
||||
},
|
||||
status.since,
|
||||
match dev_online {
|
||||
true => "Online",
|
||||
@@ -192,19 +233,28 @@ impl EnergyEngine {
|
||||
|
||||
let mut new_relays_state = self.relays_state.clone();
|
||||
|
||||
// Forcefully turn off relays that belongs to offline devices
|
||||
// Forcefully turn off disabled relays
|
||||
for d in devices {
|
||||
if !self.device_state(&d.id).is_online() {
|
||||
for r in &d.relays {
|
||||
for r in &d.relays {
|
||||
if !r.enabled || !d.enabled {
|
||||
new_relays_state.get_mut(&r.id).unwrap().on = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Forcefully turn off disabled relays
|
||||
// Apply forced relays state
|
||||
for d in devices {
|
||||
for r in &d.relays {
|
||||
if !r.enabled || !d.enabled {
|
||||
if self.relay_state(r.id).is_forced() {
|
||||
new_relays_state.get_mut(&r.id).unwrap().on = self.relay_state(r.id).is_on();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Forcefully turn off relays that belongs to offline devices
|
||||
for d in devices {
|
||||
if !self.device_state(&d.id).is_online() {
|
||||
for r in &d.relays {
|
||||
new_relays_state.get_mut(&r.id).unwrap().on = false;
|
||||
}
|
||||
}
|
||||
@@ -216,7 +266,9 @@ impl EnergyEngine {
|
||||
|
||||
for d in devices {
|
||||
for r in &d.relays {
|
||||
if new_relays_state.get(&r.id).unwrap().is_off() {
|
||||
if new_relays_state.get(&r.id).unwrap().is_off()
|
||||
|| new_relays_state.get(&r.id).unwrap().is_forced()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -240,7 +292,7 @@ impl EnergyEngine {
|
||||
for d in devices {
|
||||
for r in &d.relays {
|
||||
let state = new_relays_state.get(&r.id).unwrap();
|
||||
if state.is_off() {
|
||||
if state.is_off() || state.is_forced() {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -271,7 +323,9 @@ impl EnergyEngine {
|
||||
continue;
|
||||
}
|
||||
|
||||
if new_relays_state.get(&r.id).unwrap().is_on() {
|
||||
if new_relays_state.get(&r.id).unwrap().is_on()
|
||||
|| new_relays_state.get(&r.id).unwrap().is_forced()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -298,7 +352,7 @@ impl EnergyEngine {
|
||||
}
|
||||
}
|
||||
|
||||
// Order relays
|
||||
// Order relays to select the ones with the most elevated priorities
|
||||
let mut ordered_relays = devices
|
||||
.iter()
|
||||
.filter(|d| self.device_state(&d.id).is_online() && d.enabled)
|
||||
@@ -308,10 +362,13 @@ impl EnergyEngine {
|
||||
ordered_relays.sort_by_key(|r| r.priority);
|
||||
ordered_relays.reverse();
|
||||
|
||||
// Select relays to start, starting with those with highest priorities
|
||||
loop {
|
||||
let mut changed = false;
|
||||
for relay in &ordered_relays {
|
||||
if new_relays_state.get(&relay.id).unwrap().is_on() {
|
||||
if new_relays_state.get(&relay.id).unwrap().is_on()
|
||||
|| new_relays_state.get(&relay.id).unwrap().is_forced()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user