first sleep switch implementation
This commit is contained in:
@@ -1,30 +1,137 @@
|
||||
import appdaemon.plugins.hass.hassapi as hass
|
||||
from smartswitch import SmartSwitch
|
||||
import ad_toolbox.smartcondition as SmartCondition
|
||||
from ad_toolbox.eventhandler import EventHandler
|
||||
|
||||
# =============================================================================
|
||||
# SmartLight — Light-specific extension of SmartSwitch
|
||||
# =============================================================================
|
||||
# Adds brightness control and smooth transitions on top of all SmartSwitch
|
||||
# features. Use this class instead of SmartSwitch when the entity is a light.
|
||||
#
|
||||
# Inherits all SmartObject and SmartSwitch YAML keys.
|
||||
# The "entity" key is required and must refer to a light entity.
|
||||
#
|
||||
# YAML CONFIGURATION
|
||||
# ------------------
|
||||
#
|
||||
# brightness_pct_step: <int> # optional, default 5
|
||||
# Step size (% of full brightness) used by increase/decrease events.
|
||||
#
|
||||
# increase_brightness_events: # optional
|
||||
# <EventHandler events_block>
|
||||
# HA events that increase brightness by brightness_pct_step.
|
||||
# Has no effect while the light is off.
|
||||
#
|
||||
# decrease_brightness_events: # optional
|
||||
# <EventHandler events_block>
|
||||
# HA events that decrease brightness by brightness_pct_step.
|
||||
# Has no effect while the light is off.
|
||||
#
|
||||
# on_events_with_transition: # optional
|
||||
# <label>:
|
||||
# events:
|
||||
# <EventHandler events_block>
|
||||
# brightness_pct: <0-100>
|
||||
# Target brightness level.
|
||||
# transition_time: <seconds>
|
||||
# Duration of the ramp from 1 % to brightness_pct.
|
||||
# Turns the light on with a smooth ramp-up. Multiple labelled
|
||||
# transitions can be defined (e.g. "dim", "full").
|
||||
#
|
||||
# light_brightness_pct: # optional
|
||||
# always_change_brightness: true|false # optional, default false
|
||||
# When true, apply the resolved brightness even if the light
|
||||
# is currently off. When false, only apply it while on.
|
||||
# <label>:
|
||||
# <SmartCondition block>
|
||||
# The condition value (label) is used directly as the brightness
|
||||
# percentage when the condition succeeds.
|
||||
# Conditions are evaluated in declaration order; the first
|
||||
# Succeeded result wins.
|
||||
# Dynamically sets the brightness based on conditions. When the
|
||||
# active condition changes, the new brightness is applied
|
||||
# immediately (subject to always_change_brightness).
|
||||
# Note: brightness 0 also calls light/turn_off for compatibility
|
||||
# with integrations that do not honour brightness = 0.
|
||||
#
|
||||
# icon_override: # optional
|
||||
# on_icon: <mdi:icon>
|
||||
# off_icon: <mdi:icon>
|
||||
# dest_entities: <entity_id | list of entity_ids>
|
||||
# Updates the icon attribute on dest_entities whenever the light
|
||||
# turns on or off. Useful for dashboard button cards.
|
||||
#
|
||||
# EXAMPLE YAML
|
||||
# ------------
|
||||
# living_light:
|
||||
# module: smartlight
|
||||
# class: SmartLight
|
||||
# entity: light.living_room
|
||||
#
|
||||
# brightness_pct_step: 10
|
||||
#
|
||||
# increase_brightness_events:
|
||||
# btn_up:
|
||||
# event_name: WALL_SWITCH
|
||||
# event_data: {action: brightness_up}
|
||||
# decrease_brightness_events:
|
||||
# btn_down:
|
||||
# event_name: WALL_SWITCH
|
||||
# event_data: {action: brightness_down}
|
||||
#
|
||||
# on_events_with_transition:
|
||||
# dim:
|
||||
# events:
|
||||
# btn:
|
||||
# event_name: WALL_SWITCH
|
||||
# event_data: {action: dim}
|
||||
# brightness_pct: 20
|
||||
# transition_time: 5
|
||||
#
|
||||
# light_brightness_pct:
|
||||
# always_change_brightness: false
|
||||
# "10":
|
||||
# trigger:
|
||||
# condition: sensor.lux > 500
|
||||
# "60":
|
||||
# trigger:
|
||||
# condition: sensor.lux > 100
|
||||
# "100":
|
||||
# trigger:
|
||||
# condition: "true"
|
||||
#
|
||||
# icon_override:
|
||||
# on_icon: mdi:lightbulb
|
||||
# off_icon: mdi:lightbulb-outline
|
||||
# dest_entities: sensor.living_room_button
|
||||
# =============================================================================
|
||||
|
||||
class SmartLight(SmartSwitch):
|
||||
|
||||
#@SmartCondition.catch_smartcondition_exception(lambda self, message: self.log_error(message,stop_app = True))
|
||||
def on_initialize_smart_object(self):
|
||||
# light_brightness_pct_list : ordered list of (Evaluator, label) pairs
|
||||
# light_brightness_pct : currently active brightness % (str label)
|
||||
self.light_brightness_pct_list = list()
|
||||
self.light_brightness_pct = None
|
||||
|
||||
super().on_initialize_smart_object()
|
||||
|
||||
# increase/decrease brightness step events
|
||||
if "increase_brightness_events" in self.args:
|
||||
self.register_event_from_yaml(self.args["increase_brightness_events"],self.on_increase_brightness_event)
|
||||
self.event_handlers.append(EventHandler(self, self.args["increase_brightness_events"], self.on_increase_brightness_event))
|
||||
if "decrease_brightness_events" in self.args:
|
||||
self.register_event_from_yaml(self.args["decrease_brightness_events"],self.on_decrease_brightness_event)
|
||||
self.event_handlers.append(EventHandler(self, self.args["decrease_brightness_events"], self.on_decrease_brightness_event))
|
||||
|
||||
if "brightness_pct_step" in self.args:
|
||||
self.brightness_pct_step = self.args["brightness_pct_step"]
|
||||
else: self.brightness_pct_step = 5
|
||||
|
||||
# on_events_with_transition: one EventHandler per labelled transition
|
||||
if "on_events_with_transition" in self.args:
|
||||
for key in self.args["on_events_with_transition"]:
|
||||
#self.log(f"{key}")
|
||||
self.register_event_from_yaml(self.args["on_events_with_transition"][key]["events"],self.on_turn_on_with_transition,key)
|
||||
self.event_handlers.append(EventHandler(self, self.args["on_events_with_transition"][key]["events"], self.on_turn_on_with_transition, key))
|
||||
|
||||
# light_brightness_pct: build ordered evaluator list, run initial pass
|
||||
if "light_brightness_pct" in self.args:
|
||||
self.always_change_brightness = False
|
||||
|
||||
@@ -37,6 +144,8 @@ class SmartLight(SmartSwitch):
|
||||
|
||||
self.listen_state(self.on_state_change,self.entity_id)
|
||||
|
||||
# listen_state callback on self.entity_id. Applies icon_override when
|
||||
# the light turns on or off.
|
||||
def on_state_change(self, entity, attribute, old, new, *kwargs):
|
||||
if "icon_override" in self.args:
|
||||
override_data = self.args['icon_override']
|
||||
@@ -50,21 +159,35 @@ class SmartLight(SmartSwitch):
|
||||
update_icon(override_data['dest_entities'],new)
|
||||
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Brightness event callbacks
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
# Increase brightness by brightness_pct_step while the light is on.
|
||||
def on_increase_brightness_event(self, event_name, data, kwargs):
|
||||
if self.get_state(self.entity_id) != 'off':
|
||||
self.call_service("light/turn_on", entity_id = self.entity_id, brightness_step_pct = self.brightness_pct_step)
|
||||
|
||||
# Decrease brightness by brightness_pct_step while the light is on.
|
||||
def on_decrease_brightness_event(self, event_name, data, kwargs):
|
||||
if self.get_state(self.entity_id) != 'off':
|
||||
self.call_service("light/turn_on", entity_id = self.entity_id, brightness_step_pct = -self.brightness_pct_step)
|
||||
|
||||
def on_turn_on_with_transition(self, event_name, data, kwargs,event_category):
|
||||
# EventHandler callback for on_events_with_transition. Jumps to 1 %
|
||||
# first so the ramp always starts from a known low level, then
|
||||
# transitions to the configured brightness over transition_time seconds.
|
||||
def on_turn_on_with_transition(self, event_name, data, kwargs, event_category):
|
||||
transition_time = self.args["on_events_with_transition"][event_category]["transition_time"]
|
||||
brightness_pct = self.args["on_events_with_transition"][event_category]["brightness_pct"]
|
||||
self.log(f"Turn on at {brightness_pct}% with a transition of {transition_time}s")
|
||||
self.call_service("light/turn_on", entity_id = self.entity_id,brightness_pct = 1)
|
||||
self.call_service("light/turn_on", entity_id = self.entity_id, transition = transition_time,brightness_pct = brightness_pct)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# SmartSwitch overrides
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
# Override: apply light_brightness_pct when turning on, if one is active.
|
||||
def switch_on(self):
|
||||
if self.light_brightness_pct != None:
|
||||
self.log(f"Turn on {self.entity_id} at {self.light_brightness_pct}%")
|
||||
@@ -72,6 +195,10 @@ class SmartLight(SmartSwitch):
|
||||
else:
|
||||
super().switch_on()
|
||||
|
||||
# on_update_cb for all light_brightness_pct evaluators. Walks the list
|
||||
# in order and applies the first Succeeded result. Pushes the new
|
||||
# brightness to the light if it is on (or always_change_brightness=true).
|
||||
# Brightness 0 additionally calls light/turn_off for compatibility.
|
||||
def on_update_light_brightness_pct(self):
|
||||
for brightness_pct_evaluator in self.light_brightness_pct_list:
|
||||
if brightness_pct_evaluator[0].evaluate(False) == SmartCondition.Result.Succeeded:
|
||||
|
||||
Reference in New Issue
Block a user