feat: Migrate to rumqttc-next
Build and deploy / Build container and manifests (push) Successful in 21m5s
Build and deploy / build (push) Successful in 21m5s
Build and deploy / Deploy container (push) Successful in 40s

This commit is contained in:
2026-08-26 05:44:33 +02:00
parent 7ca1da8349
commit 64f3052b76
14 changed files with 250 additions and 97 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ inventory = { workspace = true }
lua_typed = { workspace = true }
mlua = { workspace = true }
reqwest = { workspace = true }
rumqttc = { workspace = true }
rumqttc-next = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
serde_repr = { workspace = true }
+4 -1
View File
@@ -159,7 +159,10 @@ impl OpenClose for ContactSensor {
#[async_trait]
impl OnMqtt for ContactSensor {
async fn on_mqtt(&self, message: rumqttc::Publish) {
if !rumqttc::matches(&message.topic, &self.config.mqtt.topic) {
if !rumqttc::matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
return;
}
+4 -1
View File
@@ -98,7 +98,10 @@ impl LuaDeviceCreate for HueSwitch {
impl OnMqtt for HueSwitch {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the device itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let message = match serde_json::from_slice::<State>(&message.payload) {
Ok(message) => message,
Err(err) => {
+4 -1
View File
@@ -70,7 +70,10 @@ impl LuaDeviceCreate for IkeaRemote {
impl OnMqtt for IkeaRemote {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the deviec itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let message = match RemoteMessage::try_from(message) {
Ok(message) => message,
Err(err) => {
+4 -1
View File
@@ -85,7 +85,10 @@ impl Device for LightSensor {
#[async_trait]
impl OnMqtt for LightSensor {
async fn on_mqtt(&self, message: Publish) {
if !rumqttc::matches(&message.topic, &self.config.mqtt.topic) {
if !rumqttc::matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
return;
}
+7 -2
View File
@@ -105,7 +105,10 @@ impl Device for Presence {
#[async_trait]
impl OnMqtt for Presence {
async fn on_mqtt(&self, message: Publish) {
if !rumqttc::matches(&message.topic, &self.config.mqtt.topic) {
if !rumqttc::matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
return;
}
@@ -116,7 +119,9 @@ impl OnMqtt for Presence {
.find('+')
.or(self.config.mqtt.topic.find('#'))
.expect("Presence::create fails if it does not contain wildcards");
let device_name = message.topic[offset..].into();
let device_name: String = str::from_utf8(&message.topic[offset..])
.expect("Topic should be valid")
.into();
if message.payload.is_empty() {
// Remove the device from the map
+4 -1
View File
@@ -66,7 +66,10 @@ impl Device for WakeOnLAN {
#[async_trait]
impl OnMqtt for WakeOnLAN {
async fn on_mqtt(&self, message: Publish) {
if !rumqttc::matches(&message.topic, &self.config.mqtt.topic) {
if !rumqttc::matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
return;
}
+4 -1
View File
@@ -89,7 +89,10 @@ const HYSTERESIS: isize = 10;
#[async_trait]
impl OnMqtt for Washer {
async fn on_mqtt(&self, message: Publish) {
if !rumqttc::matches(&message.topic, &self.config.mqtt.topic) {
if !rumqttc::matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
return;
}
+17 -10
View File
@@ -1,3 +1,4 @@
use core::str;
use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc;
@@ -16,7 +17,7 @@ use google_home::errors::ErrorCode;
use google_home::traits::{Brightness, Color, ColorSetting, ColorTemperatureRange, OnOff};
use google_home::types::Type;
use lua_typed::Typed;
use rumqttc::{Publish, matches};
use rumqttc::{Publish, PublishOptions, matches};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
@@ -177,7 +178,10 @@ where
impl OnMqtt for LightOnOff {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the device itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let state = match serde_json::from_slice::<StateOnOff>(&message.payload) {
Ok(state) => state,
Err(err) => {
@@ -210,7 +214,10 @@ impl OnMqtt for LightOnOff {
impl OnMqtt for LightBrightness {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the deviec itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let state = match serde_json::from_slice::<StateBrightness>(&message.payload) {
Ok(state) => state,
Err(err) => {
@@ -249,7 +256,10 @@ impl OnMqtt for LightBrightness {
impl OnMqtt for LightColorTemperature {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the deviec itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let state = match serde_json::from_slice::<StateColorTemperature>(&message.payload) {
Ok(state) => state,
Err(err) => {
@@ -342,9 +352,8 @@ where
.client
.publish(
&topic,
rumqttc::QoS::AtLeastOnce,
false,
serde_json::to_string(&message).unwrap(),
PublishOptions::at_least_once(),
)
.await
.map_err(|err| warn!("Failed to update state on {topic}: {err}"))
@@ -386,9 +395,8 @@ where
.client
.publish(
&topic,
rumqttc::QoS::AtLeastOnce,
false,
serde_json::to_string(&message).unwrap(),
PublishOptions::at_least_once(),
)
.await
.map_err(|err| warn!("Failed to update state on {topic}: {err}"))
@@ -434,9 +442,8 @@ where
.client
.publish(
&topic,
rumqttc::QoS::AtLeastOnce,
false,
serde_json::to_string(&message).unwrap(),
PublishOptions::at_least_once(),
)
.await
.map_err(|err| warn!("Failed to update state on {topic}: {err}"))
+10 -5
View File
@@ -16,7 +16,7 @@ use google_home::errors::ErrorCode;
use google_home::traits::OnOff;
use google_home::types::Type;
use lua_typed::Typed;
use rumqttc::{Publish, matches};
use rumqttc::{Publish, PublishOptions, matches};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
@@ -162,7 +162,10 @@ where
impl OnMqtt for OutletOnOff {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the device itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let state = match serde_json::from_slice::<StateOnOff>(&message.payload) {
Ok(state) => state,
Err(err) => {
@@ -195,7 +198,10 @@ impl OnMqtt for OutletOnOff {
impl OnMqtt for OutletPower {
async fn on_mqtt(&self, message: Publish) {
// Check if the message is from the deviec itself or from a remote
if matches(&message.topic, &self.config.mqtt.topic) {
if matches(
str::from_utf8(&message.topic).expect("Topic should be valid"),
&self.config.mqtt.topic,
) {
let state = match serde_json::from_slice::<StatePower>(&message.payload) {
Ok(state) => state,
Err(err) => {
@@ -284,9 +290,8 @@ where
.client
.publish(
&topic,
rumqttc::QoS::AtLeastOnce,
false,
serde_json::to_string(&message).unwrap(),
PublishOptions::at_least_once(),
)
.await
.map_err(|err| warn!("Failed to update state on {topic}: {err}"))