Error rendering data template

Hi All i have been trying to trouble shoot this issue below to no avail, i cant seem to see where the issue is or what to change, i hear there was a breaking change in templates but i have no ideas where to look, anyone have any ideas.

this is the error message i get in the logs…

ERROR (MainThread) [homeassistant.components.automation.irrigation_notify_about_irrigation_events_user1] Error while executing automation automation.irrigation_notify_about_irrigation_events_user1: Error rendering data template: UndefinedError: 'dict object' has no attribute 'to_state'
#================
#=== Automations
#================
automation:

  #===================================================
  #=== Notify about irrigation events
  #===================================================
  - alias: Irrigation Notify About Irrigation Events User1
    trigger:
      - platform: state
        entity_id:
        - input_boolean.irrigation_cycle1_running
        - input_boolean.irrigation_cycle2_running
        from: 'off'
        to: 'on'

    condition:
      - condition: state
        entity_id: input_boolean.irrigation_notify_user1
        state: 'on'      
    action:
      - service: telegram_bot.send_message
        data_template:
          target: ********
          title: '*IRRIGATION SYSTEM*
          message: >
            {% if trigger.entity_id == 'input_boolean.irrigation_cycle1_running' %}
              {% set cycle = 'cycle1' %}
            {% else %}
              {% set cycle = 'cycle2' %}
            {% endif %}

            {% set cycle_name = states('input_text.irrigation_' ~ cycle ~ '_name') %}

            {% if trigger.to_state.state == 'on' %}
              {% set ns = namespace(total_time = 0) %}
              {% for zone in states.input_number if zone.entity_id.startswith('input_number.irrigation_' ~ cycle ~ '_zone') and
                                                    zone.entity_id.endswith('_duration') %}
                {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_zone' ~ loop.index ~ '_skip', 'off') %}
                    {# Adjust for rainfall #}
                    {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_rainfall', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_rainfall_multiplier') | float %}
                    {% elif is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_temperature', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_temp_multiplier') | float %}
                    {% else %}
                      {% set ns.total_time = ns.total_time + states(zone.entity_id) | float %}
                    {% endif %}
                {% endif %} 
              {% endfor %}
              
              I thought you'd like to know that the {{ cycle_name }} cycle has just started.


            The total watering time should be about {{ (ns.total_time * 60) | timestamp_custom('%H:%M', false) }} but I'll let you know when it has finished.
            {% else %}
              All the {{ cycle_name }} cycle watering is done.
            {% endif %}

You can just add this condition and it will stop triggers at startup or shutdown

      - condition: template
        value_template: >
          {{ trigger | default(none) is not none and trigger.to_state is defined and trigger.from_state is defined }}
1 Like

I did try this but it still gave the same errors in the log when i activate the automation, but i think that this is not what i need stoping the trigger, i would like to get it working again like it used to but i cant trouble shoot the issue.

But thanks for the input.

When you activate the automation from the UI it just runs the actions as a script. Which means trigger isn’t defined and any time the actions attempt to use it in templates you’re going to get that warning.

One option is to fix it like petro is showing. Basically any place you are using trigger in templates you add an extra condition first to check if trigger exists. You’ll have to do that in a few places, I see a reference to trigger.entity_id and another trigger.to_state.state.

Another option is to just ignore it. You won’t get this warning when your automation runs normally (i.e. when one of those irrigation cycle booleans turns on). You’ll only get this warning when you press the icon to manually run the automation from the UI. Since your automation relies on trigger it never worked correctly when you ran it from the UI so nothing has really changed in that regard except now this warning is letting you know that it didn’t work right.

Another option is to put something like this at the start of your template:

{% set trigger = trigger if trigger is defined else {"entity_id":"an_testing_id", "to_state":{... put testing state data here...}} %}

Basically stub out a value for trigger when it doesn’t exist that gets used when doing manual testing from the UI.

Up to you how much time you want to invest in this.

1 Like

You won’t get it working without a proper trigger. If you try to catch it, you’ll just end up with a message that adds up nothing because the cycle will be undefined.

If you want to test your template, use the template editor. You can also turn it into a scrip and only pass in the cycle. Then you can test the script to your hearts content. When complete, make the automation that pulls the cycle and on/off state and passes it to the script

1 Like

I was on my cell last night, so I couldn’t really post.

script

irrigation_notification:
  fields:
    cycle:
      description: (Required) The name of the cycle in the entity_id
      example: cycle1
    trigger_state:
      description: The state of the automation's trigger.
      example: "on"
  sequence:
      - service: telegram_bot.send_message
        data_template:
          target: ********
          title: '*IRRIGATION SYSTEM*
          message: >
            {% set cycle_name = states('input_text.irrigation_' ~ cycle ~ '_name') %}

            {% if trigger_state == 'on' %}
              {% set ns = namespace(total_time = 0) %}
              {% for zone in states.input_number if zone.entity_id.startswith('input_number.irrigation_' ~ cycle ~ '_zone') and
                                                    zone.entity_id.endswith('_duration') %}
                {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_zone' ~ loop.index ~ '_skip', 'off') %}
                    {# Adjust for rainfall #}
                    {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_rainfall', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_rainfall_multiplier') | float %}
                    {% elif is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_temperature', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_temp_multiplier') | float %}
                    {% else %}
                      {% set ns.total_time = ns.total_time + states(zone.entity_id) | float %}
                    {% endif %}
                {% endif %} 
              {% endfor %}
              
              I thought you'd like to know that the {{ cycle_name }} cycle has just started.


            The total watering time should be about {{ (ns.total_time * 60) | timestamp_custom('%H:%M', false) }} but I'll let you know when it has finished.
            {% else %}
              All the {{ cycle_name }} cycle watering is done.
            {% endif %}

automation:

  - alias: Irrigation Notify About Irrigation Events User1
    trigger:
      - platform: state
        entity_id:
        - input_boolean.irrigation_cycle1_running
        - input_boolean.irrigation_cycle2_running
        from: 'off'
        to: 'on'

    condition:
      - condition: state
        entity_id: input_boolean.irrigation_notify_user1
        state: 'on'
      - condition: template
        value_template: >
          {{ trigger | default(none) is not none and trigger.to_state is defined and trigger.from_state is defined }}
    action:
      - service: script.irrigation_notification
        data:
          cycle: >
            {{ trigger.entity_id.split('.')[-1].split('_')[1] }}
          trigger_state: >
            {{ trigger.to_state.state }}

Now to test, just execute the script from the dev tools services tab. Don’t touch the automation because it won’t work without a proper trigger.

1 Like

Excuse my ignorance, maybe I should know this1 but…

If the trigger is an entity that goes from ‘off’ to ‘on’, how can the trigger ever not have from or a to state.

1 My only excuse is that I’ve been mostly away from HA for a few months :stuck_out_tongue_winking_eye:

it’s overkill. In the past startup or shutdown could trigger a state change resulting in only a to_state and no from_state. I don’t know if that’s a thing any more but I keep in my conditions. That value template ensures a state trigger is complete and it will not error at startup or shutdown.

1 Like

All this talk about State Triggers triggering on startup has me perplexed. I can’t recall any of my automations, employing State Triggers, doing that. :thinking:

I just tested this simple automation (version 2021.5.5) and it doesn’t trigger on startup (or Reload Automation)

- alias: state trigger test
  trigger:
  - platform: state
    entity_id: input_boolean.test
    from: 'off'
    to: 'on'
  action:
  - service: notify.persistent_notification
    data:
      title: Trigger Test
      message: "It's {{ trigger.to_state.state }}!"

However, I can reproduce the 'dict object' has no attribute 'to_state' error message:

Logger: homeassistant.components.automation.state_trigger_test
Source: components/automation/__init__.py:508
Integration: Automation (documentation, issues)
First occurred: 15:19:14 (1 occurrences)
Last logged: 15:19:14

Error while executing automation automation.state_trigger_test: Error rendering data template: UndefinedError: 'dict object' has no attribute 'to_state'

It happens when one manually executes the automation. The outcome is expected because the trigger variable is undefined when an automation is executed in this manner.

Does anyone have an example that reliably reproduces the error when Home Assistant is restarted?

Remove from state from your automation

I’ll try it but the OP’s automation uses from and claims to get the error message on startup.

I think I said things about start up, not op. It’s just a condition I’ve always used From the start of HA. Admittedly, most of my automations are complicated and do not use a from or to for state triggers.

Ok this is what i got so far by messing around with the scripts, templates etc and i must state i have no knowledge of what i have done but it works up to a certain extent, the automation will now send a notification stating that the irrigation has started and that is fine for now.

The original automation used to notify me when it has been completed as well, I have tried to use a few combinations with what’s above and use the off instead of on in another automation to no avail, but that’s not a biggie.

I did in one of my try’s had a notification that gave me the watering is done before and after the irrigation start and finish, but did not save that config as I was trying all sorts to get it to work to properly notify me ie: notify when “irrigation has started”, and the same notify when “irrigation is done”

Anyway I have got further than expected and thanks a lot for the discussion and pointers.

#===================
#=== Input Booleans
#===================
input_boolean:
  irrigation_notify_user1:
    name: Notify andiewill of events
    icon: mdi:message-text-outline

  irrigation_notify_user2:
    name: Notify User2 of events
    icon: mdi:message-text-outline


#================
#=== Automations
#================
automation:

  # #===================================================
  # #=== Notify about irrigation events user 1
  # #===================================================
  - alias: Irrigation Notify About Irrigation Events User1
    trigger:
      - platform: state
        entity_id:
        - input_boolean.irrigation_cycle1_running
        - input_boolean.irrigation_cycle2_running
        from: 'off'
        to: 'on'

    condition:
      - condition: state
        entity_id: input_boolean.irrigation_notify_user1
        state: 'on'
      - condition: template     
        value_template: >
          {{ trigger | default(none) is not none and trigger.to_state is defined and trigger.from_state is defined }}
 

    action:
      - service: telegram_bot.send_message
        data:
          target: ********
          title: '*IRRIGATION SYSTEM*'
          
          message: >
            {% if trigger.entity_id == 'input_boolean.irrigation_cycle1_running' %}
              {% set cycle = 'cycle1' %}
            {% else %}
              {% set cycle = 'cycle2' %}
            {% endif %}

            {% set cycle_name = states('input_text.irrigation_' ~ cycle ~ '_name') %}

            {% if trigger_state == 'on' %}
              {% set ns = namespace(total_time = 0) %}
              {% for zone in states.input_number if zone.entity_id.startswith('input_number.irrigation_' ~ cycle ~ '_zone') and
                                                    zone.entity_id.endswith('_duration') %}
                {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_zone' ~ loop.index ~ '_skip', 'off') %}
                    {# Adjust for rainfall #}
                    {% if is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_rainfall', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_rainfall_multiplier') | float %}
                    {% elif is_state('input_boolean.irrigation_' ~ cycle ~ '_adjust_for_temperature', 'on') %}
                      {% set ns.total_time = ns.total_time * states('input_number.irrigation_temp_multiplier') | float %}
                    {% else %}
                      {% set ns.total_time = ns.total_time + states(zone.entity_id) | float %}
                    {% endif %}
                {% endif %} 
              {% endfor %}
              
            I thought you'd like to know that the {{ cycle_name }} has just started.
            {% else %}
              All the {{ cycle_name }} watering has started.
            {%endif %}