Skip to content

Commit b5f0a34

Browse files
medusalixMossop
authored andcommitted
Add command_topic and make state_topic optional
1 parent a6b3904 commit b5f0a34

4 files changed

Lines changed: 36 additions & 10 deletions

File tree

src/homeassistant/light.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,6 @@ impl Serialize for LightState<'_> {
324324

325325
/// A light entity
326326
pub struct Light<'a, const C: usize, const E: usize> {
327-
/// A command topic that Home Assistant can use to control the light.
328-
/// It will be sent a [`LightState`] payload.
329-
pub command_topic: Option<Topic<&'a str>>,
330327
/// The color modes supported by the light.
331328
pub supported_color_modes: [SupportedColorMode; C],
332329
/// Any effects that can be used.
@@ -338,7 +335,7 @@ impl<const C: usize, const E: usize> Serialize for Light<'_, C, E> {
338335
where
339336
S: Serializer,
340337
{
341-
let mut len = 3;
338+
let mut len = 2;
342339

343340
if C > 0 {
344341
len += 1;
@@ -350,7 +347,6 @@ impl<const C: usize, const E: usize> Serialize for Light<'_, C, E> {
350347

351348
let mut serializer = serializer.serialize_struct("Light", len)?;
352349

353-
serializer.serialize_field("cmd_t", &self.command_topic)?;
354350
serializer.serialize_field("schema", "json")?;
355351

356352
if C > 0 {

src/homeassistant/mod.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
//! unique_id: Some("motion"),
2121
//! name: "Motion",
2222
//! availability: AvailabilityTopics::All([DEVICE_AVAILABILITY_TOPIC]),
23-
//! state_topic: MOTION_STATE_TOPIC,
23+
//! state_topic: Some(MOTION_STATE_TOPIC),
24+
//! command_topic: None,
2425
//! component: BinarySensor {
2526
//! device_class: Some(BinarySensorClass::Motion),
2627
//! },
@@ -206,7 +207,9 @@ pub struct Entity<'a, const A: usize, C: Component> {
206207
/// determine this entity's availability.
207208
pub availability: AvailabilityTopics<'a, A>,
208209
/// The state topic that this entity's state is published to.
209-
pub state_topic: Topic<&'a str>,
210+
pub state_topic: Option<Topic<&'a str>>,
211+
/// The command topic that this entity receives commands from.
212+
pub command_topic: Option<Topic<&'a str>>,
210213
/// The specific entity.
211214
pub component: C,
212215
}
@@ -233,8 +236,16 @@ impl<const A: usize, C: Component> Entity<'_, A, C> {
233236
}
234237

235238
/// Publishes this entity's state to the broker.
239+
///
240+
/// # Errors
241+
///
242+
/// - [`Error::Invalid`] if the entity doesn't have a state topic.
236243
pub async fn publish_state(&self, state: C::State) -> Result<(), Error> {
237-
self.component.publish_state(&self.state_topic, state).await
244+
if let Some(topic) = self.state_topic {
245+
self.component.publish_state(&topic, state).await
246+
} else {
247+
Err(Error::Invalid)
248+
}
238249
}
239250
}
240251

src/homeassistant/ser.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ impl<const A: usize, C: Component, S: Serializer> Serializer for DiscoverySerial
8888
name: &'static str,
8989
mut len: usize,
9090
) -> Result<Self::SerializeStruct, Self::Error> {
91-
len += 6;
91+
len += 5;
92+
if self.discovery.state_topic.is_some() {
93+
len += 1;
94+
}
95+
if self.discovery.command_topic.is_some() {
96+
len += 1;
97+
}
9298
if self.discovery.unique_id.is_some() {
9399
len += 1;
94100
}
@@ -104,7 +110,18 @@ impl<const A: usize, C: Component, S: Serializer> Serializer for DiscoverySerial
104110
serializer.serialize_field("obj_id", self.discovery.object_id)?;
105111

106112
serializer.serialize_field("name", self.discovery.name)?;
107-
serializer.serialize_field("stat_t", &self.discovery.state_topic)?;
113+
114+
if let Some(t) = self.discovery.state_topic {
115+
serializer.serialize_field("stat_t", &t)?;
116+
} else {
117+
serializer.skip_field("stat_t")?;
118+
}
119+
120+
if let Some(t) = self.discovery.command_topic {
121+
serializer.serialize_field("cmd_t", &t)?;
122+
} else {
123+
serializer.skip_field("cmd_t")?;
124+
}
108125

109126
match &self.discovery.availability {
110127
AvailabilityTopics::None => {

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ pub enum Error {
6868
TooLarge,
6969
/// A packet or payload could not be decoded or encoded.
7070
PacketError,
71+
/// An invalid or unsupported operation was attempted.
72+
Invalid,
7173
}
7274

7375
#[allow(clippy::large_enum_variant)]

0 commit comments

Comments
 (0)