Understanding event_data content

Hey all,
slowly getting to know Home Assistant and I hope the community can help me to understand this question.

In the context of an event triggered automation, what is inside event_data?

Some explanation to the question is given here - however the truth seems to lie somewhere in between.

Example

I observe events via the developer tools and the “*” filter. The event for a door sensor I want to trigger on looks as such:

Event trace...
{
    "event_type": "state_changed",
    "data": {
        "entity_id": "binary_sensor.door_bathroom",
        "old_state": {
            "entity_id": "binary_sensor.door_bathroom",
            "state": "off",
            "attributes": {
                "battery": "High",
                "error": "No",
                "rssi_peer": 0,
                "rssi_device": -59,
                "id": "LEQ1466850",
                "interface": "wireless",
                "friendly_name": "Homematic Türkontakt Bad",
                "device_class": "opening"
            },
            "last_changed": "2020-03-21T17:21:42.848532+00:00",
            "last_updated": "2020-03-21T17:21:42.848532+00:00",
            "context": {
                "id": "f4395769514d46a7a4b6656cdbd73d59",
                "parent_id": null,
                "user_id": null
            }
        },
        "new_state": {
            "entity_id": "binary_sensor.door_bathroom",
            "state": "on",
            "attributes": {
                "battery": "High",
                "error": "No",
                "rssi_peer": 0,
                "rssi_device": -59,
                "id": "LEQ1466850",
                "interface": "wireless",
                "friendly_name": "Homematic Türkontakt Bad",
                "device_class": "opening"
            },
            "last_changed": "2020-03-21T17:21:44.840558+00:00",
            "last_updated": "2020-03-21T17:21:44.840558+00:00",
            "context": {
                "id": "9227ef990e5d4eab8717acc192d8ca65",
                "parent_id": null,
                "user_id": null
            }
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-03-21T17:21:44.841066+00:00",
    "context": {
        "id": "9227ef990e5d4eab8717acc192d8ca65",
        "parent_id": null,
        "user_id": null
    }
}

But this view doesn’t seem very useful, as its data clearly is not used for automations.

The following automation triggers:

- alias: bathroom_light_via_doorsensor
  trigger:
    - platform: event
      event_type: state_changed
      event_data:
        entity_id: binary_sensor.door_bathroom
  action:
    service: light.turn_on
    entity_id: light.bathroom

this one doesn’t trigger:

- alias: bathroom_light_via_doorsensor
  trigger:
    - platform: event
      event_type: state_changed
      event_data:
        entity_id: binary_sensor.door_bathroom
        new_state:        # Added
          state: 'on'     # Added
        # Also doesn't work
        # new_state: 'on'
  action:
    service: light.turn_on
    entity_id: light.bathroom

Of course I could work with a state trigger or tailor this with a condition but I am trying to learn.

Questions

The example raises a few questions:

  • Why does the second automation not work?
  • Is there any interface on which one can directly and unambiguously see all events and state changes with all linked data (which can then be used in triggers, conditions and actions)? This seems to be an important piece of the HA ecosystem I did not yet find.

Based on this discussion I’ll contribute an improvement to the documentation.

Thanks for your help!

I assume this is all part of exploring how the Event Trigger works? Because if you’re using a binary_sensor then State Trigger would be the easiest type of trigger to use.

1 Like

Because new_state is not {"state": "on"}, its:

        {
            "entity_id": "binary_sensor.door_bathroom",
            "state": "on",
            "attributes": {
                "battery": "High",
                "error": "No",
                "rssi_peer": 0,
                "rssi_device": -59,
                "id": "LEQ1466850",
                "interface": "wireless",
                "friendly_name": "Homematic Türkontakt Bad",
                "device_class": "opening"
            },
            "last_changed": "2020-03-21T17:21:44.840558+00:00",
            "last_updated": "2020-03-21T17:21:44.840558+00:00",
            "context": {
                "id": "9227ef990e5d4eab8717acc192d8ca65",
                "parent_id": null,
                "user_id": null
            }
        }
1 Like

You are correct and my implemented automation uses a state trigger :+1:

I’m interested in the Event Trigger for one, but more general in every kind of “event” as in action that we can trigger on.
The Events Developer Tool and the Log Viewer both seem to serve other purposes. I’m missing a view that shows all events/state changes/whatever in a log like fashion and wonder how everyone else does that…

When using an event trigger, it’s often better to do more of the filtering in the automation condition. So, e.g., this would probably do what you want:

- alias: bathroom_light_via_doorsensor
  trigger:
    - platform: event
      event_type: state_changed
      event_data:
        entity_id: binary_sensor.door_bathroom
  condition:
    - condition: template
      value_template: >
        {{ trigger.event.data.new_state.state == 'on' }}
  action:
    service: light.turn_on
    entity_id: light.bathroom
2 Likes

Hey Phil,
thanks :wink: I kinda already suspected the first and used the second.
The problem is that this is not clear from the outset and I suppose you “just know” from experience? I made similar discoveries and am now trying to learn to improve the documentation

Regarding new_state: I don’t think the automation trigger generally works this way. It’s an elective filter and if that stops at new_state, I wonder why!?

Hey Thomas!

No problem!

I’m not sure what you mean by that. Basically if you specify a key (such as new_state) under event_data, then if that key exists in the event data, then the value you supply must match the value in the event exactly. You specified (in the trigger) that new_state's value should be {"state": "on"}, but the value of new_state in the event had a lot more key/value pairs in its value, and hence did not match exactly with the value you put in the trigger.

I agree that event triggers are probably harder to understand and use than the others. (The others are, in effect, event triggers as well, since pretty much everything in HA is event driven, but they do some of the processing for you to make them easier to use.) The way I learned how they work was by reading the code. The doc probably could use some improvement, but I wouldn’t know how to explain it concisely so that non-programmers would understand.

Came here to say … what Phil said.

The options for event_data are all relative to "data": so that’s why entity_id works (because the value you supplied for this key is a perfect match). In contrast, the value you supplied for new_state is merely a fraction of the dictionary it actually contains and therefore fails to match it.

1 Like

I’m not sure what you mean by that.

I phrased it badly but both of you explained the contrary quite well :slight_smile: In general the way triggers are matched is:

if that key exists in the event data, then the value you supply must match the value in the event exactly

Good so far. However, when we get to a key like new_state containing a nested dictionary, it is not possible to select keys within this dict. That was not specifically clear to me and feels inconsistent. Do you agree? This should be documented and maybe improved in the future.

but I wouldn’t know how to explain it concisely so that non-programmers would understand.

This is exactly why I started this discussion :slight_smile: I am a software engineer with years of experience. I also like to read code and build up knowledge by testing. This part of HA felt weird so I wanted to know what your experience is.

I already have some ideas how to improve the Event vs. State Trigger documentation.

Back to the second topic:

  1. Is there any interface on which one can directly and unambiguously see all events and state changes with all linked data (which can then be used in triggers, conditions and actions)?

Could be anything from a simple syslog console to an interactive elasticsearch-like frontend. Home Assistant doesn’t offer something like this out of the box and my question is quite simple: Why? :upside_down_face:

You can use the EVENTS tab of the Developer Tools page to see individual event types, as you already did I believe.

You can also set:

logger:
  default: info
  logs:
    homeassistant.core: debug

Then you will be able to see all events in home-assistant.log. Unfortunately they are not displayed extremely well, but they’re there.

You can also look at the events table in the database, if you’re familiar with how to do that. But, again, the data representation is a little different.

AFAIK, there’s no way to see all events in all their glory in the UI, but maybe I’m overlooking something.

I agree. The documentation for Event Trigger provides only one simple example and doesn’t explain the details. What I know was learned by trial and error … and by reading how other people tried and failed.

I guess the issue is that Event Trigger is, compared to other triggers, more complex and advanced. I guess the assumption is that if you’re using it then you’re not exactly a beginner (and willing to experiment). I’m not saying that’s a good justification but it just appears to be that way.

If you are willing to improve the documentation for Event Trigger, please do!

I am struggling with the same. I want to catch a specific ZHA event and let that trigger an automation. In my case i also want to check the args for certain predefined values in the event.

example event captured by developer tools:

{
    "event_type": "zha_event",
    "data": {
        "device_ieee": "00:15:8d:00:02:93:04:11",
        "unique_id": "00:15:8d:00:02:93:04:11:1:0x0006",
        "endpoint_id": 1,
        "cluster_id": 6,
        "command": "attribute_updated",
        "args": {
            "attribute_id": 0,
            "attribute_name": "on_off",
            "value": false
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-09-23T12:12:10.223091+00:00",
    "context": {
        "id": "019d5966fd9611ea973c0b2e05cd396a",
        "parent_id": null,
        "user_id": null
    }
}

In my case i want the automation triggerd when device_iee mtaches and the args->value is equal to true.

So i use the following trigger in my automation:

platform: event
event_type: zha_event
event_data:
  device_ieee: '00:15:8d:00:02:93:04:11'
  args:
    attribute_id: 0
    attribute_name: on_off
    value: true

In this case the automation is triggerd regardless of the value of args (value: true or value: false).
The automation is only started when the device_ieee equals ‘00:15:8d:00:02:93:04:11’

So it looks like whe cannot use nested arguments in the trigger event_data, for filtering?
In my case i supplied the whole directory for args, so matching should be possible.

I doubt the trigger is recursive, i.e. I don’t think it goes into args. I could be wrong, either way, just use a template condition:

trigger:
- platform: event
  event_type: zha_event
  event_data:
    device_ieee: '00:15:8d:00:02:93:04:11'
condition:
- condition: template
  value_template: >
    {% set data = trigger.event.data %}
    {{ data.attribute_id == 0 and 
       data.attribute_name == 'on_off' and
       data.value == 'true' }}
action:
...
  

You may need to alter the data.value == 'true' because you need to verify if it’s a boolean or a string.

Yes i know this is a solution, but not when using it with the new “wait_for_trigger” statement in the actions part when you want to catch a specific event with its matching data. I would be logical it would be recursive.

I just verified that it works. Even tested it with an automation:

- alias: Triggered True
  trigger:
  - platform: event
    event_type: zha_event
    event_data:
      device_ieee: 00:15:8d:00:02:93:04:11
      args:
        attribute_id: 0
        attribute_name: on_off
        value: true
  action:
  - service: persistent_notification.create
    data_template:
      message: Triggered "True" at {{ now().strftime("%I:%M %p") }}
  mode: single


- alias: Triggered false
  trigger:
  - platform: event
    event_type: zha_event
    event_data:
      device_ieee: 00:15:8d:00:02:93:04:11
      args:
        attribute_id: 0
        attribute_name: on_off
        value: false
  action:
  - service: persistent_notification.create
    data_template:
      message: Triggered "false" at {{ now().strftime("%I:%M %p") }}
  mode: single

I tested on the developer tools -> events page:

image

image

So it only triggered when the data match. I didn’t get a false trigger when true was in the dict and vise versa.

You’re welcome to test this yourself.

Thanks for your help, this lead me to the solution. The problem was that during a button press i got 3 events.

Event 2 fired 4:30 PM:
{
    "event_type": "zha_event",
    "data": {
        "device_ieee": "00:15:8d:00:02:93:04:11",
        "unique_id": "00:15:8d:00:02:93:04:11:1:0x0006",
        "endpoint_id": 1,
        "cluster_id": 6,
        "command": "attribute_updated",
        "args": {
            "attribute_id": 0,
            "attribute_name": "on_off",
            "value": false
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-09-23T14:30:50.509664+00:00",
    "context": {
        "id": "60e45171fda911eaad6a0bd8630bb091",
        "parent_id": null,
        "user_id": null
    }
}
Event 1 fired 4:30 PM:
{
    "event_type": "zha_event",
    "data": {
        "device_ieee": "00:15:8d:00:02:93:04:11",
        "unique_id": "00:15:8d:00:02:93:04:11:1:0x0006",
        "endpoint_id": 1,
        "cluster_id": 6,
        "command": "attribute_updated",
        "args": {
            "attribute_id": 0,
            "attribute_name": "on_off",
            "value": true
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-09-23T14:30:50.372105+00:00",
    "context": {
        "id": "60cf5449fda911eab5c3d9e5b425f4a8",
        "parent_id": null,
        "user_id": null
    }
}
Event 0 fired 4:30 PM:
{
    "event_type": "zha_event",
    "data": {
        "device_ieee": "00:15:8d:00:02:93:04:11",
        "unique_id": "00:15:8d:00:02:93:04:11:1:0x0006",
        "endpoint_id": 1,
        "cluster_id": 6,
        "command": "click",
        "args": {
            "click_type": "single"
        }
    },
    "origin": "LOCAL",
    "time_fired": "2020-09-23T14:30:50.370765+00:00",
    "context": {
        "id": "60cf220bfda911eaa385b5010b9e5350",
        "parent_id": null,
        "user_id": null
    }
}

In this case it also reacted on the Event 0 who also contains a dictionary in args (maybe you could try this in your test also). When python compares 2 dictionaries and they are different, this also results also in a false.

adding the value “command” solved the problem, now makes the differance between value true or false.

New trigger definition:

platform: event
event_type: zha_event
event_data:
  device_ieee: '00:15:8d:00:02:93:04:11'
  command: attribute_updated
  args:
    attribute_id: 0
    attribute_name: on_off
    value: true
1 Like

@petro, I also have an other problem with the new “wait_for_trigger”. I want to wait for a trigger and set the timeout. In case of the timeout i want a different action, then when the event arrives. I already posted this as bug. Maybe you have a clue? see https://github.com/home-assistant/core/issues/40489#issuecomment-697323271

Problem with “wait_for_trigger” is solved.

See end result of script :slight_smile: