Skip to main content

Crate ebus_homie

Crate ebus_homie 

Source
Expand description

Homie 5 protocol core for eBus.

The crate performs no I/O: callers pass in received MQTT messages and send the messages it returns, so the same core serves tokio services and microcontrollers.

ModuleContents
controllerThe controller state machine: discovery, pacing, device views, events, /set and $broadcast (alloc)
deviceThe device role: a tree of devices, nodes and properties, publishing and /set handling (alloc)
descriptionThe $description model, parsing, validation and wire form (alloc)
datatypeThe nine datatypes, payload checks, /set parsing and the encoders
topicParsing and building {domain}/5/{device}/... topics
id, state, payloadTopic-level ids, $state values, empty-payload rules

A controller runs on the caller’s connection and clock. Feed it a link change and messages, then send what poll_command returns and read what poll_event returns:

use ebus_homie::controller::{Config, Controller, Event};
use ebus_mqtt::{Command, Instant, Link, Message};

let mut c = Controller::new(Config::device("meter-1")?)?;
let now = Instant(0);
c.handle_link(now, Link::up(false));
while let Some(cmd) = c.poll_command() {
    if let Command::Subscribe { filters, .. } = cmd {
        assert!(filters.iter().any(|(f, _)| f == "ebus/5/meter-1/$state"));
    }
}

let retained = |topic, payload: &'static str| Message::new(topic, payload.as_bytes(), Some(true));
c.handle_message(now, retained("ebus/5/meter-1/$state", "ready"));
c.handle_message(
    now,
    retained(
        "ebus/5/meter-1/$description",
        r#"{"homie":"5.0","version":1,"nodes":{"power":{"properties":{"watts":{"datatype":"float"}}}}}"#,
    ),
);
while c.poll_command().is_some() {}
c.handle_message(now, retained("ebus/5/meter-1/power/watts", "1234.5"));

let mut synced = false;
while let Some(e) = c.poll_event() {
    synced |= matches!(e, Event::DeviceSynced { missing: 0, .. });
}
assert!(synced);
let watts = c.device("meter-1").and_then(|d| d.property("power", "watts"));
assert_eq!(watts.and_then(|p| p.value.as_ref()).map(|v| &*v.raw), Some("1234.5"));

§Features

Re-exports§

pub use serde_json;alloc

Modules§

controlleralloc
The Homie 5 controller as a sans-IO state machine.
datatype
Property datatypes and payload grammar (convention.md: Payload).
descriptionalloc
The $description document: model, wire form and validation (convention.md: Device Attributes, Nodes, Properties).
devicealloc
The Homie 5 device role as a sans-IO state machine.
id
Homie topic-level identifiers (convention.md: Topic IDs).
payload
Raw MQTT payload classification (convention.md: Empty string values).
state
Device $state values (convention.md: Device Lifecycle).
topic
Parse and build Homie 5 topics {domain}/5/{device}/....

Structs§

Idalloc
A Homie id (device, node, property or alert), validated with is_valid_id and cheap to clone.
PropertyAddralloc
One property of one device.

Constants§

EBUS_DOMAIN
Topic domain the eBus framework uses in place of Homie’s default homie.
HOMIE_DESCRIPTION_VERSION
Value of the homie field in a $description.
HOMIE_TOPIC_VERSION
Homie convention major version, as it appears in topics ({domain}/5/...).