How to use listen_state call not in initialization func?

HI,

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.

Thank you in advance,
Alex

why do you want it in another function?
if you share your code we could look at what you might be doing wrong.

1 Like

Thank you!

Here you can find the settings and code

#####################################################################################################
###   AUTO LOCKER   ####################################################################   LOCK   ###
#####################################################################################################
auto_locker:
  module: auto_lock
  class: AutoLockLocker
  locks:
    - lock: lock.kwikset_touchpad_electronic_deadbolt_locked
      sensor_alarm_type: sensor.kwikset_touchpad_electronic_deadbolt_alarm_type
      sensor_alarm_level: sensor.kwikset_touchpad_electronic_deadbolt_alarm_level
      sensor: binary_sensor.door_window_sensor_158d000XXXXXXX
  states:
    - 19
    - 22
    - 25
  timeout: input_number.auto_lock_timeout
  status: input_boolean.auto_lock_status
  verbose_log: True
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.

1 Like

@ReneTode Thank you!

1 Like