Added charger as outlet type
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Dreaded_X 2023-03-19 22:34:26 +01:00
parent 18bca5abf4
commit 07563a6d30
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
6 changed files with 74 additions and 39 deletions

View File

@ -25,16 +25,25 @@ max = 25_000
[devices.kitchen_kettle] [devices.kitchen_kettle]
type = "IkeaOutlet" type = "IkeaOutlet"
outlet_type = "Kettle"
name = "Kettle" name = "Kettle"
room = "Kitchen" room = "Kitchen"
topic = "zigbee2mqtt/kitchen/kettle" topic = "zigbee2mqtt/kitchen/kettle"
kettle = { timeout = 5 } timeout = 5
[devices.living_workbench] [devices.workbench_charger]
type = "IkeaOutlet" type = "IkeaOutlet"
name = "Workbench" outlet_type = "Charger"
room = "Living Room" name = "Charger"
topic = "zigbee2mqtt/living/workbench" room = "Workbench"
topic = "zigbee2mqtt/workbench/charger"
timeout = 5
[devices.workbench_outlet]
type = "IkeaOutlet"
name = "Outlet"
room = "Workbench"
topic = "zigbee2mqtt/workbench/outlet"
[devices.living_zeus] [devices.living_zeus]
type = "WakeOnLAN" type = "WakeOnLAN"

View File

@ -24,21 +24,30 @@ topic = "automation/debug"
[light_sensor] [light_sensor]
topic = "zigbee2mqtt/living/light" topic = "zigbee2mqtt/living/light"
min = 20_500 min = 21_000
max = 22_000 max = 22_500
[devices.kitchen_kettle] [devices.kitchen_kettle]
type = "IkeaOutlet" type = "IkeaOutlet"
outlet_type = "Kettle"
name = "Kettle" name = "Kettle"
room = "Kitchen" room = "Kitchen"
topic = "zigbee2mqtt/kitchen/kettle" topic = "zigbee2mqtt/kitchen/kettle"
kettle = { timeout = 300 } timeout = 300
[devices.living_workbench] [devices.workbench_charger]
type = "IkeaOutlet" type = "IkeaOutlet"
name = "Workbench" outlet_type = "Charger"
room = "Living Room" name = "Charger"
topic = "zigbee2mqtt/living/workbench" room = "Workbench"
topic = "zigbee2mqtt/workbench/charger"
timeout = 72000
[devices.workbench_outlet]
type = "IkeaOutlet"
name = "Outlet"
room = "Workbench"
topic = "zigbee2mqtt/workbench/outlet"
[devices.living_zeus] [devices.living_zeus]
type = "WakeOnLAN" type = "WakeOnLAN"

View File

@ -30,16 +30,25 @@ max = 25_000
[devices.kitchen_kettle] [devices.kitchen_kettle]
type = "IkeaOutlet" type = "IkeaOutlet"
outlet_type = "Kettle"
name = "Kettle" name = "Kettle"
room = "Kitchen" room = "Kitchen"
topic = "zigbee2mqtt/kitchen/kettle" topic = "zigbee2mqtt/kitchen/kettle"
kettle = { timeout = 5 } timeout = 5
[devices.living_workbench] [devices.workbench_charger]
type = "IkeaOutlet" type = "IkeaOutlet"
name = "Workbench" outlet_type = "Charger"
room = "Living Room" name = "Charger"
topic = "zigbee2mqtt/living/workbench" room = "Workbench"
topic = "zigbee2mqtt/workbench/charger"
timeout = 5
[devices.workbench_outlet]
type = "IkeaOutlet"
name = "Outlet"
room = "Workbench"
topic = "zigbee2mqtt/workbench/outlet"
[devices.living_zeus] [devices.living_zeus]
type = "WakeOnLAN" type = "WakeOnLAN"

View File

@ -6,6 +6,8 @@ pub enum Type {
Kettle, Kettle,
#[serde(rename = "action.devices.types.OUTLET")] #[serde(rename = "action.devices.types.OUTLET")]
Outlet, Outlet,
#[serde(rename = "action.devices.types.GRILL")]
Grill,
#[serde(rename = "action.devices.types.SCENE")] #[serde(rename = "action.devices.types.SCENE")]
Scene, Scene,
} }

View File

@ -116,6 +116,13 @@ pub struct MqttDeviceConfig {
pub topic: String, pub topic: String,
} }
#[derive(Debug, Clone, Deserialize)]
pub enum OutletType {
Outlet,
Kettle,
Charger,
}
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct KettleConfig { pub struct KettleConfig {
pub timeout: Option<u64>, // Timeout in seconds pub timeout: Option<u64>, // Timeout in seconds
@ -157,7 +164,9 @@ pub enum Device {
info: InfoConfig, info: InfoConfig,
#[serde(flatten)] #[serde(flatten)]
mqtt: MqttDeviceConfig, mqtt: MqttDeviceConfig,
kettle: Option<KettleConfig>, #[serde(default = "default_outlet_type")]
outlet_type: OutletType,
timeout: Option<u64>, // Timeout in seconds
}, },
WakeOnLAN { WakeOnLAN {
#[serde(flatten)] #[serde(flatten)]
@ -184,6 +193,10 @@ pub enum Device {
} }
} }
fn default_outlet_type() -> OutletType {
OutletType::Outlet
}
fn default_broadcast_ip() -> Ipv4Addr { fn default_broadcast_ip() -> Ipv4Addr {
Ipv4Addr::new(255, 255, 255, 255) Ipv4Addr::new(255, 255, 255, 255)
} }
@ -228,9 +241,9 @@ impl Device {
#[async_recursion] #[async_recursion]
pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result<DeviceBox, DeviceCreationError> { pub async fn create(self, identifier: &str, config: &Config, client: AsyncClient) -> Result<DeviceBox, DeviceCreationError> {
let device = match self { 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); 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)? .map(device_box)?
}, },
Device::WakeOnLAN { info, mqtt, mac_address, broadcast_ip } => { Device::WakeOnLAN { info, mqtt, mac_address, broadcast_ip } => {

View File

@ -3,11 +3,11 @@ use async_trait::async_trait;
use google_home::errors::ErrorCode; use google_home::errors::ErrorCode;
use google_home::{GoogleHomeDevice, device, types::Type, traits::{self, OnOff}}; use google_home::{GoogleHomeDevice, device, types::Type, traits::{self, OnOff}};
use rumqttc::{AsyncClient, Publish, matches}; use rumqttc::{AsyncClient, Publish, matches};
use tracing::{debug, trace, error, warn}; use tracing::{debug, error, warn};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
use pollster::FutureExt as _; use pollster::FutureExt as _;
use crate::config::{KettleConfig, InfoConfig, MqttDeviceConfig}; use crate::config::{InfoConfig, MqttDeviceConfig, OutletType};
use crate::devices::Device; use crate::devices::Device;
use crate::error::DeviceError; use crate::error::DeviceError;
use crate::mqtt::{OnMqtt, OnOffMessage}; use crate::mqtt::{OnMqtt, OnOffMessage};
@ -18,7 +18,8 @@ pub struct IkeaOutlet {
identifier: String, identifier: String,
info: InfoConfig, info: InfoConfig,
mqtt: MqttDeviceConfig, mqtt: MqttDeviceConfig,
kettle: Option<KettleConfig>, outlet_type: OutletType,
timeout: Option<u64>,
client: AsyncClient, client: AsyncClient,
last_known_state: bool, last_known_state: bool,
@ -26,11 +27,11 @@ pub struct IkeaOutlet {
} }
impl IkeaOutlet { impl IkeaOutlet {
pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, kettle: Option<KettleConfig>, client: AsyncClient) -> Result<Self, DeviceError> { pub async fn build(identifier: &str, info: InfoConfig, mqtt: MqttDeviceConfig, outlet_type: OutletType, timeout: Option<u64>, client: AsyncClient) -> Result<Self, DeviceError> {
// @TODO Handle potential errors here // @TODO Handle potential errors here
client.subscribe(mqtt.topic.clone(), rumqttc::QoS::AtLeastOnce).await?; 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 this is a kettle start a timeout for turning it of again
if state { if state {
let kettle = match &self.kettle { let timeout = match self.timeout {
Some(kettle) => kettle,
None => return,
};
let timeout = match kettle.timeout.clone() {
Some(timeout) => Duration::from_secs(timeout), Some(timeout) => Duration::from_secs(timeout),
None => { None => return,
trace!(id = self.identifier, "Outlet is a kettle without timeout");
return;
},
}; };
// Turn the kettle of after the specified timeout // Turn the kettle of after the specified timeout
@ -129,10 +122,10 @@ impl OnPresence for IkeaOutlet {
impl GoogleHomeDevice for IkeaOutlet { impl GoogleHomeDevice for IkeaOutlet {
fn get_device_type(&self) -> Type { fn get_device_type(&self) -> Type {
if self.kettle.is_some() { match self.outlet_type {
Type::Kettle OutletType::Outlet => Type::Outlet,
} else { OutletType::Kettle => Type::Kettle,
Type::Outlet OutletType::Charger => Type::Outlet, // Find a better device type for this, ideally would like to use charger, but that needs more work
} }
} }