Improved error handling
This commit is contained in:
@@ -4,10 +4,11 @@ use rumqttc::{AsyncClient, matches};
|
||||
use tracing::{error, warn, debug};
|
||||
|
||||
use crate::config::MqttDeviceConfig;
|
||||
use crate::error;
|
||||
use crate::mqtt::{OnMqtt, RemoteMessage, RemoteAction};
|
||||
use crate::presence::OnPresence;
|
||||
|
||||
use super::Device;
|
||||
use super::{Device, DeviceBox, AsOnOff};
|
||||
|
||||
// @TODO Ideally we store am Arc to the childern devices,
|
||||
// that way they hook into everything just like all other devices
|
||||
@@ -20,10 +21,20 @@ pub struct AudioSetup {
|
||||
}
|
||||
|
||||
impl AudioSetup {
|
||||
pub async fn new(identifier: String, mqtt: MqttDeviceConfig, mixer: Box<dyn traits::OnOff + Sync + Send>, speakers: Box<dyn traits::OnOff + Sync + Send>, client: AsyncClient) -> Self {
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await.unwrap();
|
||||
pub async fn build(identifier: &str, mqtt: MqttDeviceConfig, mixer: DeviceBox, speakers: DeviceBox, client: AsyncClient) -> error::Result<Self> {
|
||||
// We expect the children devices to implement the OnOff trait
|
||||
let mixer = match AsOnOff::consume(mixer) {
|
||||
Some(mixer) => mixer,
|
||||
None => Err(error::ExpectedOnOff::new(&(identifier.to_owned() + ".mixer")))?,
|
||||
};
|
||||
let speakers = match AsOnOff::consume(speakers) {
|
||||
Some(speakers) => speakers,
|
||||
None => Err(error::ExpectedOnOff::new(&(identifier.to_owned() + ".speakers")))?,
|
||||
};
|
||||
|
||||
Self { identifier, mqtt, mixer, speakers }
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?;
|
||||
|
||||
Ok(Self { identifier: identifier.to_owned(), mqtt, mixer, speakers })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use rumqttc::{AsyncClient, matches};
|
||||
use tokio::task::JoinHandle;
|
||||
use tracing::{error, debug, warn};
|
||||
|
||||
use crate::{config::{MqttDeviceConfig, PresenceDeviceConfig}, mqtt::{OnMqtt, ContactMessage, PresenceMessage}, presence::OnPresence};
|
||||
use crate::{config::{MqttDeviceConfig, PresenceDeviceConfig}, mqtt::{OnMqtt, ContactMessage, PresenceMessage}, presence::OnPresence, error};
|
||||
|
||||
use super::Device;
|
||||
|
||||
@@ -22,18 +22,18 @@ pub struct ContactSensor {
|
||||
}
|
||||
|
||||
impl ContactSensor {
|
||||
pub async fn new(identifier: String, mqtt: MqttDeviceConfig, presence: Option<PresenceDeviceConfig>, client: AsyncClient) -> Self {
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await.unwrap();
|
||||
pub async fn build(identifier: &str, mqtt: MqttDeviceConfig, presence: Option<PresenceDeviceConfig>, client: AsyncClient) -> error::Result<Self> {
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?;
|
||||
|
||||
Self {
|
||||
identifier,
|
||||
Ok(Self {
|
||||
identifier: identifier.to_owned(),
|
||||
mqtt,
|
||||
presence,
|
||||
client,
|
||||
overall_presence: false,
|
||||
is_closed: true,
|
||||
handle: None,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ impl OnMqtt for ContactSensor {
|
||||
// This is to prevent the house from being marked as present for however long the
|
||||
// timeout is set when leaving the house
|
||||
if !self.overall_presence {
|
||||
self.client.publish(topic, rumqttc::QoS::AtLeastOnce, false, serde_json::to_string(&PresenceMessage::new(true)).unwrap()).await.unwrap();
|
||||
self.client.publish(topic.clone(), rumqttc::QoS::AtLeastOnce, false, serde_json::to_string(&PresenceMessage::new(true)).unwrap()).await.map_err(|err| warn!("Failed to publish presence on {topic}: {err}")).ok();
|
||||
}
|
||||
} else {
|
||||
// Once the door is closed again we start a timeout for removing the presence
|
||||
@@ -109,7 +109,7 @@ impl OnMqtt for ContactSensor {
|
||||
debug!(id, "Starting timeout ({timeout:?}) for contact sensor...");
|
||||
tokio::time::sleep(timeout).await;
|
||||
debug!(id, "Removing door device!");
|
||||
client.publish(topic, rumqttc::QoS::AtLeastOnce, false, "").await.unwrap();
|
||||
client.publish(topic.clone(), rumqttc::QoS::AtLeastOnce, false, "").await.map_err(|err| warn!("Failed to publish presence on {topic}: {err}")).ok();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4,12 +4,13 @@ use async_trait::async_trait;
|
||||
use google_home::errors::ErrorCode;
|
||||
use google_home::{GoogleHomeDevice, device, types::Type, traits::{self, OnOff}};
|
||||
use rumqttc::{AsyncClient, Publish, matches};
|
||||
use tracing::{debug, trace, error};
|
||||
use tracing::{debug, trace, error, warn};
|
||||
use tokio::task::JoinHandle;
|
||||
use pollster::FutureExt as _;
|
||||
|
||||
use crate::config::{KettleConfig, InfoConfig, MqttDeviceConfig};
|
||||
use crate::devices::Device;
|
||||
use crate::error;
|
||||
use crate::mqtt::{OnMqtt, OnOffMessage};
|
||||
use crate::presence::OnPresence;
|
||||
|
||||
@@ -26,11 +27,11 @@ pub struct IkeaOutlet {
|
||||
}
|
||||
|
||||
impl IkeaOutlet {
|
||||
pub async fn new(identifier: String, info: InfoConfig, mqtt: MqttDeviceConfig, kettle: Option<KettleConfig>, client: AsyncClient) -> Self {
|
||||
pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, kettle: Option<KettleConfig>, client: AsyncClient) -> error::Result<Self> {
|
||||
// @TODO Handle potential errors here
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await.unwrap();
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?;
|
||||
|
||||
Self{ identifier, info, mqtt, kettle, client, last_known_state: false, handle: None }
|
||||
Ok(Self{ identifier: identifier.to_owned(), info, mqtt, kettle, client, last_known_state: false, handle: None })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +39,7 @@ async fn set_on(client: AsyncClient, topic: String, on: bool) {
|
||||
let message = OnOffMessage::new(on);
|
||||
|
||||
// @TODO Handle potential errors here
|
||||
client.publish(topic + "/set", rumqttc::QoS::AtLeastOnce, false, serde_json::to_string(&message).unwrap()).await.unwrap();
|
||||
client.publish(topic.clone() + "/set", rumqttc::QoS::AtLeastOnce, false, serde_json::to_string(&message).unwrap()).await.map_err(|err| warn!("Failed to update state on {topic}: {err}")).ok();
|
||||
}
|
||||
|
||||
impl Device for IkeaOutlet {
|
||||
|
||||
@@ -13,9 +13,8 @@ pub struct KasaOutlet {
|
||||
}
|
||||
|
||||
impl KasaOutlet {
|
||||
pub fn new(identifier: String, ip: Ipv4Addr) -> Self {
|
||||
// @TODO Get the current state of the outlet
|
||||
Self { identifier, addr: (ip, 9999).into() }
|
||||
pub fn new(identifier: &str, ip: Ipv4Addr) -> Self {
|
||||
Self { identifier: identifier.to_owned(), addr: (ip, 9999).into() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@ use google_home::{GoogleHomeDevice, types::Type, device, traits::{self, Scene},
|
||||
use tracing::{debug, error};
|
||||
use rumqttc::{AsyncClient, Publish, matches};
|
||||
use pollster::FutureExt as _;
|
||||
use eui48::MacAddress;
|
||||
|
||||
use crate::{config::{InfoConfig, MqttDeviceConfig}, mqtt::{OnMqtt, ActivateMessage}};
|
||||
use crate::{config::{InfoConfig, MqttDeviceConfig}, mqtt::{OnMqtt, ActivateMessage}, error};
|
||||
|
||||
use super::Device;
|
||||
|
||||
@@ -13,15 +14,15 @@ pub struct WakeOnLAN {
|
||||
identifier: String,
|
||||
info: InfoConfig,
|
||||
mqtt: MqttDeviceConfig,
|
||||
mac_address: String,
|
||||
mac_address: MacAddress,
|
||||
}
|
||||
|
||||
impl WakeOnLAN {
|
||||
pub async fn new(identifier: String, info: InfoConfig, mqtt: MqttDeviceConfig, mac_address: String, client: AsyncClient) -> Self {
|
||||
pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, mac_address: MacAddress, client: AsyncClient) -> error::Result<Self> {
|
||||
// @TODO Handle potential errors here
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await.unwrap();
|
||||
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?;
|
||||
|
||||
Self { identifier, info, mqtt, mac_address }
|
||||
Ok(Self { identifier: identifier.to_owned(), info, mqtt, mac_address })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user