Naming error with Deconz and Appdaemon

@aimc @Robban

I’m having problems of using the deconz and appdaemon components together. After a google search I found out the following

The deconz components uses “event” as an parameter in event_data. Appdaemon also has “event” as a parameter for its listen_event() function. When I want to listen to a specific event of the deconz component, lets say Xiaomi button pressed, I have to use the event parameter twice, which gives an error. This is because I use “event” as a keyword argument and as a possitional argument.

My suggestion is to change the naming of “event” in event_data of the Deconz component to “event_id” (or something)
Or changing “event” to “event_name” in the listen.event() function of Appdaemon. This way it is also consistent with the naming in the Event Callback where also event_name is used

Or do you know a workaround? I’m really new in python.

Would you mind posting an example?

sure:

the listen_event function: listen_event(function, event, **kwargs)

so if I use this for the Xiaomi butten I get the following

self.listen_event(self.button_released, "deconz_event", id = "lumisensor_switch", event = 1002 )

This gives the error that the event is used twice as parameter.

I think I may have found a work around, by leaving the “event=1002” parameter out, and extracting it out of the new defined button_pressed function:

  def button_pressed(self, event_name, data, kwargs):
    self.click_type=data["event"]

Still need to test this. Hope I’m clear. As said before, I’m quite new to python

@aimc will there be any change with Appdaemon 3 or should I just bite the bullet and change the name from event?

No changes planned but I don’t want to be the bad guy and force the issue … Now in beta is a good time to make breaking changes. It’s late tonight, let me think a little and we can discuss more tomorrow.

i think that if there is an option to change names from other parties, or use other ways to avoid double names, there is no reason to create breaking changes.

there will always be third parties that use the same names, for sure when it gets to things like “events, entities, new, old, attributes, etc” in an automation development.

it could very well be that if Andrew changes it to “event_name” then some other components will get a problem, because they use event_name in stead of event.

Absolutely. It’s a mine field. And this is my own fault not thinking of it since I do use appdaemon. Just never tried events before.

I guess it might be more appropriate for me to rename the event to button_event or press or something similar

i didnt get that you are the third party :wink:
isnt that event also in the attributes?
or could you add it there?
then there wouldnt be a need for listen_event at all and noone would have to have breaking changes.

1 Like

Unfortunately no. The remotes are only exposed as events so someone have to make a change

This is the way to go I think - the filtering function of listen_event() is optional - you will still get the callback, and you simply need to use an if statement in your callback to check the id and event entries in the data parameter that AppDaemon supplies to you.

It’s a couple of lines more code, but no one has to make any breaking changes :slight_smile:

Thanks, yes I solved it, see link

Excellent!

1 Like

There is no performance penalty in this?

Not really - the filtering is just a convenience function - either way there is an if/then evaluation either implicitly in the appdaemon code if you specify the additional arguments and they match fields in the event data, or in the app where you are handed a complete set of the event data anyway.

@Try2Fly would you be willing to post a full AD example of this? Either here or as an PR for the component documentation. Would be really nice to have an AD example in the documentation.

1 Like

Yeah sure, this is a AD example that works, loosely based on this script, or do you mean a more basic version?

import appdaemon.appapi as appapi
import time

class dimming(appapi.AppDaemon):

  def initialize(self):
    self.listen_event(self.button_pressed, "deconz_event", id = "lumisensor_switch" )
    self.table_hold = False
    self.table_dim = False
  def button_pressed(self, event_name, data, kwargs):
    self.click_type=data["event"]
    if self.click_type == 1000:
      if self.table_hold == False or self.get_state("light.table") == "off":
        self.table_pressed = False
        self.toggle("light.table")
      self.table_hold = False
    if self.click_type == 1002:
      self.table_pressed = True
      time.sleep(0.3)
      self.table_hold = True
      if self.table_pressed:
        self.long_press()
        self.table_dim = not self.table_dim
     

  def long_press(self):
    if self.table_dim == False and self.table_hold == True and self.get_state("light.table") == "on":
      while self.table_hold:
        self.new_brightness = self.get_state("light.table", "brightness") + 25
        if self.new_brightness >= 255:
          self.new_brightness = 255
        self.turn_on("light.table", brightness = self.new_brightness)
      self.table_hold = False  

    elif self.table_dim == True and self.table_hold == True and self.get_state("light.table") == "on":
      while self.table_hold:
        self.new_brightness = self.get_state("light.table", "brightness") - 25
        if self.new_brightness <= 0:
          self.new_brightness = 6
        self.turn_on("light.table", brightness = self.new_brightness)
      self.table_hold = False

That works! Thanks! Do you have a config example to go with that?

what do you mean? config of the lights or button? Those are just loaded from the deconz component.

I used to toggle the light with this automation, but I couldn’t get the dimming working within yaml in a correct way.

- alias: toggle table light
  trigger:
    platform: event
    event_type: deconz_event
    event_data:
      id: lumisensor_switch
      event: 1000
  action:
    - service: light.toggle
      entity_id: light.table

btw chances are that the event codes 1000 and 1002 for pressed and released will be swapped in the next version of the deconz rest api, as this is now a pull request.

I will correct that for the example so it is default behavior for all devices.

Regarding config I mean the app daemon config for the app