Scheduler error

I’m getting the following error when an event scheduled with run_in tries to fire. Fair notice, this event has a several values being passed through kwargs.

2017-04-08 20:46:11.118393 WARNING ------------------------------------------------------------
2017-04-08 20:46:11.118971 WARNING Unexpected error during exec_schedule() for App: light_control
2017-04-08 20:46:11.119657 WARNING Args: {'name': 'light_control', 'type': None, 'offset': 0, 'basetime': 1491702372, 'id': UUID('8e010d93-ef24-420b-9571-6983c4ebfd6f'), 'callback': <bound method light_control.timer_handler of <light_control.light_control object at 0x70141e10>>, 'repeat': False, 'timestamp': 1491702372, 'interval': 0, 'kwargs': {'trigger': 'switch.master_toilet_light', 'entity': 'switch.master_toilet_fan', 'trigger_state': 'off', 'state': 'off'}}
2017-04-08 20:46:11.120115 WARNING ------------------------------------------------------------
2017-04-08 20:46:11.120780 WARNING Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/appdaemon/appdaemon.py", line 391, in exec_schedule
    "attribute": args["kwargs"]["attribute"],
KeyError: 'attribute'
2017-04-08 20:46:11.121223 WARNING ------------------------------------------------------------
2017-04-08 20:46:11.121988 WARNING Scheduler entry has been deleted
2017-04-08 20:46:11.122354 WARNING ------------------------------------------------------------
2017-04-08 20:28:17.128735 WARNING ------------------------------------------------------------
2017-04-08 20:28:17.129556 WARNING Scheduler entry has been deleted
2017-04-08 20:28:17.130086 WARNING ------------------------------------------------------------

Here is the calling section of code.

  if onoff=="off":
    self.log("turning off {} in {} seconds onoff={} trigger={}  trigger_state={}".format(light,seconds,onoff,trigger,trigger_state))
    self.run_in(self.timer_handler,seconds,entity=light,state=onoff,trigger=trigger,trigger_state=trigger_state)
  elif onoff=="on":
    self.log("turning on {} in {} seconds onoff={} trigger={}  trigger_state={}".format(light,seconds,onoff,trigger,trigger_state))
    self.run_in(self.timer_handler,seconds,entity=light,state=onoff,trigger=trigger,trigger_state=trigger_state)
  else:
    self.log("invalid value for on/off - {}".format(onoff))

Here is the callback function

  def timer_handler(self,kwargs):
    self.log("in timer_handler")
    for a in kwargs:
      self.log("{} = {}".format(a,kwargs[a]))
    if "trigger" in kwargs:
      if not kwargs["trigger_state"]==self.get_state(kwargs["trigger"],attribute="state"):
        self.log("trigger {} state changed not turning {} {}".format(kwargs["trigger"],kwargs["light_entity"],kwargs["state"]))
        return

    if kwargs["state"]=="on":
      self.turn_on(kwargs["light_entity"])
    else:
      self.turn_off(kwargs["light_entity"])

I never even get the “in timer_handler” log message so I don’t believe it’s getting into the handler.

Here is the message log

2017-04-08 20:45:41.790957 INFO light_control: set_light_state - (126) turning off switch.master_toilet_fan in 30 seconds onoff=off trigger=switch.master_toilet_light  trigger_state=off

2017-04-08 20:46:11.121613 WARNING Logged an error to /home/homeassistant/appdaemon/appdaemon.err

Any ideas?

Yes, you are running into a collision with one of the parameter names - I really should document these and/or change them to less obvious values.

For now, change your parameter entity to something else and it should fix the issue.

3 Likes

That got it. Thanks

I am having a similar problem…could it be I don’t understand how to use kwargs? or how to read errors?
Here is my code:

import appdaemon.plugins.hass.hassapi as hass
import base64

class testing(hass.Hass):
    def initialize(self):
        self.listen_state(self.turn_on_front_outside_lights,"sensor.backyard_motion", new="test")
    def turn_on_front_outside_lights(self, entity, attribute, old, new, kwargs):
                self.turn_on("light.level_8", brightness = "120")
                self.run_in(self.timer_handler, 60, entity = "light.level_8" )
                self.log("light.level_8 on")
    def timer_handler(self, kwargs):
        self.log(kwargs)
        self.turn_off(kwargs)
        self.log("light.level_8 will be off in 60 seconds")

My log

2018-06-04 13:28:30.012768 WARNING AppDaemon: ------------------------------------------------------------
pi@hassbian:/home/homeassistant/conf $ tail error.log
2018-06-04 13:37:30.007469 WARNING AppDaemon: Args: {'name': 'test_motion_sensor', 'interval': 0, 'kwargs': {'**entity': 'light.level_8**'}, 'type': None, 'callback': <bound method testing.timer_handler of <test.testing object at 0x68742c30>>, 'offset': 0, 'timestamp': 1528144650, 'id': UUID('445d6e6f-5f3c-40f2-a76d-f26a102f7895'), 'basetime': 1528144650, 'repeat': False}
2018-06-04 13:37:30.008206 WARNING AppDaemon: ------------------------------------------------------------
2018-06-04 13:37:30.009487 WARNING AppDaemon: Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/appdaemon.py", line 816, in exec_schedule
    "attribute": args["kwargs"]["attribute"],
KeyError: 'attribute'

2018-06-04 13:37:30.010214 WARNING AppDaemon: ------------------------------------------------------------
2018-06-04 13:37:30.011023 WARNING AppDaemon: Scheduler entry has been deleted
2018-06-04 13:37:30.011704 WARNING AppDaemon: ------------------------------------------------------------

I change “entity” to “my_entity” and here are the results.

pi@hassbian:/home/homeassistant/conf $ tail error.log
    self.turn_off(kwargs)
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/plugins/hass/hassapi.py", line 22, in func_wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/plugins/hass/hassapi.py", line 334, in turn_off
    self._check_entity(self._get_namespace(**kwargs), entity_id)
  File "/usr/local/lib/python3.5/dist-packages/appdaemon/appapi.py", line 65, in _check_entity
    "{}: Invalid entity ID: {}".format(self.name, entity))
ValueError: test_motion_sensor: Invalid entity ID: {'myentity': 'light.level_8'}

2018-06-04 13:41:46.012741 WARNING AppDaemon: ------------------------------------------------------------

kwargs is a dictionary, containing an entry ‘myentity’. So to use it you need

self.turn_off(kwargs['myentity'])
2 Likes

Thank you very much. I have been trying to get my head around the kwarg concept and for some reason it is not sinking in too quickly. I made the changes you suggested and it is working now.

2018-06-04 14:56:28.115479 INFO test_motion_sensor: light.level_8 will be off in 60 seconds
class testing(hass.Hass):
    def initialize(self):
        self.listen_state(self.turn_on_front_outside_lights,"sensor.backyard_motion", new="test")
    def turn_on_front_outside_lights(self, entity, attribute, old, new, kwargs):
                self.turn_on("light.level_8", brightness = '120')
                self.run_in(self.timer_handler, 60, myentity = "light.level_8" )
                self.log("light.level_8 on")
    def timer_handler(self, kwargs):
        self.log(kwargs)
        self.turn_off(kwargs['myentity'])
        self.log(kwargs['myentity'] + " will be off in 60 seconds")

Thanks again!:blush:

1 Like