Trigger object is undefined for message when using device_tracker state change

I’ve been playing around with HA for about a month now. Coming from SmartThings, I’m very impressed with the amount of customizability. The documentation and community support has been very helpful, but unfortunately I’ve hit a wall with this problem:

I want to be notified when people are home/away.

# automations.yaml

- alias: Presence State Change
  trigger:
    - platform: state
      # entity_id: light.kitchen_lights
      # entity_id: device_tracker.dan_mandle, device_tracker.sam, device_tracker.rebecca, device_tracker.pete
      entity_id: device_tracker.dan_mandle
  action:
    - service: notify.telegram_group
      data:
        message: '{{ trigger.to_state.name }} is {{ trigger.to_state.state }}'

The code above works for the kitchen lights, but throws an error when I try to use it with device_tracker entities (either commented line).

The error is: homeassistant.exceptions.TemplateError: UndefinedError: 'trigger' is undefined .

Why doesn’t this work with device_tracker? What are alternatives to accomplish the same thing?

I don’t think ‘name’ works for a lot of things, I struggle to work out all the trigger.whatever templates as they’re not very intuitive IMO. Try…

{{ trigger.to_state.attributes.friendly_name }}

Also I believe you need to use data_template: instead of data:.

1 Like

try and adjust this:

  - alias: Daughter abbandoned home
    id: 'Daughter abbandoned home'
    initial_state: on
    trigger:
      platform: state
      entity_id:
        - device_tracker.daughter1
        - device_tracker.daughter2
        - device_tracker.daughter3
        - device_tracker.daughter4
      to: 'not_home'
    condition:
      condition: state
      entity_id: input_boolean.notify_presence
      state: 'on'
    action:
      - service: notify.notify
        data_template:
          title: 'Daughter abbandoned home:'
          message: >-
            {{as_timestamp(now()) | timestamp_custom('%X') }} 
            {{ trigger.to_state.attributes.friendly_name}} left home,
            {{ trigger.entity_id.split('.')[1]|replace('_', '')}} is 
            {{ trigger.to_state.state }}
      - condition: state
        entity_id: binary_sensor.daughters_home
        state: 'off'
      - service: notify.notify
        data_template:
          message: >
           {{as_timestamp(now()) | timestamp_custom("%X") }}: No daughter at home anymore

or arrive home of course (made 2 automations to keep it a bit simpler…)

  - alias: Daughters arrived Home
    id: 'Daughters arrived Home'
    initial_state: on
    trigger:
      platform: state
      entity_id:
        - device_tracker.daughter1
        - device_tracker.daughter2
        - device_tracker.daughter3
        - device_tracker.daughter4
      to: 'home'
    condition:
      condition: state
      entity_id: input_boolean.notify_presence
      state: 'on'
    action:
      - service: notify.notify
        data_template:
          title: 'Daughter at home:'
          message: >-
            {{as_timestamp(now()) | timestamp_custom('%X') }} 
            {{ trigger.to_state.attributes.friendly_name}} came home,
            {{ trigger.entity_id.split('.')[1]|replace('_', '')}} is 
            {{ trigger.to_state.state }}
      - condition: state
        entity_id: input_boolean.notify_announcement
        state: 'on'
      - service: notify.ios_telefoonmhb
        data_template:
          title: 'Daughter arrived home speech'
          message: >-
            {{as_timestamp(now()) | timestamp_custom("%X") }} : 
            {{ trigger.to_state.attributes.friendly_name}} arrived home.
          data:
            push:
              sound: US-EN-Morgan-Freeman-Daughter-Is-Arriving.wav
1 Like

I agree with @anon43302295 on this. It’s a pain in the ass trying to figure out whats inside trigger attributes. It depends on where it’s coming from. For safety, I always get the entity_id out and work with that when dealing with unknown to_state attributes:

example:

  ...
  action:
    - service: notify.telegram_group
      data_template: #@pnbruckner's change, which is required.
        message: >
          {% set state = states(trigger.entity_id) %}
          {{ state.name }} is {{ state.state }}

I’m not sure this would work. Doesn’t states() return the state as a string instead of the state object? Wouldn’t it need to be something like the following?

{% set e = trigger.entity_id %}
{{ state_attr(e, 'friendly_name') }} is {{ states(e) }}

Personally I have no problem using the trigger variable. In this case it’s pretty clear that it is from a state trigger. And even when there are different types of triggers, there’s always a way to test which one happened. And sometimes it’s important to use the trigger variable, because it shows exactly the state change (or time or whatever) that caused the trigger, when by the time the entity is being tested (in a condition or in the action sequence) it’s possible (although usually unlikely) that the entity has changed. But, I guess this comes down to personal preference mostly. :slight_smile:

ah yes, I was thinking of the selectattr method: This is what I usually use. I should have actually looked at my code.

  ...
  action:
    - service: notify.telegram_group
      data_template: #@pnbruckner's change, which is required.
        message: >
          {% set state = states | selectattr('entity_id', 'eq', trigger.entity_id) %}
          {{ state.name }} is {{ state.state }}
1 Like

The plot thickens. The code works… but only for home. I got that to work by turning the devices into a list and changing back to message_template.

- alias: Presence State Change
  trigger:
    - platform: state
      entity_id:
        - device_tracker.dan_mandle
        - device_tracker.dan_white
        - device_tracker.sam
        - device_tracker.rebecca
        - device_tracker.pete
  action:
    - service: notify.telegram_group
      data_template:
        message: '{{ trigger.to_state.name }} is {{ trigger.to_state.state }}'

That code works, but only for the home state. When a device goes not_home, it errors out. Why would it work for home and not for not_home?

'can't parse entities: can't find end of the entity starting at byte offset 17. Args: (-284538191, 'Dan Mandle is not_home'), kwargs: {'parse_mode': 'Markdown', 'disable_notification': False, 'disable_web_page_preview': None, 'reply_to_message_id': None, 'reply_markup': None, 'timeout': None}

That is weird. Must have something to do with the particular notification platform you’re using. Is there more to that error message that might help?

In any case, if you only care about home vs away (and not what zone they might have entered), you could maybe try:

message: >
  {{ trigger.to_state.name }} is {{ 'home' if trigger.to_state.state == 'home' else 'away' }}

In fact, if you don’t care about zone transitions (other than home) you might even want to add a condition that trigger.from_state.state or trigger.to_state.state is ‘home’ so that you don’t get notifications if someone transitions between not_home and a zone or vice versa. Something like:

condition:
  condition: template
  value_template: >
    {{ trigger.from_state.state == 'home' or trigger.to_state.state == 'home' }}

turn logging to info and see whats in the trigger.to_state object when the automation fires.

EDIT: This might only explain why it’s happening. To fix it, do what @pnbruckner said.