hass-appdaemon/apps/evening_mode_lighting.py

96 lines
3.7 KiB
Python
Raw Permalink Normal View History

2024-07-08 23:14:29 +00:00
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