From a638de42c1d7ab0d9b75c9eb253ea8e5cc356ecf Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Sat, 7 Jan 2023 05:00:59 +0100 Subject: [PATCH] AudioSetup now stores children as OnOff instead of Device as that is all that is required --- impl_cast/src/lib.rs | 9 +++++++- src/config.rs | 15 ++++++++++++- src/devices/audio_setup.rs | 45 +++++++++++++------------------------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/impl_cast/src/lib.rs b/impl_cast/src/lib.rs index c5c8235..d283aba 100644 --- a/impl_cast/src/lib.rs +++ b/impl_cast/src/lib.rs @@ -5,11 +5,15 @@ macro_rules! impl_cast { ($base:ident, $trait:ident) => { $crate::paste::paste! { pub trait [< As $trait>] { + fn consume(self: Box) -> Option>; fn cast(&self) -> Option<&dyn $trait>; fn cast_mut(&mut self) -> Option<&mut dyn $trait>; } impl [< As $trait>] for T { + default fn consume(self: Box) -> Option> { + None + } default fn cast(&self) -> Option<&dyn $trait> { None } @@ -18,7 +22,10 @@ macro_rules! impl_cast { } } - impl [< As $trait>] for T { + impl [< As $trait>] for T { + fn consume(self: Box) -> Option> { + Some(self) + } fn cast(&self) -> Option<&dyn $trait> { Some(self) } diff --git a/src/config.rs b/src/config.rs index b0082b4..e34374a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -5,7 +5,7 @@ use tracing::{debug, trace, error}; use rumqttc::{AsyncClient, has_wildcards}; use serde::Deserialize; -use crate::devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet}; +use crate::devices::{DeviceBox, IkeaOutlet, WakeOnLAN, AudioSetup, ContactSensor, KasaOutlet, AsOnOff}; // @TODO Configure more defaults @@ -223,8 +223,21 @@ impl Device { } Device::AudioSetup { mqtt, mixer, speakers } => { trace!(id = identifier, "AudioSetup [{}]", identifier); + // Create the child devices let mixer = (*mixer).into(identifier.clone() + ".mixer", config, client.clone()); let speakers = (*speakers).into(identifier.clone() + ".speakers", config, client.clone()); + + // The AudioSetup expects the children to be something that implements the OnOff trait + // So let's convert the children and make sure OnOff is implemented + let mixer = match AsOnOff::consume(mixer) { + Some(mixer) => mixer, + None => todo!("Handle this properly"), + }; + let speakers = match AsOnOff::consume(speakers) { + Some(speakers) => speakers, + None => todo!("Handle this properly"), + }; + Box::new(AudioSetup::new(identifier, mqtt, mixer, speakers, client)) }, Device::ContactSensor { mqtt, mut presence } => { diff --git a/src/devices/audio_setup.rs b/src/devices/audio_setup.rs index dd8f866..f674453 100644 --- a/src/devices/audio_setup.rs +++ b/src/devices/audio_setup.rs @@ -1,22 +1,22 @@ +use google_home::traits; use rumqttc::{AsyncClient, matches}; use tracing::{error, warn}; use pollster::FutureExt as _; use crate::config::MqttDeviceConfig; -use crate::devices::AsOnOff; use crate::mqtt::{OnMqtt, RemoteMessage, RemoteAction}; -use super::{Device, DeviceBox}; +use super::Device; pub struct AudioSetup { identifier: String, mqtt: MqttDeviceConfig, - mixer: DeviceBox, - speakers: DeviceBox, + mixer: Box, + speakers: Box, } impl AudioSetup { - pub fn new(identifier: String, mqtt: MqttDeviceConfig, mixer: DeviceBox, speakers: DeviceBox, client: AsyncClient) -> Self { + pub fn new(identifier: String, mqtt: MqttDeviceConfig, mixer: Box, speakers: Box, client: AsyncClient) -> Self { client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).block_on().unwrap(); Self { identifier, mqtt, mixer, speakers } @@ -43,38 +43,23 @@ impl OnMqtt for AudioSetup { } }; - let mixer = match AsOnOff::cast_mut(self.mixer.as_mut()) { - Some(mixer) => mixer, - None => { - error!(id = self.identifier, "Mixer device '{}' does not implement OnOff trait", self.mixer.get_id()); - return; - }, - }; - let speakers = match AsOnOff::cast_mut(self.speakers.as_mut()) { - Some(speakers) => speakers, - None => { - error!(id = self.identifier, "Speakers device '{}' does not implement OnOff trait", self.mixer.get_id()); - return; - }, - }; - match action { RemoteAction::On => { - if mixer.is_on().unwrap() { - speakers.set_on(false).unwrap(); - mixer.set_on(false).unwrap(); + if self.mixer.is_on().unwrap() { + self.speakers.set_on(false).unwrap(); + self.mixer.set_on(false).unwrap(); } else { - speakers.set_on(true).unwrap(); - mixer.set_on(true).unwrap(); + self.speakers.set_on(true).unwrap(); + self.mixer.set_on(true).unwrap(); } }, RemoteAction::BrightnessMoveUp => { - if !mixer.is_on().unwrap() { - mixer.set_on(true).unwrap(); - } else if speakers.is_on().unwrap() { - speakers.set_on(false).unwrap(); + if !self.mixer.is_on().unwrap() { + self.mixer.set_on(true).unwrap(); + } else if self.speakers.is_on().unwrap() { + self.speakers.set_on(false).unwrap(); } else { - speakers.set_on(true).unwrap(); + self.speakers.set_on(true).unwrap(); } }, RemoteAction::BrightnessStop => { /* Ignore this action */ },