Skip to content

Commit 14216e3

Browse files
committed
update a lot of documentation
1 parent 1841ac9 commit 14216e3

14 files changed

+527
-49
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ The library provides fully typed support for all homie5 datatypes.
77

88
Due to this, the usage of the library is a bit more involved as with a completly ready to use homie library. Benefit is however that you can use the library basically everywhere from a simple esp32, raspberrypi to a x86 machine.
99

10+
[![works with MQTT Homie](https://homieiot.github.io/img/works-with-homie.png)](https://homieiot.github.io/)
11+
1012
## Content
1113

1214
<!-- TOC start (generated with https://github.com/derlin/bitdowntoc) -->

src/controller_proto.rs

+126-15
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
//! Provides MQTT subscription and publish message generators for a Homie 5 controller.
2+
//!
3+
//! This module implements the `Homie5ControllerProtocol` which generates MQTT messages necessary for discovering and controlling Homie 5 devices.
4+
//! The protocol manages the lifecycle of device discovery, subscribing to device attributes, and handling property changes.
5+
//!
6+
//! # Device Discovery Flow
7+
//! 1. Start with the Subscriptions returned by [`Homie5ControllerProtocol::discover_devices`]
8+
//! This will subscribe to the $state attribute of all devices.
9+
//! 2. When receiving a [`Homie5Message::DeviceState`] message, check if the device is already
10+
//! known, if not subscribe to the device using [`Homie5ControllerProtocol::subscribe_device`].
11+
//! This will subscibe to all the other device attributes like $log/$description/$alert
12+
//! 3. When receiving a [`Homie5Message::DeviceDescription`] message, store the description for the
13+
//! device and subscibe to all the property values using
14+
//! [`Homie5ControllerProtocol::subscribe_props`]
15+
//! 4. after this you will start receiving [`Homie5Message::PropertyValue`] and
16+
//! ['Homie5Message::PropertyTarget`] messages for the properties of the device
17+
//!
18+
119
use std::iter;
220

321
use crate::{
@@ -7,38 +25,66 @@ use crate::{
725
DEVICE_ATTRIBUTE_STATE, HOMIE_TOPIC_BROADCAST, HOMIE_VERSION, PROPERTY_ATTRIBUTE_TARGET, PROPERTY_SET_TOPIC,
826
};
927

10-
/// Provides generators for all mqtt subscribe and publish packages needed for a homie5 controller
11-
/// ### The general order for discovering devices is as follows:
12-
/// * Start with the Subscriptions returned by [`Homie5ControllerProtocol::discover_devices`]
13-
/// This will subscribe to the $state attribute of all devices.
14-
/// * When receiving a [`Homie5Message::DeviceState`] message, check if the device is already
15-
/// known, if not subscribe to the device using [`Homie5ControllerProtocol::subscribe_device`].
16-
/// This will subscibe to all the other device attributes like $log/$description/$alert
17-
/// * When receiving a [`Homie5Message::DeviceDescription`] message, store the description for the
18-
/// device and subscibe to all the property values using
19-
/// [`Homie5ControllerProtocol::subscribe_props`]
20-
/// * after this you will start receiving [`Homie5Message::PropertyValue`] and
21-
/// ['Homie5Message::PropertyTarget`] messages for the properties of the device
28+
/// The `Homie5ControllerProtocol` struct provides the core functionality for generating MQTT subscription and publish commands required for interacting with Homie 5 devices.
29+
///
30+
/// This struct simplifies the process of discovering devices, subscribing to device attributes, handling device property changes, and sending commands or broadcasts to devices in the Homie MQTT protocol. It supports managing device discovery, subscriptions to device states and properties, and sending set commands and broadcast messages.
31+
///
32+
/// The `Homie5ControllerProtocol` is designed for use in Homie-based IoT controllers where efficient communication with multiple devices is required. It offers a straightforward interface for subscribing to device attributes and managing device properties.
33+
///
34+
/// # Usage
35+
///
36+
/// To create an instance of `Homie5ControllerProtocol`, use the `new` method. This struct provides methods for discovering devices, subscribing to device attributes and properties, and sending commands or broadcasts via MQTT topics.
37+
///
38+
/// # Example
39+
///
40+
/// ```rust
41+
/// use homie5::{Homie5ControllerProtocol, HomieDomain};
42+
///
43+
/// let protocol = Homie5ControllerProtocol::new();
44+
/// let subscriptions = protocol.discover_devices(&HomieDomain::Default);
45+
/// for subscription in subscriptions {
46+
/// // Handle each subscription
47+
/// }
48+
/// ```
49+
///
50+
/// The struct is intended for use in controller applications interacting with multiple Homie devices, enabling efficient subscription management and MQTT communication.
2251
#[derive(Default)]
2352
pub struct Homie5ControllerProtocol {}
2453

2554
impl Homie5ControllerProtocol {
26-
/// Create a new Homie5ControllerProtocol object
55+
/// Creates a new `Homie5ControllerProtocol` instance.
56+
///
57+
/// # Returns
58+
/// A new `Homie5ControllerProtocol` object initialized with default values.
2759
pub fn new() -> Self {
2860
Default::default()
2961
}
3062

63+
/// Generates a subscription to discover Homie devices by subscribing to the `$state` attribute of all devices.
64+
///
65+
/// # Parameters
66+
/// - `homie_domain`: The Homie domain in which to discover devices.
67+
///
68+
/// # Returns
69+
/// An iterator over a `Subscription` object that subscribes to the `$state` attribute of all devices in the specified domain.
3170
pub fn discover_devices<'a>(&'a self, homie_domain: &HomieDomain) -> impl Iterator<Item = Subscription> + 'a {
3271
iter::once(Subscription {
3372
topic: format!("{}/{}/+/{}", homie_domain, HOMIE_VERSION, DEVICE_ATTRIBUTE_STATE),
3473
qos: QoS::ExactlyOnce,
3574
})
3675
}
3776

77+
/// Generates subscriptions for all attributes of a specified device, excluding `$state`.
78+
///
79+
/// # Parameters
80+
/// - `device`: A reference to the `DeviceRef` that identifies the device.
81+
///
82+
/// # Returns
83+
/// An iterator over `Subscription` objects for the device's attributes (e.g., `$log`, `$description`, `$alert`).
3884
pub fn subscribe_device<'a>(&'a self, device: &'a DeviceRef) -> impl Iterator<Item = Subscription> + 'a {
3985
DEVICE_ATTRIBUTES
4086
.iter()
41-
.skip(1) // Skip the $state attribute (which must be first in the array)
87+
.skip(1) // Skip the $state attribute
4288
.map(move |attribute| {
4389
if *attribute == DEVICE_ATTRIBUTE_ALERT {
4490
Subscription {
@@ -54,6 +100,13 @@ impl Homie5ControllerProtocol {
54100
})
55101
}
56102

103+
/// Generates unsubscribe requests for all attributes of a specified device, excluding `$state`.
104+
///
105+
/// # Parameters
106+
/// - `device`: A reference to the `DeviceRef` that identifies the device.
107+
///
108+
/// # Returns
109+
/// An iterator over `Unsubscribe` objects for the device's attributes (e.g., `$log`, `$description`, `$alert`).
57110
pub fn unsubscribe_device<'a>(&'a self, device: &'a DeviceRef) -> impl Iterator<Item = Unsubscribe> + 'a {
58111
DEVICE_ATTRIBUTES.iter().skip(1).map(move |attribute| {
59112
if *attribute == DEVICE_ATTRIBUTE_ALERT {
@@ -68,6 +121,14 @@ impl Homie5ControllerProtocol {
68121
})
69122
}
70123

124+
/// Subscribes to all properties of a device as described in the provided `HomieDeviceDescription`.
125+
///
126+
/// # Parameters
127+
/// - `device`: A reference to the `DeviceRef` that identifies the device.
128+
/// - `description`: A reference to the `HomieDeviceDescription` that describes the device's properties.
129+
///
130+
/// # Returns
131+
/// An iterator over `Subscription` objects for the device's properties.
71132
pub fn subscribe_props<'a>(
72133
&'a self,
73134
device: &'a DeviceRef,
@@ -95,6 +156,14 @@ impl Homie5ControllerProtocol {
95156
})
96157
}
97158

159+
/// Unsubscribes from all properties of a device based on its `HomieDeviceDescription`.
160+
///
161+
/// # Parameters
162+
/// - `device`: A reference to the `DeviceRef` that identifies the device.
163+
/// - `description`: A reference to the `HomieDeviceDescription` that describes the device's properties.
164+
///
165+
/// # Returns
166+
/// An iterator over `Unsubscribe` objects for the device's properties.
98167
pub fn unsubscribe_props<'a>(
99168
&'a self,
100169
device: &'a DeviceRef,
@@ -106,6 +175,17 @@ impl Homie5ControllerProtocol {
106175
})
107176
}
108177

178+
/// Publishes a set command to change a property's value.
179+
///
180+
/// # Parameters
181+
/// - `homie_domain`: The Homie domain in which the device is located.
182+
/// - `device_id`: The ID of the device.
183+
/// - `node_id`: The ID of the node the property belongs to.
184+
/// - `prop_id`: The ID of the property.
185+
/// - `value`: The new value to set for the property.
186+
///
187+
/// # Returns
188+
/// A `Publish` object containing the set command to be sent to the MQTT broker.
109189
pub fn set_command_ids(
110190
&self,
111191
homie_domain: &HomieDomain,
@@ -125,7 +205,14 @@ impl Homie5ControllerProtocol {
125205
}
126206
}
127207

128-
//pub fn set_command(&self, prop: &PropertyIdentifier, value: impl Into<String>) -> Publish {
208+
/// Publishes a set command for a property using a `PropertyRef`.
209+
///
210+
/// # Parameters
211+
/// - `prop`: A reference to the `PropertyRef` identifying the property.
212+
/// - `value`: The new value to set for the property.
213+
///
214+
/// # Returns
215+
/// A `Publish` object containing the set command to be sent to the MQTT broker.
129216
pub fn set_command(&self, prop: &PropertyRef, value: &HomieValue) -> Publish {
130217
self.set_command_ids(
131218
&prop.node.device.homie_domain,
@@ -136,6 +223,15 @@ impl Homie5ControllerProtocol {
136223
)
137224
}
138225

226+
/// Sends a broadcast message to all devices in the specified Homie domain.
227+
///
228+
/// # Parameters
229+
/// - `homie_domain`: The Homie domain in which to send the broadcast.
230+
/// - `broadcast_topic`: The topic of the broadcast.
231+
/// - `broadcast_message`: The content of the broadcast message.
232+
///
233+
/// # Returns
234+
/// A `Publish` object representing the broadcast message to be sent to the MQTT broker.
139235
pub fn send_broadcast(
140236
&self,
141237
homie_domain: &HomieDomain,
@@ -153,12 +249,27 @@ impl Homie5ControllerProtocol {
153249
}
154250
}
155251

252+
/// Subscribes to broadcast messages in the specified Homie domain.
253+
///
254+
/// # Parameters
255+
/// - `homie_domain`: The Homie domain in which to subscribe to broadcasts.
256+
///
257+
/// # Returns
258+
/// An iterator over a `Subscription` object that subscribes to broadcast messages.
156259
pub fn subscribe_broadcast<'a>(&'a self, homie_domain: &HomieDomain) -> impl Iterator<Item = Subscription> + 'a {
157260
iter::once(Subscription {
158261
topic: format!("{}/{}/$broadcast/#", homie_domain, HOMIE_VERSION),
159262
qos: QoS::ExactlyOnce,
160263
})
161264
}
265+
266+
/// Unsubscribes from broadcast messages in the specified Homie domain.
267+
///
268+
/// # Parameters
269+
/// - `homie_domain`: The Homie domain in which to unsubscribe from broadcasts.
270+
///
271+
/// # Returns
272+
/// An iterator over an `Unsubscribe` object that unsubscribes from broadcast messages.
162273
pub fn unsubscribe_broadcast<'a>(&'a self, homie_domain: &HomieDomain) -> impl Iterator<Item = Unsubscribe> + 'a {
163274
iter::once(Unsubscribe {
164275
topic: format!("{}/{}/$broadcast/#", homie_domain, HOMIE_VERSION),

src/device_description/builder.rs

+58
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
//! This module provides builders for constructing descriptions of Homie devices, nodes, and properties.
2+
//! The builders allow for flexible and incremental building of `HomieDeviceDescription`,
3+
//! `HomieNodeDescription`, and `HomiePropertyDescription` objects, commonly used in the Homie protocol.
4+
//!
5+
//! # Conditional Building
6+
//!
7+
//! All builders in this module offer the `do_if` method, which allows for executing a closure
8+
//! only if a certain condition is met. This is useful for adding optional elements or applying logic
9+
//! based on runtime conditions.
10+
//!
11+
//! ```
112
use crate::{HomieDataType, HomieID, HOMIE_VERSION_FULL};
213

314
use super::{
@@ -6,6 +17,21 @@ use super::{
617
};
718
use std::collections::{hash_map, HashMap};
819

20+
/// Builder for constructing `HomieDeviceDescription` objects.
21+
///
22+
/// The `DeviceDescriptionBuilder` helps construct a complete `HomieDeviceDescription` by setting attributes
23+
/// like children, nodes, extensions, and device metadata. It provides flexibility in handling device structure
24+
/// and content, allowing for customization at each step.
25+
///
26+
/// ### Example Usage
27+
/// ```rust
28+
/// use homie5::device_description::*;
29+
/// let device_description = DeviceDescriptionBuilder::new()
30+
/// .name(Some("MyDevice".to_string()))
31+
/// .add_child("node1".try_into().unwrap())
32+
/// .add_extension("com.example.extension".to_string())
33+
/// .build();
34+
/// ```
935
pub struct DeviceDescriptionBuilder {
1036
description: HomieDeviceDescription,
1137
}
@@ -119,6 +145,20 @@ impl DeviceDescriptionBuilder {
119145
}
120146
}
121147

148+
/// Builder for constructing `HomieNodeDescription` objects.
149+
///
150+
/// The `NodeDescriptionBuilder` simplifies the creation of `HomieNodeDescription` instances.
151+
/// Nodes are the intermediate layer between devices and properties, and this builder facilitates
152+
/// adding properties, setting the node name and type, and optionally removing or replacing properties.
153+
///
154+
/// ### Example Usage
155+
/// ```rust
156+
/// use homie5::device_description::*;
157+
/// let node_description = NodeDescriptionBuilder::new()
158+
/// .name(Some("TemperatureNode".to_string()))
159+
/// .r#type("sensor")
160+
/// .build();
161+
/// ```
122162
pub struct NodeDescriptionBuilder {
123163
description: HomieNodeDescription,
124164
}
@@ -212,6 +252,24 @@ impl NodeDescriptionBuilder {
212252
}
213253
}
214254

255+
/// Builder for constructing `HomiePropertyDescription` objects.
256+
///
257+
/// The `PropertyDescriptionBuilder` is designed for constructing `HomiePropertyDescription`
258+
/// objects, which represent individual properties of a node, such as sensor readings or settings.
259+
/// Properties have attributes like datatype, format, settable, and retained, which can be set using
260+
/// this builder.
261+
///
262+
/// ### Example Usage
263+
/// ```rust
264+
/// use homie5::device_description::*;
265+
/// use homie5::*;
266+
/// let property_description = PropertyDescriptionBuilder::new(HomieDataType::Float)
267+
/// .name(Some("Temperature".to_string()))
268+
/// .settable(false)
269+
/// .retained(true)
270+
/// .unit(Some("°C".to_string()))
271+
/// .build();
272+
/// ```
215273
pub struct PropertyDescriptionBuilder {
216274
description: HomiePropertyDescription,
217275
}

src/device_description/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//! This module provides all types and tools to create (builders) and manage homie device, node and property
2+
//! descriptions.
13
use std::collections::hash_map::DefaultHasher;
24
use std::hash::Hasher;
35
use std::iter::Iterator;

0 commit comments

Comments
 (0)