Added trait for devices that can turn off a given timeout

This commit is contained in:
Dreaded_X 2023-08-14 02:58:13 +02:00
parent e38c5eed31
commit 12ca577a65
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
4 changed files with 42 additions and 24 deletions

View File

@ -20,6 +20,7 @@ use crate::event::EventChannel;
use crate::event::OnMqtt; use crate::event::OnMqtt;
use crate::event::OnPresence; use crate::event::OnPresence;
use crate::messages::OnOffMessage; use crate::messages::OnOffMessage;
use crate::traits::Timeout;
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Copy)] #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Copy)]
pub enum OutletType { pub enum OutletType {
@ -50,7 +51,7 @@ pub struct IkeaOutlet {
info: InfoConfig, info: InfoConfig,
mqtt: MqttDeviceConfig, mqtt: MqttDeviceConfig,
outlet_type: OutletType, outlet_type: OutletType,
timeout: Option<u64>, timeout: Option<Duration>,
client: AsyncClient, client: AsyncClient,
last_known_state: bool, last_known_state: bool,
@ -81,7 +82,7 @@ impl CreateDevice for IkeaOutlet {
info: config.info, info: config.info,
mqtt: config.mqtt, mqtt: config.mqtt,
outlet_type: config.outlet_type, outlet_type: config.outlet_type,
timeout: config.timeout, timeout: config.timeout.map(Duration::from_secs),
client: client.clone(), client: client.clone(),
last_known_state: false, last_known_state: false,
handle: None, handle: None,
@ -142,27 +143,8 @@ impl OnMqtt for IkeaOutlet {
self.last_known_state = state; self.last_known_state = state;
// If this is a kettle start a timeout for turning it of again // If this is a kettle start a timeout for turning it of again
if state { if state && let Some(timeout) = self.timeout {
let timeout = match self.timeout { self.start_timeout(timeout);
Some(timeout) => Duration::from_secs(timeout),
None => return,
};
// Turn the kettle of after the specified timeout
// TODO: Impl Drop for IkeaOutlet that will abort the handle if the IkeaOutlet
// get dropped
let client = self.client.clone();
let topic = self.mqtt.topic.clone();
let id = self.identifier.clone();
self.handle = Some(tokio::spawn(async move {
debug!(id, "Starting timeout ({timeout:?})...");
tokio::time::sleep(timeout).await;
debug!(id, "Turning outlet off!");
// TODO: Idealy we would call self.set_on(false), however since we want to do
// it after a timeout we have to put it in a seperate task.
// I don't think we can really get around calling outside function
set_on(client, &topic, false).await;
}));
} }
} }
} }
@ -222,3 +204,28 @@ impl traits::OnOff for IkeaOutlet {
Ok(()) Ok(())
} }
} }
impl crate::traits::Timeout for IkeaOutlet {
fn start_timeout(&mut self, timeout: Duration) {
// Abort any timer that is currently running
if let Some(handle) = self.handle.take() {
handle.abort();
}
// Turn the kettle of after the specified timeout
// TODO: Impl Drop for IkeaOutlet that will abort the handle if the IkeaOutlet
// get dropped
let client = self.client.clone();
let topic = self.mqtt.topic.clone();
let id = self.identifier.clone();
self.handle = Some(tokio::spawn(async move {
debug!(id, "Starting timeout ({timeout:?})...");
tokio::time::sleep(timeout).await;
debug!(id, "Turning outlet off!");
// TODO: Idealy we would call self.set_on(false), however since we want to do
// it after a timeout we have to put it in a seperate task.
// I don't think we can really get around calling outside function
set_on(client, &topic, false).await;
}));
}
}

View File

@ -22,9 +22,10 @@ pub use self::wake_on_lan::WakeOnLAN;
use google_home::{device::AsGoogleHomeDevice, traits::OnOff}; use google_home::{device::AsGoogleHomeDevice, traits::OnOff};
use crate::traits::Timeout;
use crate::{event::OnDarkness, event::OnMqtt, event::OnNotification, event::OnPresence}; use crate::{event::OnDarkness, event::OnMqtt, event::OnNotification, event::OnPresence};
#[impl_cast::device(As: OnMqtt + OnPresence + OnDarkness + OnNotification + OnOff)] #[impl_cast::device(As: OnMqtt + OnPresence + OnDarkness + OnNotification + OnOff + Timeout)]
pub trait Device: AsGoogleHomeDevice + std::fmt::Debug + Sync + Send { pub trait Device: AsGoogleHomeDevice + std::fmt::Debug + Sync + Send {
fn get_id(&self) -> &str; fn get_id(&self) -> &str;
} }

View File

@ -1,5 +1,6 @@
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![feature(specialization)] #![feature(specialization)]
#![feature(let_chains)]
pub mod auth; pub mod auth;
pub mod config; pub mod config;
pub mod device_manager; pub mod device_manager;
@ -8,3 +9,4 @@ pub mod error;
pub mod event; pub mod event;
pub mod messages; pub mod messages;
pub mod mqtt; pub mod mqtt;
pub mod traits;

8
src/traits.rs Normal file
View File

@ -0,0 +1,8 @@
use std::time::Duration;
use impl_cast::device_trait;
#[device_trait]
pub trait Timeout {
fn start_timeout(&mut self, _timeout: Duration) {}
}