From 74568b4e1fe5b076ae60dd7dbb348e953c784b05 Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Sun, 31 Aug 2025 22:10:41 +0200 Subject: [PATCH] Handle turning off devices when away through lua --- automation_devices/src/hue_bridge.rs | 9 ------- automation_devices/src/kasa_outlet.rs | 13 +-------- automation_devices/src/zigbee/light.rs | 12 +-------- automation_devices/src/zigbee/outlet.rs | 16 +---------- config.lua | 35 ++++++++++++++++++++----- 5 files changed, 31 insertions(+), 54 deletions(-) diff --git a/automation_devices/src/hue_bridge.rs b/automation_devices/src/hue_bridge.rs index 8f431ff..e981259 100644 --- a/automation_devices/src/hue_bridge.rs +++ b/automation_devices/src/hue_bridge.rs @@ -3,7 +3,6 @@ use std::net::SocketAddr; use async_trait::async_trait; use automation_lib::device::{Device, LuaDeviceCreate}; -use automation_lib::event::OnPresence; use automation_lib::lua::traits::AddAdditionalMethods; use automation_macro::{LuaDevice, LuaDeviceConfig}; use mlua::LuaSerdeExt; @@ -110,11 +109,3 @@ impl AddAdditionalMethods for HueBridge { ); } } - -#[async_trait] -impl OnPresence for HueBridge { - async fn on_presence(&self, presence: bool) { - trace!("Bridging presence to hue"); - self.set_flag(Flag::Presence, presence).await; - } -} diff --git a/automation_devices/src/kasa_outlet.rs b/automation_devices/src/kasa_outlet.rs index a480213..301c728 100644 --- a/automation_devices/src/kasa_outlet.rs +++ b/automation_devices/src/kasa_outlet.rs @@ -4,7 +4,6 @@ use std::str::Utf8Error; use async_trait::async_trait; use automation_lib::device::{Device, LuaDeviceCreate}; -use automation_lib::event::OnPresence; use automation_macro::{LuaDevice, LuaDeviceConfig}; use bytes::{Buf, BufMut}; use google_home::errors::{self, DeviceError}; @@ -13,7 +12,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; -use tracing::{debug, trace}; +use tracing::trace; #[derive(Debug, Clone, LuaDeviceConfig)] pub struct Config { @@ -276,13 +275,3 @@ impl OnOff for KasaOutlet { .or(Err(DeviceError::TransientError.into())) } } - -#[async_trait] -impl OnPresence for KasaOutlet { - async fn on_presence(&self, presence: bool) { - if !presence { - debug!(id = Device::get_id(self), "Turning device off"); - self.set_on(false).await.ok(); - } - } -} diff --git a/automation_devices/src/zigbee/light.rs b/automation_devices/src/zigbee/light.rs index 64157dd..7b5e427 100644 --- a/automation_devices/src/zigbee/light.rs +++ b/automation_devices/src/zigbee/light.rs @@ -7,7 +7,7 @@ use async_trait::async_trait; use automation_lib::action_callback::ActionCallback; use automation_lib::config::{InfoConfig, MqttDeviceConfig}; use automation_lib::device::{Device, LuaDeviceCreate}; -use automation_lib::event::{OnMqtt, OnPresence}; +use automation_lib::event::OnMqtt; use automation_lib::helpers::serialization::state_deserializer; use automation_lib::mqtt::WrappedAsyncClient; use automation_macro::{LuaDevice, LuaDeviceConfig}; @@ -251,16 +251,6 @@ impl OnMqtt for Light { } } -#[async_trait] -impl OnPresence for Light { - async fn on_presence(&self, presence: bool) { - if !presence { - debug!(id = Device::get_id(self), "Turning device off"); - self.set_on(false).await.ok(); - } - } -} - #[async_trait] impl google_home::Device for Light { fn get_device_type(&self) -> Type { diff --git a/automation_devices/src/zigbee/outlet.rs b/automation_devices/src/zigbee/outlet.rs index 3b69cca..47bdab6 100644 --- a/automation_devices/src/zigbee/outlet.rs +++ b/automation_devices/src/zigbee/outlet.rs @@ -7,7 +7,7 @@ use async_trait::async_trait; use automation_lib::action_callback::ActionCallback; use automation_lib::config::{InfoConfig, MqttDeviceConfig}; use automation_lib::device::{Device, LuaDeviceCreate}; -use automation_lib::event::{OnMqtt, OnPresence}; +use automation_lib::event::OnMqtt; use automation_lib::helpers::serialization::state_deserializer; use automation_lib::mqtt::WrappedAsyncClient; use automation_macro::{LuaDevice, LuaDeviceConfig}; @@ -50,10 +50,6 @@ pub struct Config { #[device_config(default(OutletType::Outlet))] pub outlet_type: OutletType, - // TODO: One presence is reworked, this should be removed! - #[device_config(default(true))] - pub presence_auto_off: bool, - #[device_config(from_lua, default)] pub callback: ActionCallback, T>, @@ -202,16 +198,6 @@ impl OnMqtt for Outlet { } } -#[async_trait] -impl OnPresence for Outlet { - async fn on_presence(&self, presence: bool) { - if self.config.presence_auto_off && !presence { - debug!(id = Device::get_id(self), "Turning device off"); - self.set_on(false).await.ok(); - } - } -} - #[async_trait] impl google_home::Device for Outlet { fn get_device_type(&self) -> Type { diff --git a/config.lua b/config.lua index 6979b72..0b1f597 100644 --- a/config.lua +++ b/config.lua @@ -77,6 +77,14 @@ on_presence:add(function(presence) }) end) +local function turn_off_when_away(device) + on_presence:add(function(presence) + if not presence then + device:set_on(false) + end + end) +end + local on_light = { add = function(self, f) self[#self + 1] = f @@ -119,6 +127,9 @@ automation.device_manager:add(hue_bridge) on_light:add(function(light) hue_bridge:set_flag("darkness", not light) end) +on_presence:add(function(presence) + hue_bridge:set_flag("presence", presence) +end) local kitchen_lights = HueGroup.new({ identifier = "kitchen_lights", @@ -176,6 +187,7 @@ local living_mixer = OutletOnOff.new({ topic = mqtt_z2m("living/mixer"), client = mqtt_client, }) +turn_off_when_away(living_mixer) automation.device_manager:add(living_mixer) local living_speakers = OutletOnOff.new({ name = "Speakers", @@ -183,6 +195,7 @@ local living_speakers = OutletOnOff.new({ topic = mqtt_z2m("living/speakers"), client = mqtt_client, }) +turn_off_when_away(living_speakers) automation.device_manager:add(living_speakers) automation.device_manager:add(IkeaRemote.new({ @@ -232,6 +245,7 @@ local kettle = OutletPower.new({ client = mqtt_client, callback = kettle_timeout(), }) +turn_off_when_away(kettle) automation.device_manager:add(kettle) local function set_kettle(_, on) @@ -270,13 +284,14 @@ local function off_timeout(duration) end end -automation.device_manager:add(LightOnOff.new({ +local bathroom_light = LightOnOff.new({ name = "Light", room = "Bathroom", topic = mqtt_z2m("bathroom/light"), client = mqtt_client, callback = off_timeout(debug and 60 or 45 * 60), -})) +}) +automation.device_manager:add(bathroom_light) automation.device_manager:add(Washer.new({ identifier = "bathroom_washer", @@ -294,7 +309,6 @@ automation.device_manager:add(Washer.new({ })) automation.device_manager:add(OutletOnOff.new({ - presence_auto_off = false, name = "Charger", room = "Workbench", topic = mqtt_z2m("workbench/charger"), @@ -302,12 +316,14 @@ automation.device_manager:add(OutletOnOff.new({ callback = off_timeout(debug and 5 or 20 * 3600), })) -automation.device_manager:add(OutletOnOff.new({ +local workbench_outlet = OutletOnOff.new({ name = "Outlet", room = "Workbench", topic = mqtt_z2m("workbench/outlet"), client = mqtt_client, -})) +}) +turn_off_when_away(workbench_outlet) +automation.device_manager:add(workbench_outlet) local workbench_light = LightColorTemperature.new({ name = "Light", @@ -315,6 +331,7 @@ local workbench_light = LightColorTemperature.new({ topic = mqtt_z2m("workbench/light"), client = mqtt_client, }) +turn_off_when_away(workbench_light) automation.device_manager:add(workbench_light) local delay_color_temp = Timeout.new() @@ -417,6 +434,7 @@ local hallway_storage = LightBrightness.new({ hallway_light_automation:light_callback(state.state) end, }) +turn_off_when_away(hallway_storage) automation.device_manager:add(hallway_storage) local hallway_bottom_lights = HueGroup.new({ @@ -478,12 +496,14 @@ local hallway_trash = ContactSensor.new({ automation.device_manager:add(hallway_trash) hallway_light_automation.trash = hallway_trash -automation.device_manager:add(LightOnOff.new({ +local guest_light = LightOnOff.new({ name = "Light", room = "Guest Room", topic = mqtt_z2m("guest/light"), client = mqtt_client, -})) +}) +turn_off_when_away(guest_light) +automation.device_manager:add(guest_light) local bedroom_air_filter = AirFilter.new({ name = "Air Filter", @@ -554,6 +574,7 @@ local storage_light = LightBrightness.new({ topic = mqtt_z2m("storage/light"), client = mqtt_client, }) +turn_off_when_away(storage_light) automation.device_manager:add(storage_light) automation.device_manager:add(ContactSensor.new({