ControllerX. Bring full functionality to light and media player controllers

First off great project!

I think I can do this myself based of the existing code, but a thought for a feature request. Custom Integration option?

One of my use cases is I use Lutron Pico remotes using the lutron-caseta-pro custom component, which pushes the pico button presses to sensors. What I was thinking was using automations to fire events based on the sensor changes. I could get press and release events for each button as the sensor. I could fake this by making the events match a current integration in the code, but was wondering if a custom integration method would make more sense. I know dimming from the Lutron Pico’s comes up from time to time on the forums.

Hi @tube0013,

First of all, thanks for the appreciation. If I understand correctly the lutron-caseta-pro maps the button states into sensors. I see that when no button is pressed the state of the sensor is 0, but when is pressed, it follows this mapping and then go back to 0. If this is correct, you will need to listen for states, which is what z2m integration does already. However, I think is a good idea to create a custom integration where you can set if you are listening for state or event and in case of event, what type of event, etc. I will consider this as a feature request, but in the meantime, the z2m integration should do the work.

I just released a beta version v2.3.0b2 with support to custom controllers, so you can map the button states to actions through yaml configuration. You can check the documentation for it in here. If you have any questions or you need help with the configuration, you can just sent a PM :slight_smile:

thanks, I roll with ZHA mainly, so did not look into how the z2m integration worked, I will take a look!

1 Like

I’m using the one with “on/off” buttons with z2m and it works fine.

1 Like

@xaviml I set up a custom controller like this:

  module: controllerx
  class: CustomLightController
  controller: sensor.den_pico_den_srairs
  integration: z2m
  light: light.den_recessed_lights
  mapping:
    1: on_full_brightness
    4: off
    0: release
    8: click_brightness_up
    16: click_brightness_down 

I get this in the appdaemon log:

2020-02-19 04:01:42.376908 INFO AppDaemon: Initializing app pico_app using class CustomLightController from module controllerx

I can see the state changes for my sensor in HA, but don’t get any dimming/on/off.


I confirmed that the issue is the raw numbers as the state of the sensor - I set up some rest_commands to create a new sensor via HA rest api based on the numeric values and using that as the sensor it works as expected.

Since the remove returns to 0 after a press, is there any way to register holds, in addition to clicks? I’m able to use a hold or a click but not both. I guess that would need some logic to differentiate the click vs the hold.

Hi @tube0013,

Could it be that the state number are actually strings and not numbers? Could you try:

module: controllerx
class: CustomLightController
controller: sensor.den_pico_den_srairs
integration: z2m
light: light.den_recessed_lights
mapping:
  "1": on_full_brightness
  "4": "off"
  "0": release
  "8": click_brightness_up
  "16": click_brightness_down 

I also quoted “off” otherwise it gets parsed as a false value.

I am afraid this is not possible. This is a problem of the custom component, it should send a different state for click than hold, the same that z2m, deconz and zha does.

I don’t understand. I installed this via HACS.
Then I made new file: .homeassistant\appdaemon\apps\apps.yaml

livingroom_controller:
  module: controllerx
  class: E1810Controller
  controller: sensor.0x000d6ffffe54fd83_action
  integration: z2m
  light: light.0x00124b001ba6f59b_light

kitchen_controller:
  module: controllerx
  class: E1810Controller
  controller: sensor.0x000d6ffffe09fda2_action
  integration: z2m
  light: light.0x00124b001ba6d8d7_light

But nothing.

Nothing happens, when I press the buttons. There is no entities named: kitchen_controller or livingroom_controller.

Do I need to add something to configuration.yaml, or how does it know to search for apps.yaml?

Hi @valexi,

Did you install AppDaemon addon? You will need to install AppDaemon addon and then place that in the apps.yaml. You can check more about it in here.

Estimado @xaviml :
He instalado el controller de Ikea E1810 configurado mediante el Sniffer USB ConBee2 (deconz) en HA. Mediante Automations y Scenes lo he conseguido hacer funcionar, pero no lo logro con tu ControllerX v2.2.1 que he instalado desde HACS.

Dentro del directorio config de HA, he entrado a la carpeta appdaemon y ahí dentro hice “sudo nano apps.yaml” y configuré lo siguiente:

Luz_Mesa_Comedor_controller_IKEA_E1810:
  module: controllerx
  class: E1810Controller
  controller: controller_ikea
  integration: deconz
  light: light.mesa_comedor
  constrain_input_boolean: light.mesa_comedor
  manual_steps: 10

Mi intención es subirle / bajarle el brillo y la temperatura Kelvin con dicho controller de IKEA, pero no lo logro. ¿Que me he dejado?

En el siguiente apartardo de tu doku dices que es necesario estraer el controller parmeter:
https://xaviml.github.io/controllerx/how-to/extract-controller-id concretamente cuando dices " you will need to copy the id inside the data object."

Cuando sigo tus pasos me aparecen las siguientes dos ID:


{
    "event_type": "deconz_event",
    "data": {
        "id": "controller_ikea",
        "unique_id": "00:0d:6f:ff:fe:4f:23:e1",
        "event": 3002

Entiendo que te refieres a que debemos copiar la “unique_id” porque la “id” a secas es el nombre que le hemos puesto al controller dentro de HA

Gracias de antemano y felicidades por este fabuloso trabajo!!!

Hola @Carlos_Luis,

Primero de todo, has instalado el addon de AppDaemon? ControllerX se ejecuta por encima de AppDaemon. Puedes leer más sobre ello aquí. Una vez instalado entonces puedes copiar la configuración que mencionas.

Segundo, la configuración que has pasado está bien excepto el constrain_input_boolean que no te hace falta. Tu configuración quedaría:

Luz_Mesa_Comedor_controller_IKEA_E1810:
  module: controllerx
  class: E1810Controller
  controller: controller_ikea
  integration: deconz
  light: light.mesa_comedor

Por último, ya has hecho bien, lo importante es el id y no el unique_id cuando se integra con deconz.

Espero que te haya ayudado,
Un saludo,
Xavi M.

@xaviml Thanks! I thought that HACS appdaemon enable would get thing going, but I was wrong.
I have now installed AppDaemon, but still there is some errors:

root@odroid:~/appdaemon# sudo systemctl status [email protected][email protected] - AppDaemon
   Loaded: loaded (/etc/systemd/system/[email protected]; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2020-02-21 10:27:29 UTC; 7s ago
 Main PID: 31340 (appdaemon)
   CGroup: /system.slice/system-appdaemon.slice/[email protected]
           └─31340 /usr/bin/python3.7 /usr/local/bin/appdaemon -c /home/homeassistant/.homeassistant/appdaemon

Feb 21 10:27:33 odroid appdaemon[31340]:     self.AD, name, self.AD.logging, app_args, self.AD.config, self.app_config, self.AD.global_vars
Feb 21 10:27:33 odroid appdaemon[31340]:   File "/usr/local/lib/python3.7/dist-packages/appdaemon/plugins/hass/hassapi.py", line 46, in __init__
Feb 21 10:27:33 odroid appdaemon[31340]:     adbase.ADBase.__init__(self, ad, name, logging, args, config, app_config, global_vars)
Feb 21 10:27:33 odroid appdaemon[31340]:   File "/usr/local/lib/python3.7/dist-packages/appdaemon/adbase.py", line 75, in __init__
Feb 21 10:27:33 odroid appdaemon[31340]:     self.dashboard_dir = self.AD.http.dashboard_dir
Feb 21 10:27:33 odroid appdaemon[31340]: AttributeError: 'NoneType' object has no attribute 'dashboard_dir'
Feb 21 10:27:33 odroid appdaemon[31340]: 2020-02-21 12:27:33.131138 WARNING kitchen_controller: ------------------------------------------------------------
Feb 21 10:27:33 odroid appdaemon[31340]: 2020-02-21 12:27:33.134127 WARNING AppDaemon: Unable to find module livingroom_controller - initialize() skipped
Feb 21 10:27:33 odroid appdaemon[31340]: 2020-02-21 12:27:33.135644 WARNING AppDaemon: Unable to find module kitchen_controller - initialize() skipped
Feb 21 10:27:33 odroid appdaemon[31340]: 2020-02-21 12:27:33.136702 INFO AppDaemon: App initialization complete

Estimado @xaviml :

muchas gracias por la celeridad en tu respuesta. Efectivamente había pasado por alto el tener que instalar el Add-On Appdaemon. Pensé que con instalar desde HACS tu “script” era suficiente.

En mi caso no sería un Add-On como tal porque tengo HomeAssitant (no Hassio) corriendo bajo docker, por lo que debo instalar el “AppDaemon” como contenedor.

Con la intención de lograrlo he seguido los pasos de esta fuente: https://www.wouterbulten.nl/blog/tech/home-automation-setup-docker-compose/#appdaemon

Tengo el contenedor docker AppDaemon levantado y corriendo:

Mi docker-compose.yaml;

appdaemon:
  container_name: appdaemon
  restart: unless-stopped
  image: acockburn/appdaemon:latest
  environment:
    HA_URL: "3.0.0.232:8123"
    TOKEN: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eXXXXXXXXXXXXXX (ejemplo)"
    DASH_URL: "3.0.0.232:5050"
  ports:
    - "5050:5050"
  volumes:
    # Set which local directory will contain all your app daemon configuration
    - /home/luiscarlos/dockerdisco2/volumes/AppDaemon/conf:/conf

Pero me da los siguientes errores:

AppDaemon_docker01

El fichero de configuración “appdaemon.yaml” lo tengo así:

appdaemon:
  plugins:
    HASS:
      type: hass
      ha_url: 3.0.0.232:8123
      token: <My HA Token>
http:
  url: 3.0.0.232:5050
admin:
api:
hadashboard:

¿Me falta algo por cumplimentar?
Entiendo que debería poder acceder a la URL 3.0.0.55:5050 (en mi caso) para poder gestionar algo, ¿es correcto?

Por último, en cuanto los “Warning”:

2020-02-21 10:43:48.390268 ERROR AppDaemon: time_zone not specified in appdaemon.cfg
2020-02-21 10:43:48.390319 ERROR AppDaemon: latitude not specified in appdaemon.cfg
2020-02-21 10:43:48.390365 ERROR AppDaemon: longitude not specified in appdaemon.cfg
2020-02-21 10:43:48.390417 ERROR AppDaemon: elevation not specified in appdaemon.cfg

Tampoco he encontrado el el fichero appdaemon.cfg, me gustaría por lo menos configurar la zona horaria para evitar posibles problemas, entiendo que la latitud, longitud y altura no son tan relevantes.

Mil gracias de antemano.

I was able to get it to work. Here is example of my appdaemon.yaml

appdaemon:
  threads: 10
  plugins:
    HASS:
      type: hass
      ha_url: https://<yourip>:<port>
      token: <your secret token>
  latitude: <your lat>
  longitude: <your long>
  elevation: 59
  time_zone: Europe/Helsinki
http:
  url: http://localhost:5050
admin:
1 Like

Dear @valexi thanks for your answer. Are you running HA under docker as well?
I’m still running HA locally so everything runs under http instead https for me right now: http://MyLocal_IP:8123.

My config file “appdaemon.yaml” removes automatically the “http://” in front of my local IP, so my file looks like this after copy and paste the example of your “appdaemon.yaml”:


appdaemon:
  threads: 10
  plugins:
    HASS:
      type: hass
      ha_url: 3.0.0.232:8123
      token: <MY TOKEN >
  latitude: 40.4165001
  longitude: -3.7025599
  elevation: 667
  time_zone: Europe/Madrid
http:
  url: 3.0.0.232:5050
admin:

Unfortunately I0m getting now the following errors:

2020-02-21 14:31:26.552842 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.552957 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.553151 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.553234 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.553334 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.553491 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.553592 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.553769 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.553851 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.553960 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.554146 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.554256 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.554437 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.554520 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.554615 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.554764 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.554866 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.555039 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.555120 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.555215 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.555364 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.555466 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.555656 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.555746 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.555843 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.556007 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.556116 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.556292 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.556374 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.556470 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.556622 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.556724 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.556903 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.556985 WARNING AppDaemon: Unexpected error during process_event()


2020-02-21 14:31:26.557081 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.557236 WARNING AppDaemon: Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/events.py", line 208, in process_event


    await self.AD.http.stream_update(namespace, mydata)


  File "/usr/local/lib/python3.8/site-packages/appdaemon/http.py", line 657, in stream_update


    self.AD.thread_async.call_async_no_wait(self.stream.send_update, data)


AttributeError: 'HTTP' object has no attribute 'stream'




2020-02-21 14:31:26.557336 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.557494 WARNING AppDaemon: ------------------------------------------------------------


2020-02-21 14:31:26.557599 WARNING AppDaemon: Unexpected error during run()


2020-02-21 14:31:26.557699 WARNING AppDaemon: ------------------------------------------------------------


Traceback (most recent call last):


  File "/usr/local/lib/python3.8/site-packages/appdaemon/__main__.py", line 135, in run


    loop.run_until_complete(asyncio.gather(*pending))


  File "/usr/local/lib/python3.8/asyncio/base_events.py", line 612, in run_until_complete


    return future.result()


  File "/usr/local/lib/python3.8/site-packages/appdaemon/admin_loop.py", line 19, in loop


    if self.AD.http.stats_update != "none" and self.AD.sched is not None:


AttributeError: 'HTTP' object has no attribute 'stats_update'


2020-02-21 14:31:26.558364 INFO AppDaemon: Previous message repeated 1 times


2020-02-21 14:31:26.558453 INFO AppDaemon: AppDaemon Exited


/usr/local/lib/python3.8/site-packages/appdaemon/__main__.py:134: DeprecationWarning: Task.all_tasks() is deprecated, use asyncio.all_tasks() instead


  pending = asyncio.Task.all_tasks()

Any ideas?
Thanks in advance.

@Carlos_Luis Try this?

appdaemon:
  threads: 10
  plugins:
    HASS:
      type: hass
      ha_url: http://3.0.0.232:8123
      token: <MY TOKEN >
  latitude: 40.4165001
  longitude: -3.7025599
  elevation: 667
  time_zone: Europe/Madrid
http:
  url: http://3.0.0.232:5050
admin:

Hi @valexi,

with this config I get exactly the same errors as before:

Hi I have such a panel ikea FLOALT panel WS 60x60 Model L1529 after configuration works only on / off brightening up / down but when changing the color temperature crashes error that the lamp does not support xy_color or color_temp

2020-02-23 17:13:02.450159 WARNING salon: Unexpected error in worker for App salon:
2020-02-23 17:13:02.451967 WARNING salon: Worker Ags: {'id': 'c4fcac9e3cfe4ca2bd3a16d1980a1291', 'name': 'salon', 'objectid': 'f2c0cf3dcfa646f18d64cb9b00209382', 'type': 'event', 'event': 'deconz_event', 'function': <bound method DeCONZIntegration.callback of <core.integration.deconz.DeCONZIntegration object at 0x753354d8>>, 'data': {'id': 'tradfri_remote_control', 'unique_id': '00:0b:57:ff:fe:9b:8c:51', 'event': 5002}, 'pin_app': True, 'pin_thread': 1, 'kwargs': {'id': 'tradfri_remote_control', '__thread_id': 'MainThread'}}
2020-02-23 17:13:02.453887 WARNING salon: ------------------------------------------------------------
2020-02-23 17:13:02.455829 WARNING salon: Traceback (most recent call last):
  File "/usr/lib/python3.8/site-packages/appdaemon/threading.py", line 725, in async_worker
    await funcref(args["event"], data, args["kwargs"])
  File "/config/appdaemon/apps/controllerx/core/integration/deconz.py", line 15, in callback
    await self.controller.handle_action(data["event"])
  File "/config/appdaemon/apps/controllerx/core/controller.py", line 108, in handle_action
    await action(*args)
  File "/config/appdaemon/apps/controllerx/core/controller.py", line 28, in _action_impl
    await method(self, *args, **kwargs)
  File "/config/appdaemon/apps/controllerx/core/type/light_controller.py", line 308, in click
    attribute = await self.get_attribute(attribute)
  File "/config/appdaemon/apps/controllerx/core/type/light_controller.py", line 274, in get_attribute
    raise ValueError(
ValueError: This light does not support xy_color or color_temp
2020-02-23 17:13:02.456892 WARNING salon: ------------------------------------------------------------

Hi @Andrzej_Rypien,

This message appears because the light does not support color temperature. Can you show me the states attributes of your light from the Developer Tools?

max_mireds: 500
brightness: 253
is_deconz_group: false
friendly_name: Salon
supported_features: 43

The panel itself supports color temperature change

And what about from HA? Can you change the color_temp? Or just brightness?