Add evening mode light dimming
This commit is contained in:
parent
91b0a86744
commit
047e4fd8b5
@ -4,9 +4,20 @@ scene_retry:
|
|||||||
class: SceneRetry
|
class: SceneRetry
|
||||||
single_scene: true
|
single_scene: true
|
||||||
|
|
||||||
snoo_mqtt:
|
evening_mode_lighting:
|
||||||
module: snoo_mqtt
|
module: evening_mode_lighting
|
||||||
class: SnooMQTT
|
class: EveningModeLighting
|
||||||
username: !secret snoo_username
|
target_brightness: 20
|
||||||
password: !secret snoo_password
|
target_color_temp: 443
|
||||||
token_path: /config/apps/snoo_token.json
|
evening_mode_entity: input_boolean.evening_mode
|
||||||
|
exclude_entities:
|
||||||
|
- light.bedroom
|
||||||
|
|
||||||
|
|
||||||
|
# snoo_mqtt:
|
||||||
|
# module: snoo_mqtt
|
||||||
|
# class: SnooMQTT
|
||||||
|
# username: !secret snoo_username
|
||||||
|
# password: !secret snoo_password
|
||||||
|
# token_path: /config/apps/snoo_token.json
|
||||||
|
# polling: false
|
||||||
|
95
apps/evening_mode_lighting.py
Normal file
95
apps/evening_mode_lighting.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
import appdaemon.plugins.hass.hassapi as hass
|
||||||
|
|
||||||
|
|
||||||
|
class EveningModeLighting(hass.Hass):
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
self.set_log_level("DEBUG")
|
||||||
|
# Read configuration
|
||||||
|
self.target_brightness = self.args["target_brightness"]
|
||||||
|
self.target_color_temp = self.args["target_color_temp"]
|
||||||
|
self.evening_mode_entity = self.args["evening_mode_entity"]
|
||||||
|
self.exclude_entities = self.args.get("exclude_entities", [])
|
||||||
|
self.light_listeners: list[str] = []
|
||||||
|
|
||||||
|
# Listen to changes in the evening mode toggle
|
||||||
|
self.listen_state(self.evening_mode_change, self.evening_mode_entity)
|
||||||
|
|
||||||
|
# Initialize based on current state of evening mode
|
||||||
|
if self.get_state(self.evening_mode_entity) == "on":
|
||||||
|
self.setup_listeners()
|
||||||
|
|
||||||
|
def evening_mode_change(self, entity, attribute, old, new, kwargs):
|
||||||
|
if new == "on":
|
||||||
|
self.setup_listeners()
|
||||||
|
else:
|
||||||
|
self.teardown_listeners()
|
||||||
|
|
||||||
|
def setup_listeners(self):
|
||||||
|
# Get all light entities and filter out the excluded ones and those that don't support dimming
|
||||||
|
all_light_entities = self.get_state("light")
|
||||||
|
|
||||||
|
# Set up listeners for light state changes
|
||||||
|
self.light_listeners = []
|
||||||
|
for light in all_light_entities:
|
||||||
|
if (
|
||||||
|
light in self.exclude_entities
|
||||||
|
or not self.supports_dimming(light)
|
||||||
|
or self.is_group(light)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
listener = self.listen_state(self.light_state_change, light)
|
||||||
|
self.log(
|
||||||
|
"Listening to light events for %s: %s", light, listener, level="INFO"
|
||||||
|
)
|
||||||
|
self.light_listeners.append(listener)
|
||||||
|
|
||||||
|
self.log("Listening to %d lights", len(self.light_listeners))
|
||||||
|
|
||||||
|
def teardown_listeners(self):
|
||||||
|
# Cancel all light state listeners
|
||||||
|
for listener in self.light_listeners:
|
||||||
|
self.cancel_listen_state(listener)
|
||||||
|
self.log("Canceled light event listener: %s", listener, level="INFO")
|
||||||
|
self.light_listeners = []
|
||||||
|
|
||||||
|
def light_state_change(self, entity, attribute, old, new, kwargs):
|
||||||
|
# Check if the light is being turned on
|
||||||
|
if old in ("off", "unavailable") and new == "on":
|
||||||
|
# Get the brightness attribute of the light
|
||||||
|
brightness = self.get_state(entity, attribute="brightness")
|
||||||
|
brightness_pct = int(brightness / 255 * 100)
|
||||||
|
|
||||||
|
# Check if the brightness exceeds the target value
|
||||||
|
if brightness_pct and brightness_pct > self.target_brightness:
|
||||||
|
self.log("Dimming light %s", entity, level="INFO")
|
||||||
|
# Dim the light to the target brightness
|
||||||
|
self.turn_on(
|
||||||
|
entity,
|
||||||
|
brightness_pct=self.target_brightness,
|
||||||
|
color_temp=self.target_color_temp,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.log("Light state changed, but no action: entity=%s, old=%s, new=%s", entity, old, new)
|
||||||
|
|
||||||
|
def is_group(self, entity) -> bool:
|
||||||
|
# Check if the light entity is a group
|
||||||
|
attributes = self.get_state(entity, attribute="attributes")
|
||||||
|
if attributes.get("is_hue_group", False) or attributes.get("entity_id", []):
|
||||||
|
self.log(
|
||||||
|
"Skipping light entity %s because it's a group", entity, level="DEBUG"
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def supports_dimming(self, entity):
|
||||||
|
# Check if the light entity supports dimming
|
||||||
|
if self.get_state(entity, attribute="supported_features", default=0):
|
||||||
|
return True
|
||||||
|
|
||||||
|
self.log(
|
||||||
|
"Skipping light entity %s because it doesn't support dimming",
|
||||||
|
entity,
|
||||||
|
level="DEBUG",
|
||||||
|
)
|
||||||
|
return False
|
Loading…
Reference in New Issue
Block a user