87 lines
2.8 KiB
Rust
87 lines
2.8 KiB
Rust
use async_trait::async_trait;
|
|
use google_home::traits;
|
|
use rumqttc::{AsyncClient, matches};
|
|
use tracing::{error, warn, debug};
|
|
|
|
use crate::config::MqttDeviceConfig;
|
|
use crate::mqtt::{OnMqtt, RemoteMessage, RemoteAction};
|
|
use crate::presence::OnPresence;
|
|
|
|
use super::Device;
|
|
|
|
// @TODO Ideally we store am Arc to the childern devices,
|
|
// that way they hook into everything just like all other devices
|
|
#[derive(Debug)]
|
|
pub struct AudioSetup {
|
|
identifier: String,
|
|
mqtt: MqttDeviceConfig,
|
|
mixer: Box<dyn traits::OnOff + Sync + Send>,
|
|
speakers: Box<dyn traits::OnOff + Sync + Send>,
|
|
}
|
|
|
|
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();
|
|
|
|
Self { identifier, mqtt, mixer, speakers }
|
|
}
|
|
}
|
|
|
|
impl Device for AudioSetup {
|
|
fn get_id(&self) -> String {
|
|
self.identifier.clone()
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl OnMqtt for AudioSetup {
|
|
async fn on_mqtt(&mut self, message: &rumqttc::Publish) {
|
|
if !matches(&message.topic, &self.mqtt.topic) {
|
|
return;
|
|
}
|
|
|
|
let action = match RemoteMessage::try_from(message) {
|
|
Ok(message) => message.action(),
|
|
Err(err) => {
|
|
error!(id = self.identifier, "Failed to parse message: {err}");
|
|
return;
|
|
}
|
|
};
|
|
|
|
match action {
|
|
RemoteAction::On => {
|
|
if self.mixer.is_on().unwrap() {
|
|
self.speakers.set_on(false).unwrap();
|
|
self.mixer.set_on(false).unwrap();
|
|
} else {
|
|
self.speakers.set_on(true).unwrap();
|
|
self.mixer.set_on(true).unwrap();
|
|
}
|
|
},
|
|
RemoteAction::BrightnessMoveUp => {
|
|
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 {
|
|
self.speakers.set_on(true).unwrap();
|
|
}
|
|
},
|
|
RemoteAction::BrightnessStop => { /* Ignore this action */ },
|
|
_ => warn!("Expected ikea shortcut button which only supports 'on' and 'brightness_move_up', got: {action:?}")
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl OnPresence for AudioSetup {
|
|
async fn on_presence(&mut self, presence: bool) {
|
|
// Turn off the audio setup when we leave the house
|
|
if !presence {
|
|
debug!(id = self.identifier, "Turning devices off");
|
|
self.speakers.set_on(false).unwrap();
|
|
self.mixer.set_on(false).unwrap();
|
|
}
|
|
}
|
|
}
|