mqtt improvements to sleep setter

This commit is contained in:
John Lancaster
2023-11-24 21:37:54 -06:00
parent d5e1cb174d
commit 525b519433
2 changed files with 62 additions and 21 deletions

View File

@@ -1,26 +1,26 @@
from appdaemon.entity import Entity
from appdaemon.plugins.hass import hassapi as hass
from appdaemon.plugins.hass.hassapi import Hass
from appdaemon.plugins.mqtt.mqttapi import Mqtt
import json
class SleepSetter(hass.Hass):
class SleepSetter(Hass, Mqtt):
def initialize(self):
assert self.entity_exists(entity_id=self.variable), f'{self.variable} does not exist'
self.variable_entity.listen_state(callback=self.handle_state)
if isinstance(self.button, list):
for button in self.button:
self.listen_event(self.handle_button, event='deconz_event', id=button)
self.setup_button(button)
else:
self.listen_event(self.handle_button, event='deconz_event', id=self.button)
self.variable_entity.listen_state(callback=self.handle_state)
self.setup_button(button)
self.log(f'{self.variable} can be set using {self.button}, currently {self.state}')
def handle_state(self, entity, attribute, old, new, kwargs):
self.log(f'{entity}: {old} -> {new}')
if self.state and self.sun_elevation < float(self.args['elevation_limit']):
self.all_off()
self.turn_on(self.scene)
def setup_button(self, name: str):
topic = f'zigbee2mqtt/{name}'
self.mqtt_subscribe(topic, namespace='mqtt')
self.listen_event(self.handle_button, "MQTT_MESSAGE", topic=topic, namespace='mqtt', button=name)
self.log(f'Listening for sleep setting on {name}')
@property
def button(self) -> str:
@@ -53,20 +53,57 @@ class SleepSetter(hass.Hass):
@property
def sun_elevation(self) -> float:
try:
return float(self.get_state('sun.sun', 'elevation'))
except:
self.log(f'Failed to return sun elevation')
return
def handle_state(self, entity, attribute, old, new, kwargs):
self.log(f'{entity}: {old} -> {new}')
if self.state and self.sun_elevation < float(self.args['elevation_limit']):
self.all_off()
try:
self.call_service('scene/turn_on', entity_id=self.scene)
except:
return
else:
self.log(f'Turned on scene: {self.scene}')
# self.turn_on(self.scene)
def handle_button(self, event_name, data, kwargs):
topic = data['topic']
# self.log(f'Button event for: {topic}')
if (elev := self.sun_elevation) < 0:
# long-press down
if data['event'] == 1001:
self.state = True
try:
payload = json.loads(data['payload'])
action = payload['action']
except json.JSONDecodeError:
self.log(f'Error decoding JSON from {data["payload"]}', level='ERROR')
except KeyError as e:
return
else:
self.handle_action(action)
# long-press up
# if data['event'] == 1003:
# self.state = True
else:
self.log(f'Ignoring event because sun elevation {elev} > 0')
def handle_action(self, action: str):
if action == '':
return
elif action == 'hold':
self.state = True
elif action == 'double':
self.state = not self.state
if (on_apps := self.args.get('on_apps', None)) is not None:
for app_name in on_apps:
try:
self.get_app(app_name).activate()
except:
return
else:
self.log(f'Activated {app_name}')
def all_off(self):
self.log(f'Deactivating apps')
for app_name in self.args['off_apps']:

View File

@@ -2,7 +2,7 @@ sleep:
module: sleep
class: SleepSetter
elevation_limit: -10
scene: in_bed
scene: scene.in_bed
variable: input_boolean.sleeping
button:
- Bedroom Button 1
@@ -13,6 +13,10 @@ sleep:
- living_room
- kitchen
- bathroom
- closet
off_entities:
- light.patio
- light.closet
on_apps:
- living_room
- bedroom