aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2026-01-19 20:10:35 +0000
committerdiogo464 <[email protected]>2026-01-19 20:10:36 +0000
commitaa47d88882d9bd6c7753315c8fe1b9b2e9b21fa7 (patch)
tree12c9e9031a04c169a8218c4028a78ebff036d8f5 /src
parent27779ecf0d7c00ae0acb650c0d75d28edcc3aa89 (diff)
fix: prefix discovery unique_id with device id
right now we use the entity id as the unique_id in the entity discovery payload but we should have been prefixing it with the device_id like with did for the topics to avoid generating collisions. for example if we have devices 'relay_0' and 'relay_1' and they both have a button entity with id 'trigger' then the topics will be correctly generated using the id 'relay_0_trigger' and 'relay_1_trigger' but the unique id field in the discovery payload is being set as 'trigger' for both entities which causes this type of error to show up on the home assistant logs: 2026-01-19 19:52:07.539 ERROR (MainThread) [homeassistant.components.button] Platform mqtt does not generate unique IDs. ID open already exists - ignoring button.porta_frente_abri │ │ 2026-01-19 19:52:07.611 ERROR (MainThread) [homeassistant.components.sensor] Platform mqtt does not generate unique IDs. ID wifi-rssi already exists - ignoring sensor.porta_frente │ │ 2026-01-19 19:56:08.013 ERROR (MainThread) [homeassistant.components.button] Platform mqtt does not generate unique IDs. ID open already exists - ignoring button.porta_frente_abri │ │ 2026-01-19 19:56:08.067 ERROR (MainThread) [homeassistant.components.sensor] Platform mqtt does not generate unique IDs. ID wifi-rssi already exists - ignoring sensor.porta_frente |
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs38
1 files changed, 31 insertions, 7 deletions
diff --git a/src/lib.rs b/src/lib.rs
index b09bda2..2d1ecfb 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -181,11 +181,33 @@ struct DeviceDiscovery<'a> {
181 model: &'a str, 181 model: &'a str,
182} 182}
183 183
184#[derive(Debug, Clone, Copy)]
185#[cfg_attr(feature = "defmt", derive(Format))]
186struct EntityIdDiscovery<'a> {
187 device_id: &'a str,
188 entity_id: &'a str,
189}
190
191impl<'a> core::fmt::Display for EntityIdDiscovery<'a> {
192 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
193 write!(f, "{}_{}", self.device_id, self.entity_id)
194 }
195}
196
197impl<'a> Serialize for EntityIdDiscovery<'a> {
198 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199 where
200 S: serde::Serializer,
201 {
202 serializer.collect_str(self)
203 }
204}
205
184#[derive(Debug, Serialize)] 206#[derive(Debug, Serialize)]
185#[cfg_attr(feature = "defmt", derive(Format))] 207#[cfg_attr(feature = "defmt", derive(Format))]
186struct EntityDiscovery<'a> { 208struct EntityDiscovery<'a> {
187 #[serde(rename = "unique_id")] 209 #[serde(rename = "unique_id")]
188 id: &'a str, 210 id: EntityIdDiscovery<'a>,
189 211
190 #[serde(skip_serializing_if = "Option::is_none")] 212 #[serde(skip_serializing_if = "Option::is_none")]
191 name: Option<&'a str>, 213 name: Option<&'a str>,
@@ -1006,7 +1028,10 @@ fn generate_entity_discovery(
1006 }; 1028 };
1007 1029
1008 let discovery = EntityDiscovery { 1030 let discovery = EntityDiscovery {
1009 id: entity_config.id, 1031 id: EntityIdDiscovery {
1032 device_id: device_config.device_id,
1033 entity_id: entity_config.id,
1034 },
1010 name: entity_config.name, 1035 name: entity_config.name,
1011 device_class: entity_config.device_class, 1036 device_class: entity_config.device_class,
1012 state_topic: Some(buffers.state_topic.as_str()), 1037 state_topic: Some(buffers.state_topic.as_str()),
@@ -1332,11 +1357,10 @@ pub async fn run<T: Transport>(device: &mut Device<'_>, transport: &mut T) -> Re
1332 1357
1333 let mut read_buffer = [0u8; 128]; 1358 let mut read_buffer = [0u8; 128];
1334 let data_len = publish.data_len; 1359 let data_len = publish.data_len;
1335 let receive_data = 1360 let receive_data = match mqtt_receive_data(&mut client, data_len, &mut read_buffer).await {
1336 match mqtt_receive_data(&mut client, data_len, &mut read_buffer).await { 1361 Ok(data) => data,
1337 Ok(data) => data, 1362 Err(_) => continue 'outer_loop,
1338 Err(_) => continue 'outer_loop, 1363 };
1339 };
1340 1364
1341 let command = match str::from_utf8(receive_data) { 1365 let command = match str::from_utf8(receive_data) {
1342 Ok(command) => command, 1366 Ok(command) => command,