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]
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"

View File

@ -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"

View File

@ -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"

View File

@ -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,
}

View File

@ -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<u64>, // Timeout in seconds
@ -157,7 +164,9 @@ pub enum Device {
info: InfoConfig,
#[serde(flatten)]
mqtt: MqttDeviceConfig,
kettle: Option<KettleConfig>,
#[serde(default = "default_outlet_type")]
outlet_type: OutletType,
timeout: Option<u64>, // 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<DeviceBox, DeviceCreationError> {
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 } => {

View File

@ -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<KettleConfig>,
outlet_type: OutletType,
timeout: Option<u64>,
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<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
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
}
}