Skip to main content

PowerPlan

Struct PowerPlan 

Source
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

Source

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 than active.
  • critical - the longest interval, used when charge is critically low.
§Returns

The power plan.

Source

pub fn thresholds(self, saver_below: f32, critical_below: f32) -> Self

Sets the state-of-charge thresholds for entering each lower mode.

§Arguments
§Returns

The updated plan, for chaining.

Source

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.0 turns hysteresis off, so next_mode agrees with mode at every charge. A margin that is negative or not a number is taken as 0.0.
§Returns

The updated plan, for chaining.

Source

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.

Source

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].

Source

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].

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn interval_for(&self, mode: PowerMode) -> Duration

Returns the work interval for a given mode.

§Arguments
  • mode - the mode to look up.
§Returns

The interval to wait before the next work cycle in that mode.

Source

pub fn interval(&self, soc: f32) -> Duration

Returns the work interval for the given state of charge.

§Arguments
  • soc - the battery state of charge in [0.0, 1.0].
§Returns

The interval to wait before the next work cycle.

Trait Implementations§

Source§

impl Clone for PowerPlan

Source§

fn clone(&self) -> PowerPlan

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Copy for PowerPlan

Source§

impl Debug for PowerPlan

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for PowerPlan

Source§

fn eq(&self, other: &PowerPlan) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for PowerPlan

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.