This commit is contained in:
@@ -7,7 +7,7 @@ use rumqttc::{AsyncClient, has_wildcards};
|
||||
use serde::Deserialize;
|
||||
use eui48::MacAddress;
|
||||
|
||||
use crate::{devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet}, error::{FailedToParseConfig, MissingEnv, MissingWildcard, Error, FailedToCreateDevice}};
|
||||
use crate::{devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet, self}, error::{FailedToParseConfig, MissingEnv, MissingWildcard, Error, FailedToCreateDevice}};
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
@@ -132,7 +132,7 @@ pub struct PresenceDeviceConfig {
|
||||
|
||||
impl PresenceDeviceConfig {
|
||||
/// Set the mqtt topic to an appropriate value if it is not already set
|
||||
fn generate_topic(&mut self, class: &str, identifier: &str, config: &Config) -> Result<(), MissingWildcard> {
|
||||
fn generate_topic(mut self, class: &str, identifier: &str, config: &Config) -> Result<PresenceDeviceConfig, MissingWildcard> {
|
||||
if self.mqtt.is_none() {
|
||||
if !has_wildcards(&config.presence.topic) {
|
||||
return Err(MissingWildcard::new(&config.presence.topic).into());
|
||||
@@ -145,7 +145,7 @@ impl PresenceDeviceConfig {
|
||||
self.mqtt = Some(MqttDeviceConfig { topic });
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,23 +213,27 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
// Quick helper function to box up the devices,
|
||||
// passing in Box::new would be ideal, however the return type is incorrect
|
||||
// Maybe there is a better way to solve this?
|
||||
fn device_box<T: devices::Device + 'static>(device: T) -> DeviceBox {
|
||||
let a: DeviceBox = Box::new(device);
|
||||
a
|
||||
}
|
||||
|
||||
impl Device {
|
||||
#[async_recursion]
|
||||
pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result<DeviceBox, FailedToCreateDevice> {
|
||||
let device: Result<DeviceBox, Error> = match self {
|
||||
Device::IkeaOutlet { info, mqtt, kettle } => {
|
||||
trace!(id = identifier, "IkeaOutlet [{} in {:?}]", info.name, info.room);
|
||||
match IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await {
|
||||
Ok(device) => Ok(Box::new(device)),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await
|
||||
.map(device_box)
|
||||
},
|
||||
Device::WakeOnLAN { info, mqtt, mac_address } => {
|
||||
trace!(id = identifier, "WakeOnLan [{} in {:?}]", info.name, info.room);
|
||||
match WakeOnLAN::build(&identifier, info, mqtt, mac_address, client).await {
|
||||
Ok(device) => Ok(Box::new(device)),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
WakeOnLAN::build(&identifier, info, mqtt, mac_address, client).await
|
||||
.map(device_box)
|
||||
},
|
||||
Device::KasaOutlet { ip } => {
|
||||
trace!(id = identifier, "KasaOutlet [{}]", identifier);
|
||||
@@ -243,22 +247,18 @@ impl Device {
|
||||
let speakers_id = identifier.to_owned() + ".speakers";
|
||||
let speakers = (*speakers).create(&speakers_id, config, client.clone()).await?;
|
||||
|
||||
match AudioSetup::build(&identifier, mqtt, mixer, speakers, client).await {
|
||||
Ok(device) => Ok(Box::new(device)),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
AudioSetup::build(&identifier, mqtt, mixer, speakers, client).await
|
||||
.map(device_box)
|
||||
},
|
||||
Device::ContactSensor { mqtt, mut presence } => {
|
||||
Device::ContactSensor { mqtt, presence } => {
|
||||
trace!(id = identifier, "ContactSensor [{}]", identifier);
|
||||
if let Some(presence) = &mut presence {
|
||||
presence.generate_topic("contact", &identifier, &config)
|
||||
.map_err(|err| FailedToCreateDevice::new(&identifier, err.into()))?;
|
||||
}
|
||||
let presence = presence
|
||||
.map(|p| p.generate_topic("contact", &identifier, &config))
|
||||
.transpose()
|
||||
.map_err(|err| FailedToCreateDevice::new(&identifier, err.into()))?;
|
||||
|
||||
match ContactSensor::build(&identifier, mqtt, presence, client).await {
|
||||
Ok(device) => Ok(Box::new(device)),
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
ContactSensor::build(&identifier, mqtt, presence, client).await
|
||||
.map(device_box)
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user