Skip to main content

Profile

Struct Profile 

Source
pub struct Profile {
    pub name: String,
    pub topic: String,
    pub control: ControlSpec,
    pub power: PowerSchedule,
    pub presentation: Option<Presentation>,
}
Expand description

A named, pre-wired bundle of control policy, publish topic, and power schedule.

A profile is the unit a builder instantiates instead of wiring pins and tuning constants, and it is plain data: it serializes to and from a manifest a community can write, store in a file, and share. Pick a preset such as vaccine_fridge_monitor or load one with from_json, hand it a sensor, an actuator, a transport, and a codec, and the resulting Node reads, decides, drives the output, and publishes on its own. Every field is public, so a deployment can adjust the policy, topic, or power schedule in place.

§Examples

use pamoja_profile::{ControlSpec, Profile};

let profile = Profile::vaccine_fridge_monitor();
assert_eq!(profile.name, "vaccine-fridge-monitor");
assert!(matches!(profile.control, ControlSpec::Setpoint { .. }));

Fields§

§name: String

A stable, human-readable name, such as "vaccine-fridge-monitor".

§topic: String

The topic each reading is published to.

§control: ControlSpec

The control policy applied to each reading.

§power: PowerSchedule

The power schedule that sets how often the node samples as the battery drains.

§presentation: Option<Presentation>

How this profile presents itself on the dashboard - its custom sensors, node stats, and theme. A profile that introduces no element beyond the dashboard’s built-in set leaves this None.

Implementations§

Source§

impl Profile

Source

pub fn vaccine_fridge_monitor() -> Self

A cold-chain fridge monitor: hold 5 C and alert on a spoilage excursion.

Switches a cooler to hold the contents near 5 C and raises an Alert::OutOfRange the moment the temperature leaves the 2-8 C safe range. Data integrity outweighs power here, so it keeps sampling often even as the battery drains.

§Returns

The cold-chain monitoring profile.

Source

pub fn irrigation_node() -> Self

An irrigation node: hold soil moisture near a target by opening a valve.

Treats the valve as a “heater” for soil moisture, opening it when the soil dries below the band and closing it once it is wet enough, and alerts if the soil falls critically dry. Samples less often than the fridge, since soil changes slowly and battery life matters more.

§Returns

The irrigation profile.

Source

pub fn well_level() -> Self

A well-level monitor: report depth and warn before the well runs dry.

Observes the water level without driving an output and raises an Alert::RunningOut once the level is on course to reach the dry mark within a few more samples.

§Returns

The well-level monitoring profile.

Source

pub fn flood_sensor() -> Self

A flash-flood sensor: warn when a river level rises dangerously fast.

Watches a river or stream gauge and raises an Alert::ChangingFast when the level rises more than 0.3 m in a single sample, the signature of a flash flood. It samples often, because a flood gives little warning.

§Returns

The flash-flood monitoring profile.

§Examples
use pamoja_profile::{Alert, Profile};

let mut control = Profile::flood_sensor().controller();
control.evaluate(1.0); // first fix establishes the level
let reaction = control.evaluate(1.5); // the river jumped 0.5 m
assert!(matches!(reaction.alert, Some(Alert::ChangingFast { .. })));
Source

pub fn controller(&self) -> Controller

Assembles this profile’s ControlSpec into a live Controller.

§Returns

A fresh controller implementing the profile’s policy, with its control state reset.

Source

pub fn with_presentation(self, presentation: Presentation) -> Self

Attaches a dashboard Presentation declaring this profile’s custom elements.

A profile that measures something the dashboard does not draw out of the box - a turbidity probe, a custom node stat - carries the graphic, band, and label for it here, so the dashboard offers and renders it with no code.

§Arguments
  • presentation - how this profile presents itself on the dashboard.
§Returns

The profile, for chaining.

§Examples
use pamoja_profile::{ElementSpec, Presentation, Profile, Viz};

// A water-monitoring profile that adds a turbidity gauge the dashboard would not
// otherwise know how to draw.
let profile = Profile::well_level().with_presentation(
    Presentation::new().with_element(
        ElementSpec::new("water_turbidity", "ntu", "Turbidity", Viz::Gauge)
            .with_band(0.0, 5.0),
    ),
);
let elements = &profile.presentation.unwrap().elements;
assert_eq!(elements[0].viz.kind(), "radial");
Source§

impl Profile

Source

pub fn from_json(manifest: &str) -> Result<Self>

Loads a profile from a JSON manifest.

This is how a shared profile reaches a device: a community publishes a manifest file, and the runtime loads it into a profile to assemble a node from.

§Arguments
  • manifest - the JSON text of the profile.
§Returns

The profile described by manifest.

§Errors

Returns Error::Codec if manifest is not valid JSON or does not describe a profile.

§Examples
use pamoja_profile::Profile;

// A well-level monitor, shared as a manifest. The power thresholds are
// optional and default when omitted.
let manifest = r#"{
    "name": "tank-level",
    "topic": "water/tank/level",
    "control": { "kind": "level", "empty": 0.0, "warn_within": 5 },
    "power": { "active_secs": 600, "saver_secs": 1800, "critical_secs": 3600 }
}"#;

let profile = Profile::from_json(manifest).expect("valid manifest");
assert_eq!(profile.name, "tank-level");

let mut control = profile.controller();
control.evaluate(10.0); // first reading establishes a level
assert!(control.evaluate(2.0).alert.is_some()); // falling fast toward empty
Source

pub fn to_json(&self) -> Result<String>

Serializes this profile to a JSON manifest a community can share.

§Returns

The pretty-printed JSON text of the profile.

§Errors

Returns Error::Codec if the profile cannot be serialized.

Trait Implementations§

Source§

impl Clone for Profile

Source§

fn clone(&self) -> Profile

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 Debug for Profile

Source§

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

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

impl<'de> Deserialize<'de> for Profile

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Profile

Source§

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

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

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

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Profile

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Profile

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
§

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> 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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.