diff --git a/config/ares.dev.toml b/config/ares.dev.toml index 5b90b91..53ac067 100644 --- a/config/ares.dev.toml +++ b/config/ares.dev.toml @@ -25,16 +25,25 @@ max = 25_000 [devices.kitchen_kettle] type = "IkeaOutlet" +outlet_type = "Kettle" name = "Kettle" room = "Kitchen" topic = "zigbee2mqtt/kitchen/kettle" -kettle = { timeout = 5 } +timeout = 5 -[devices.living_workbench] +[devices.workbench_charger] type = "IkeaOutlet" -name = "Workbench" -room = "Living Room" -topic = "zigbee2mqtt/living/workbench" +outlet_type = "Charger" +name = "Charger" +room = "Workbench" +topic = "zigbee2mqtt/workbench/charger" +timeout = 5 + +[devices.workbench_outlet] +type = "IkeaOutlet" +name = "Outlet" +room = "Workbench" +topic = "zigbee2mqtt/workbench/outlet" [devices.living_zeus] type = "WakeOnLAN" diff --git a/config/config.toml b/config/config.toml index 2a07110..db9df5f 100644 --- a/config/config.toml +++ b/config/config.toml @@ -24,21 +24,30 @@ topic = "automation/debug" [light_sensor] topic = "zigbee2mqtt/living/light" -min = 20_500 -max = 22_000 +min = 21_000 +max = 22_500 [devices.kitchen_kettle] type = "IkeaOutlet" +outlet_type = "Kettle" name = "Kettle" room = "Kitchen" topic = "zigbee2mqtt/kitchen/kettle" -kettle = { timeout = 300 } +timeout = 300 -[devices.living_workbench] +[devices.workbench_charger] type = "IkeaOutlet" -name = "Workbench" -room = "Living Room" -topic = "zigbee2mqtt/living/workbench" +outlet_type = "Charger" +name = "Charger" +room = "Workbench" +topic = "zigbee2mqtt/workbench/charger" +timeout = 72000 + +[devices.workbench_outlet] +type = "IkeaOutlet" +name = "Outlet" +room = "Workbench" +topic = "zigbee2mqtt/workbench/outlet" [devices.living_zeus] type = "WakeOnLAN" diff --git a/config/zeus.dev.toml b/config/zeus.dev.toml index aee1185..636b7b5 100644 --- a/config/zeus.dev.toml +++ b/config/zeus.dev.toml @@ -30,16 +30,25 @@ max = 25_000 [devices.kitchen_kettle] type = "IkeaOutlet" +outlet_type = "Kettle" name = "Kettle" room = "Kitchen" topic = "zigbee2mqtt/kitchen/kettle" -kettle = { timeout = 5 } +timeout = 5 -[devices.living_workbench] +[devices.workbench_charger] type = "IkeaOutlet" -name = "Workbench" -room = "Living Room" -topic = "zigbee2mqtt/living/workbench" +outlet_type = "Charger" +name = "Charger" +room = "Workbench" +topic = "zigbee2mqtt/workbench/charger" +timeout = 5 + +[devices.workbench_outlet] +type = "IkeaOutlet" +name = "Outlet" +room = "Workbench" +topic = "zigbee2mqtt/workbench/outlet" [devices.living_zeus] type = "WakeOnLAN" diff --git a/google-home/src/types.rs b/google-home/src/types.rs index 5ab4a93..dd8fc4e 100644 --- a/google-home/src/types.rs +++ b/google-home/src/types.rs @@ -6,6 +6,8 @@ pub enum Type { Kettle, #[serde(rename = "action.devices.types.OUTLET")] Outlet, + #[serde(rename = "action.devices.types.GRILL")] + Grill, #[serde(rename = "action.devices.types.SCENE")] Scene, } diff --git a/src/config.rs b/src/config.rs index 2068656..d4905c5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -116,6 +116,13 @@ pub struct MqttDeviceConfig { pub topic: String, } +#[derive(Debug, Clone, Deserialize)] +pub enum OutletType { + Outlet, + Kettle, + Charger, +} + #[derive(Debug, Clone, Deserialize)] pub struct KettleConfig { pub timeout: Option, // Timeout in seconds @@ -157,7 +164,9 @@ pub enum Device { info: InfoConfig, #[serde(flatten)] mqtt: MqttDeviceConfig, - kettle: Option, + #[serde(default = "default_outlet_type")] + outlet_type: OutletType, + timeout: Option, // Timeout in seconds }, WakeOnLAN { #[serde(flatten)] @@ -184,6 +193,10 @@ pub enum Device { } } +fn default_outlet_type() -> OutletType { + OutletType::Outlet +} + fn default_broadcast_ip() -> Ipv4Addr { Ipv4Addr::new(255, 255, 255, 255) } @@ -228,9 +241,9 @@ impl Device { #[async_recursion] pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result { let device = match self { - Device::IkeaOutlet { info, mqtt, kettle } => { + Device::IkeaOutlet { info, mqtt, outlet_type, timeout } => { trace!(id = identifier, "IkeaOutlet [{} in {:?}]", info.name, info.room); - IkeaOutlet::build(&identifier, info, mqtt, kettle, client).await + IkeaOutlet::build(&identifier, info, mqtt, outlet_type, timeout, client).await .map(device_box)? }, Device::WakeOnLAN { info, mqtt, mac_address, broadcast_ip } => { diff --git a/src/devices/ikea_outlet.rs b/src/devices/ikea_outlet.rs index fef07a7..4a56722 100644 --- a/src/devices/ikea_outlet.rs +++ b/src/devices/ikea_outlet.rs @@ -3,11 +3,11 @@ use async_trait::async_trait; use google_home::errors::ErrorCode; use google_home::{GoogleHomeDevice, device, types::Type, traits::{self, OnOff}}; use rumqttc::{AsyncClient, Publish, matches}; -use tracing::{debug, trace, error, warn}; +use tracing::{debug, error, warn}; use tokio::task::JoinHandle; use pollster::FutureExt as _; -use crate::config::{KettleConfig, InfoConfig, MqttDeviceConfig}; +use crate::config::{InfoConfig, MqttDeviceConfig, OutletType}; use crate::devices::Device; use crate::error::DeviceError; use crate::mqtt::{OnMqtt, OnOffMessage}; @@ -18,7 +18,8 @@ pub struct IkeaOutlet { identifier: String, info: InfoConfig, mqtt: MqttDeviceConfig, - kettle: Option, + outlet_type: OutletType, + timeout: Option, client: AsyncClient, last_known_state: bool, @@ -26,11 +27,11 @@ pub struct IkeaOutlet { } impl IkeaOutlet { - pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, kettle: Option, client: AsyncClient) -> Result { + pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, outlet_type: OutletType, timeout: Option, client: AsyncClient) -> Result { // @TODO Handle potential errors here client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?; - Ok(Self{ identifier: identifier.to_owned(), info, mqtt, kettle, client, last_known_state: false, handle: None }) + Ok(Self{ identifier: identifier.to_owned(), info, mqtt, outlet_type, timeout, client, last_known_state: false, handle: None }) } } @@ -82,17 +83,9 @@ impl OnMqtt for IkeaOutlet { // If this is a kettle start a timeout for turning it of again if state { - let kettle = match &self.kettle { - Some(kettle) => kettle, - None => return, - }; - - let timeout = match kettle.timeout.clone() { + let timeout = match self.timeout { Some(timeout) => Duration::from_secs(timeout), - None => { - trace!(id = self.identifier, "Outlet is a kettle without timeout"); - return; - }, + None => return, }; // Turn the kettle of after the specified timeout @@ -129,10 +122,10 @@ impl OnPresence for IkeaOutlet { impl GoogleHomeDevice for IkeaOutlet { fn get_device_type(&self) -> Type { - if self.kettle.is_some() { - Type::Kettle - } else { - Type::Outlet + match self.outlet_type { + OutletType::Outlet => Type::Outlet, + OutletType::Kettle => Type::Kettle, + OutletType::Charger => Type::Outlet, // Find a better device type for this, ideally would like to use charger, but that needs more work } }