Skip to main content

Node

Struct Node 

Source
pub struct Node<S, A, T, C> { /* private fields */ }
Expand description

A profile assembled around the components that make it run.

The node is the thin shell that ties a Profile’s decision logic to real I/O. Each tick reads the sensor, runs the profile’s Controller, drives the actuator when the controller calls for it, and publishes the reading over the transport with the supplied codec. The control math lives in pamoja-kit, the power schedule in pamoja-power, and the wire format in the codec, so the node adds composition, not behavior.

Readings are real-world f32 units (degrees, percent, litres), the form the pamoja-kit controllers expect; a driver is responsible for calibrating raw counts into those units before the node sees them.

§Examples

use pamoja_codec::CborCodec;
use pamoja_core::{Actuator, Result, Sensor, Transport};
use pamoja_loopback::{LoopbackBroker, LoopbackTransport};
use pamoja_profile::{Node, Profile};

struct Probe(f32);
impl Sensor for Probe {
    type Reading = f32;
    async fn read(&mut self) -> Result<f32> {
        Ok(self.0)
    }
}

struct Cooler;
impl Actuator for Cooler {
    type Command = bool;
    async fn apply(&mut self, _on: bool) -> Result<()> {
        Ok(())
    }
}

let broker = LoopbackBroker::new();
let mut link = LoopbackTransport::new(broker);
link.connect().await?;

// A warm fridge, assembled straight from its profile.
let mut node = Node::new(Profile::vaccine_fridge_monitor(), Probe(9.0), Cooler, link, CborCodec);
let reaction = node.tick().await?;
assert_eq!(reaction.actuator, Some(true)); // the cooler runs
assert!(reaction.alert.is_some()); // and 9 C is a spoilage excursion

Implementations§

Source§

impl<S, A, T, C> Node<S, A, T, C>

Source

pub fn new( profile: Profile, sensor: S, actuator: A, transport: T, codec: C, ) -> Self

Assembles a node from a profile and the components that drive it.

§Arguments
  • profile - the profile to assemble; its policy becomes the node’s controller.
  • sensor - the source of readings.
  • actuator - the output the controller switches.
  • transport - the link readings are published over; expected to be connected.
  • codec - the wire format readings are encoded with.
§Returns

A node ready to tick.

Source

pub fn profile(&self) -> &Profile

Returns the profile this node was assembled from.

§Returns

A reference to the node’s Profile.

Source

pub fn schedule(&self, soc: f32, charging: bool) -> (PowerMode, Duration)

Returns the power mode and wait interval for the next cycle.

This assembles the profile’s PowerSchedule into a pamoja-power governor: as the battery drains the interval stretches, and a charging panel eases the node back toward its active cadence. The node never sleeps; the caller waits the returned Duration before the next tick, so timing stays outside the node and the decision logic remains synchronous and testable.

§Arguments
  • soc - the battery state of charge in [0.0, 1.0].
  • charging - whether the panel is currently delivering charge.
§Returns

The [PowerMode] to run in and how long to wait before the next cycle.

Source§

impl<S, T, C> Node<S, NoActuator, T, C>

Source

pub fn monitor(profile: Profile, sensor: S, transport: T, codec: C) -> Self

Assembles a node for a profile that observes without driving an output.

Wires a NoActuator in place of a real output, so a monitoring profile such as well_level reads and publishes with the same shape as a controlling one.

§Arguments
  • profile - the profile to assemble.
  • sensor - the source of readings.
  • transport - the link readings are published over; expected to be connected.
  • codec - the wire format readings are encoded with.
§Returns

A node ready to tick, with no output to switch.

Source§

impl<S, A, T, C> Node<S, A, T, C>
where S: Sensor<Reading = f32>, A: Actuator<Command = bool>, T: Transport, C: Codec<f32>,

Source

pub async fn tick(&mut self) -> Result<Reaction>

Runs one read-decide-act-publish cycle.

Reads the sensor, evaluates the profile’s controller, applies the resulting command to the actuator when the controller calls for one, and publishes the reading to the profile’s topic.

§Returns

The Reaction the controller produced: the actuator setting that was applied (if any) and any alert the reading raised.

§Errors

Returns Error::Io or Error::Closed if the sensor read or the actuator command fails, Error::Codec if the reading cannot be encoded, and Error::Transport or Error::Closed if the publish fails.

Auto Trait Implementations§

§

impl<S, A, T, C> Freeze for Node<S, A, T, C>
where S: Freeze, A: Freeze, T: Freeze, C: Freeze,

§

impl<S, A, T, C> RefUnwindSafe for Node<S, A, T, C>

§

impl<S, A, T, C> Send for Node<S, A, T, C>
where S: Send, A: Send, T: Send, C: Send,

§

impl<S, A, T, C> Sync for Node<S, A, T, C>
where S: Sync, A: Sync, T: Sync, C: Sync,

§

impl<S, A, T, C> Unpin for Node<S, A, T, C>
where S: Unpin, A: Unpin, T: Unpin, C: Unpin,

§

impl<S, A, T, C> UnsafeUnpin for Node<S, A, T, C>

§

impl<S, A, T, C> UnwindSafe for Node<S, A, T, C>

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
§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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.

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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.