pub struct PowerPlan { /* private fields */ }Expand description
Maps a battery state of charge onto a PowerMode and a work interval.
As the battery drains, a node should do less: sample and transmit less often so
it survives the night or a cloudy week. A PowerPlan encodes that policy as
three intervals and two thresholds. Feed it a state of charge in [0.0, 1.0]
and it returns the mode to run in and how long to wait before the next cycle.
When the panel is charging it eases off by one mode, since incoming energy buys
back some headroom.
A charge read from a fuel gauge wanders by a percent or two from one reading to the
next, so a node whose charge sits at a threshold would change mode on every cycle.
next_mode takes the mode the node is in and applies
hysteresis: the node drops to a lower mode as soon as the charge falls below its
threshold, and climbs back only once the charge reaches the threshold plus a margin,
DEFAULT_HYSTERESIS unless with_hysteresis sets
another.
§Examples
use core::time::Duration;
use pamoja_power::{PowerMode, PowerPlan};
let plan = PowerPlan::new(
Duration::from_secs(60),
Duration::from_secs(600),
Duration::from_secs(3600),
);
// Low battery means the saver cadence...
assert_eq!(plan.mode(0.3), PowerMode::Saver);
// ...unless the panel is charging, which buys back the active cadence.
assert_eq!(plan.mode_while_charging(0.3, true), PowerMode::Active);
// A charge wandering around the 50% threshold settles in saver mode...
let mut mode = PowerMode::Active;
for soc in [0.49, 0.51, 0.50, 0.53, 0.48] {
mode = plan.next_mode(mode, soc);
assert_eq!(mode, PowerMode::Saver);
}
// ...until it reaches 55%.
assert_eq!(plan.next_mode(mode, 0.55), PowerMode::Active);Implementations§
Source§impl PowerPlan
impl PowerPlan
Sourcepub fn new(active: Duration, saver: Duration, critical: Duration) -> Self
pub fn new(active: Duration, saver: Duration, critical: Duration) -> Self
Creates a plan from its three work intervals, with default thresholds.
The defaults enter PowerMode::Saver below 50% charge and
PowerMode::Critical below 20%, and leave each lower mode once the charge is
DEFAULT_HYSTERESIS above the threshold that brought it on.
§Arguments
active- the interval at a healthy charge.saver- the longer interval used to conserve, normally larger thanactive.critical- the longest interval, used when charge is critically low.
§Returns
The power plan.
Sourcepub fn thresholds(self, saver_below: f32, critical_below: f32) -> Self
pub fn thresholds(self, saver_below: f32, critical_below: f32) -> Self
Sets the state-of-charge thresholds for entering each lower mode.
§Arguments
saver_below- enterPowerMode::Saverwhen charge is below this.critical_below- enterPowerMode::Criticalwhen charge is below this, normally lower thansaver_below.
§Returns
The updated plan, for chaining.
Sourcepub fn with_hysteresis(self, margin: f32) -> Self
pub fn with_hysteresis(self, margin: f32) -> Self
Sets how far above a threshold the charge must climb before the plan leaves the lower mode.
§Arguments
margin- the state of charge added to each threshold on the way back up.0.0turns hysteresis off, sonext_modeagrees withmodeat every charge. A margin that is negative or not a number is taken as0.0.
§Returns
The updated plan, for chaining.
Sourcepub fn hysteresis(&self) -> f32
pub fn hysteresis(&self) -> f32
Returns how far above a threshold the charge must climb to leave the lower mode.
§Returns
The margin as a state of charge.
Sourcepub fn saver_below(&self) -> f32
pub fn saver_below(&self) -> f32
Returns the charge below which the plan enters PowerMode::Saver.
§Returns
The saver threshold as a state of charge in [0.0, 1.0].
Sourcepub fn critical_below(&self) -> f32
pub fn critical_below(&self) -> f32
Returns the charge below which the plan enters PowerMode::Critical.
§Returns
The critical threshold as a state of charge in [0.0, 1.0].
Sourcepub fn mode(&self, soc: f32) -> PowerMode
pub fn mode(&self, soc: f32) -> PowerMode
Returns the mode for the given state of charge.
A charge that is not a number, such as a fuel gauge that failed to answer, is taken as critical: a node that cannot tell how much it has left does the least until it can.
§Arguments
soc- the battery state of charge in[0.0, 1.0].
§Returns
The PowerMode the node should run in.
Sourcepub fn next_mode(&self, current: PowerMode, soc: f32) -> PowerMode
pub fn next_mode(&self, current: PowerMode, soc: f32) -> PowerMode
Returns the mode a node in current moves to at a new state of charge.
The node drops to a lower mode as soon as the charge falls below that mode’s
threshold, as mode does. It climbs to a higher mode only once
the charge reaches the threshold plus the plan’s
hysteresis, so a charge wandering around a threshold
keeps the node where it is. A charge that is not a number is taken as critical.
§Arguments
current- the mode the node is running in.soc- the battery state of charge in[0.0, 1.0].
§Returns
The PowerMode the node should run in next.
Sourcepub fn next_mode_while_charging(
&self,
current: PowerMode,
soc: f32,
charging: bool,
) -> PowerMode
pub fn next_mode_while_charging( &self, current: PowerMode, soc: f32, charging: bool, ) -> PowerMode
Returns the mode a node in current moves to, easing off by one step when
charging.
The hysteresis of next_mode applies to the mode the
node runs in, so current is the mode this returned last time. Easing up because
the panel started charging counts as a climb, so it too waits until the charge is
the margin clear of the threshold below it.
§Arguments
current- the mode the node is running in.soc- the battery state of charge in[0.0, 1.0].charging- whether the panel is currently delivering charge.
§Returns
The PowerMode the node should run in next.
Sourcepub fn mode_while_charging(&self, soc: f32, charging: bool) -> PowerMode
pub fn mode_while_charging(&self, soc: f32, charging: bool) -> PowerMode
Returns the mode for the given charge, easing off by one step when charging.
§Arguments
soc- the battery state of charge in[0.0, 1.0].charging- whether the panel is currently delivering charge.
§Returns
The PowerMode, promoted one step toward PowerMode::Active while
charging is true.