appdaemon icon indicating copy to clipboard operation
appdaemon copied to clipboard

[Feature Request] Device trigger support

Open oxan opened this issue 4 years ago • 16 comments

I have a few buttons which I'd like to make smart using appdaemon scripts. However, these buttons work with device triggers, which (as far as I can see) aren't supported in appdaemon (yet). It would be really nice if this could be added!

oxan avatar Apr 10 '20 13:04 oxan

@oxan,

There must be an event that follows that trigger, and this will be forwarded to AD. In that case, you should be able to use to do what you want. The other option is to get the data directly from MQTT without depending on AD.

Regards

Odianosen25 avatar Apr 10 '20 13:04 Odianosen25

HA doesn't fire any special event about this as far as I can see. Only a state change, but since the "to" state might be the same as the "from" state (i.e. if I press the "on" button twice), I can't do anything with that in AD.

Maybe it's indeed better if HA fires a special event in cases like this. I'll try to open an issue there.

oxan avatar Apr 10 '20 18:04 oxan

When you register a "device_automation" via MQTT, the end result is that Home Assistant will fire an event when that trigger occurs.

Because you are using AppDaemon, you don't have to use MQTT to fire an event (though you certainly can). Instead, you can fire an event in an app by simply using:

self.fire_event('event_name_here', event_parameter_1="abc", event_parameter_2="def")

dlashua avatar Apr 11 '20 11:04 dlashua

Yes, but in this case I want to handle an event that is fired over MQTT (by zigbee2mqtt) in AppDaemon, not the other way around.

(I could just handle the MQTT event in AppDaemon myself, but I like the abstraction of dealing with just HA in my scripts and not having to think about the interface between zigbee2mqtt and HA. That would also allow me to migrate to ZHA without having to change my scripts later on.)

oxan avatar Apr 11 '20 12:04 oxan

When Zigbee2MQTT uses the "device_automation" in Home Assistant, doesn't that trigger an event in Home Assistant? If so, you can listen_event() for that in AppDaemon.

dlashua avatar Apr 12 '20 18:04 dlashua

I would also like to see this in appdemon, the new hue dimmer switch in hassio is implemented as device trigger, i don't want to create automation in hassio to send event to get it in appdemon, can u somehow intercept this triggers?

pszewello avatar Apr 12 '20 20:04 pszewello

Hmmm it seems this device trigger is beyond just a regular event is that right? Will try studying it a bit, and see what we can get out.

Never used it before, and honestly never even heard abt it until this thread. No promises though, but we could investigate and if it’s something we can get in, no worries.

Regards

Odianosen25 avatar Apr 12 '20 20:04 Odianosen25

I looked at the source code for hue, and it's just an event, https://github.com/home-assistant/core/search?q=CONF_HUE_EVENT&type= so i shoukd be able to make it work, but will have to look at their source code for event ids...

pszewello avatar Apr 12 '20 20:04 pszewello

@dlashua

When Zigbee2MQTT uses the "device_automation" in Home Assistant, doesn't that trigger an event in Home Assistant? If so, you can listen_event() for that in AppDaemon.

No, it doesn't trigger an event in Home Assistant.

@Odianosen25

Hmmm it seems this device trigger is beyond just a regular event is that right?

Yes, it's something different that doesn't fire a regular event.

oxan avatar Apr 16 '20 13:04 oxan

My cursory examination of this shows that "device automations" are part of the new "device triggers" that Home Assistant has implemented, presumably to make creating Automations from the UI easier.

Without a Home Assistant Automation, it doesn't seem to fire an event, set a state, or call any services at all. This means it's undetectable from outside of Home Assistant.

There are cases, like with ZHA, for instance, where the Device Automation is available in Home Assistant but also an Event is fired. These cases seem to be specific to the integration, though, and not actually part of the "device automation" feature.

dlashua avatar Apr 22 '20 13:04 dlashua

As a workaround, you could use the Home Assistant UI to create an automation with a device trigger that simply fires an event, and then listen for this event in AppDaemon. That's not exactly ideal, though.

Possible better solutions include:

  1. Create a Feature Request in Home Assistant asking that all "Device Automations" generate an event. This assumes the architecture of this feature in Home Assistant would allow such a thing and that the Home Assistant developers approve of such a request and add the code to their core.

  2. Write an AppDaemon custom component for Home Assistant to bridge the gap. This assumes that listening for all Device Automation Triggers is possible in a custom component, which I've not researched.

dlashua avatar Apr 22 '20 13:04 dlashua

I know this is an old one and I don't know if this helps, but I've just discovered that I can respond to Hue dimmer switches from AppDaemon by listening for hue_event:

class HueDimmer(hass.Hass):
    def initialize(self):
        self.listen_event(self.hue_event, "hue_event")

    def hue_event(self, event_name, data, kwargs):
        self.log(data)

This logs the event, giving the name of the dimmer switch and an event ID:

2020-11-05 12:08:37.038723 INFO hue-dimmer: {'id': 'dimmer_landing', 'unique_id': '00:17:88:01:08:74:cd:d8-02-fc00', 'event': 4002, 'last_updated': '2020-11-05T12:08:36'}

You can then map the event IDs to what's been pressed - e.g. 4002 is turn off.

From HA/components/hue/device_trigger.py:

CONF_TURN_ON = "turn_on"
CONF_TURN_OFF = "turn_off"
CONF_DIM_UP = "dim_up"
CONF_DIM_DOWN = "dim_down"
CONF_BUTTON_1 = "button_1"
CONF_BUTTON_2 = "button_2"
CONF_BUTTON_3 = "button_3"
CONF_BUTTON_4 = "button_4"
CONF_DOUBLE_BUTTON_1 = "double_buttons_1_3"
CONF_DOUBLE_BUTTON_2 = "double_buttons_2_4"

HUE_DIMMER_REMOTE_MODEL = "Hue dimmer switch"  # RWL020/021
HUE_DIMMER_REMOTE = {
    (CONF_SHORT_RELEASE, CONF_TURN_ON): {CONF_EVENT: 1002},
    (CONF_LONG_RELEASE, CONF_TURN_ON): {CONF_EVENT: 1003},
    (CONF_SHORT_RELEASE, CONF_DIM_UP): {CONF_EVENT: 2002},
    (CONF_LONG_RELEASE, CONF_DIM_UP): {CONF_EVENT: 2003},
    (CONF_SHORT_RELEASE, CONF_DIM_DOWN): {CONF_EVENT: 3002},
    (CONF_LONG_RELEASE, CONF_DIM_DOWN): {CONF_EVENT: 3003},
    (CONF_SHORT_RELEASE, CONF_TURN_OFF): {CONF_EVENT: 4002},
    (CONF_LONG_RELEASE, CONF_TURN_OFF): {CONF_EVENT: 4003},
}

I'd guess that other device triggers work in the same way - I found the event name by creating an automation in the GUI and checking the logbook which tells you which event triggered the automation:

image

seanb-uk avatar Nov 05 '20 12:11 seanb-uk

@oxan

do you still have this problem? It seems to work by listening to the state of the sensor.

clyra avatar Feb 20 '21 22:02 clyra

@clyra I no longer use AppDaemon, so I don't know.

oxan avatar Feb 20 '21 23:02 oxan

I investigated this, and it does not appear that there is support for subscribing to device trigger "events" in the WebSocket API.

The WebSocket API docs do not mention anything around device automation support. However, there are actually device automation commands, such as device_automation/trigger/list. Unfortunately, there doesn't appear to be any API for interacting with device triggers:

$ cd homeassistant/components/device_automation
$ git grep -A4 websocket_command
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/action/list",
__init__.py-        vol.Required("device_id"): str,
__init__.py-    }
--
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/condition/list",
__init__.py-        vol.Required("device_id"): str,
__init__.py-    }
--
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/trigger/list",
__init__.py-        vol.Required("device_id"): str,
__init__.py-    }
--
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/action/capabilities",
__init__.py-        vol.Required("action"): dict,
__init__.py-    }
--
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/condition/capabilities",
__init__.py-        vol.Required("condition"): dict,
__init__.py-    }
--
__init__.py:@websocket_api.websocket_command(
__init__.py-    {
__init__.py-        vol.Required("type"): "device_automation/trigger/capabilities",
__init__.py-        vol.Required("trigger"): dict,
__init__.py-    }

In my case, I'm using the mqtt device trigger integration to pick up doorbell events via rtl_433. I think it is probably better in that case to connect directly to mqtt. I could see a possible feature in the AppDaemon addon to automatically provide mqtt credentials. For AppDaemon, I think this may be best handled with documentation improvements, given the existing support for using both mqtt and HA APIs at the same time.

deviantintegral avatar Oct 10 '21 14:10 deviantintegral

I could see a possible feature in the AppDaemon addon to automatically provide mqtt credentials

then you can ask for that feature in the github from the addon. ;)

ReneTode avatar Oct 10 '21 18:10 ReneTode