Could you please help me to figure out, how to properly use “listen_state” in functions rather then initialize?!
I’m trying to start/cancel a few listen_state calls (with duration attribute) based on input_boolean state. Which is under listen_state call used in function initialize.
I saw them created, but they never call needed service.
import appdaemon.plugins.hass.hassapi as hass
import datetime
class AutoLockLocker(hass.Hass):
def initialize(self):
handles = []
self.listen_state(self.auto_lock_state, self.args["status"], handles = handles)
if self.get_state(self.args["status"]) == 'on':
notify = "NEW | Starting monitoring of lock state"
self.log_notify(notify)
def auto_lock_state(self, state, attribute, old, new, kwargs):
if new == 'on':
self.log("NEW | State of Auto Lock App is {}".format(new), "INFO")
if "locks" in self.args:
for lock in self.args["locks"]:
self.log("NEW | Monitoring ({}) for status.".format(self.friendly_name(lock["lock"])), "INFO")
for alarm_type in self.args["states"]:
self.log("NEW | State is {} for {}, time out is ({})".format(alarm_type, lock["sensor_alarm_type"], int(round(float(self.get_state(self.args["timeout"])))) ))
handle = self.listen_state(self.lock_state, lock["sensor_alarm_type"], new = alarm_type, duration = int(round(float(self.get_state(self.args["timeout"])))), lock = lock["lock"])
kwargs["handles"].append(handle)
self.log("NEW | List of handles {}".format(kwargs["handles"]))
elif new == 'off':
self.log("NEW | State of Auto Lock App is {}".format(new), "INFO")
for handle in kwargs["handles"][:]:
for mess in self.info_listen_state(handle):
self.log("TECH | {}".format(mess))
self.log("NEW | Handle {} is removed!".format(handle))
self.cancel_listen_state(handle)
kwargs["handles"].remove(handle)
self.log("NEW | Cleared list of Handles {}".format(kwargs["handles"]))
def lock_state(self, lock, attribute, old, new, kwargs):
notify = "Locking ({})".format(self.friendly_name(kwargs["lock"]))
self.log_notify(notify)
self.call_service("lock/lock", entity_id = kwargs["lock"])
user_id = 'XXXXXXXX'
msg = 'NEW | Lock was locked by TimeOut (3m)'
self.call_service('notify/telegram',
target=user_id,
message=msg,
data=dict(disable_notification=True))
def log_notify(self, message):
if "verbose_log" in self.args:
self.log(message)
if "notify" in self.args:
self.notify(message)
you are going the wrong way i think.
as i see it you want the listen states to be active when the input_boolean is on and inactive when the boolean is off.
for that Andrew created constraints.
so if you just put this part
self.log("NEW | State of Auto Lock App is {}".format(new), "INFO")
if "locks" in self.args:
for lock in self.args["locks"]:
self.log("NEW | Monitoring ({}) for status.".format(self.friendly_name(lock["lock"])), "INFO")
for alarm_type in self.args["states"]:
self.log("NEW | State is {} for {}, time out is ({})".format(alarm_type, lock["sensor_alarm_type"], int(round(float(self.get_state(self.args["timeout"])))) ))
handle = self.listen_state(self.lock_state, lock["sensor_alarm_type"], new = alarm_type, duration = int(round(float(self.get_state(self.args["timeout"])))), lock = lock["lock"])
kwargs["handles"].append(handle)
self.log("NEW | List of handles {}".format(kwargs["handles"]))
in your init and use an input_boolean constraint then it does just what you want.