AudioSetup now stores children as OnOff instead of Device as that is all that is required

This commit is contained in:
Dreaded_X 2023-01-07 05:00:59 +01:00
parent 8bc203cb2d
commit a638de42c1
3 changed files with 37 additions and 32 deletions

View File

@ -5,11 +5,15 @@ macro_rules! impl_cast {
($base:ident, $trait:ident) => {
$crate::paste::paste! {
pub trait [< As $trait>] {
fn consume(self: Box<Self>) -> Option<Box<dyn $trait + Sync + Send>>;
fn cast(&self) -> Option<&dyn $trait>;
fn cast_mut(&mut self) -> Option<&mut dyn $trait>;
}
impl<T: $base> [< As $trait>] for T {
default fn consume(self: Box<Self>) -> Option<Box<dyn $trait + Sync + Send>> {
None
}
default fn cast(&self) -> Option<&dyn $trait> {
None
}
@ -18,7 +22,10 @@ macro_rules! impl_cast {
}
}
impl<T: $base + $trait> [< As $trait>] for T {
impl<T: $base + $trait + Sync + Send + 'static> [< As $trait>] for T {
fn consume(self: Box<Self>) -> Option<Box<dyn $trait + Sync + Send>> {
Some(self)
}
fn cast(&self) -> Option<&dyn $trait> {
Some(self)
}

View File

@ -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 } => {

View File

@ -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<dyn traits::OnOff + Sync + Send>,
speakers: Box<dyn traits::OnOff + Sync + Send>,
}
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<dyn traits::OnOff + Sync + Send>, speakers: Box<dyn traits::OnOff + Sync + Send>, 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 */ },