Trigger Template not valid?

Hi at all,
i use HomeAssistant in virtual machine with Linux as HA CLI with OS Version 17.1 and Core Version 2026.2.2

I have two shelly plugs in my house and I want to get 2 new values for each shelly.
First: Time when trigger is set (last time)
Second: When trigger comes, time range between last trigger and this trigger.

It is a pump with a power value. When power value comes 11:00:00 from 0 to a valid power value, this time should be stored as first value (11:00:00). When power value comes back to 0 (for example 11:00:10) and comes again at 11:02:00 to a value larger than 0, I want to see the time difference as 2minutes. It means from one time to next time that power value was changed from 0 to a value larger than 0, it was 2 minutes and this should be second value.

I created this with following code and add this to /config/configuration.yaml with Terminal window in HA.

template:
  - trigger:
      - platform: state
        entity_id: sensor.shellyplusplugs_1_switch_0_power
    sensor:
      - name: "Zeitintervall_Drainage_1"
        unit_of_measurement: "s"
        state: >
          {% set from = trigger.from_state %}
          {% set to = trigger.to_state %}
          {% set last = states('sensor.Zeitintervall_Drainage_1') %}
          {% if last in ['unknown', 'unavailable', None] %}
            {% set last = 0 %}
          {% endif %}

          {# Initialisierung abfangen #}
          {% if from is none or to is none %}
            {{ last }}

          {% elif to.state | float == 0 %}
            {{ last }}

          {% elif from.state | float == 0 and to.state | float > 0 %}
            {% set diff = (as_timestamp(to.last_changed) - as_timestamp(from.last_changed)) | int %}
            {% if diff < 60 %}
              {{ diff }} s

            {% elif diff < 3600 %}
              {% set mins = diff // 60 %}
              {% set secs = diff % 60 %}
              {{ mins }}min {{ secs }}s

            {% else %}
              {% set hours = diff // 3600 %}
              {% set mins = (diff % 3600) // 60 %}
              {% set secs = diff % 60 %}
              {{ hours }}h {{ mins }}min {{ secs }}s
            {% endif %}

          {% else %}
            {{ last }}
          {% endif %}

      - name: "Letzter_Trigger_Drainage_1"
        state: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

  - trigger:
      - platform: state
        entity_id: sensor.shellyplusplugs_2_switch_0_power
    sensor:
      - name: "Zeitintervall_Drainage_2"
        unit_of_measurement: "s"
        state: >
          {% set from = trigger.from_state %}
          {% set to = trigger.to_state %}
          {% set last = states('sensor.Zeitintervall_Drainage_2') %}
          {% if last in ['unknown', 'unavailable', None] %}
            {% set last = 0 %}
          {% endif %}

          {# Initialisierung abfangen #}
          {% if from is none or to is none %}
            {{ last }}

          {% elif to.state | float == 0 %}
            {{ last }}

          {% elif from.state | float == 0 and to.state | float > 0 %}
            {% set diff = (as_timestamp(to.last_changed) - as_timestamp(from.last_changed)) | int %}
            {% if diff < 60 %}
              {{ diff }} s

            {% elif diff < 3600 %}
              {% set mins = diff // 60 %}
              {% set secs = diff % 60 %}
              {{ mins }}min {{ secs }}s

            {% else %}
              {% set hours = diff // 3600 %}
              {% set mins = (diff % 3600) // 60 %}
              {% set secs = diff % 60 %}
              {{ hours }}h {{ mins }}min {{ secs }}s
            {% endif %}

          {% else %}
            {{ last }}
          {% endif %}

      - name: "Letzter_Trigger_Drainage_2"
        state: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"

My problem is, that after storing file and restart HA, no value changed. All 4 values are “unknown”. Some trys before, sometimes I saw a value but now, all are unknown.
Can you help me or explain, what is my mistake?

Edit:
I click to Adjustments → Developer Tools → YAML → Reload Template-Entity
It is reloaded and now in my dashboard, 3 values are unknown and one value is written: Entity doesn’t found

I take a look in /config/configuration.yaml file and all 4 values are inside.
I don’t understand the problem

Are you sure that is correct?
And the same with #2.

No not sure. It is my first time for creating source code in yaml.
I asked internet, AI and watch some examples and create this source by myself.
What should I use instead of states('sensor.Zeitintervall_Drainage_1')

For first sensor I think, this is right and for second sensor I used states('sensor.Zeitintervall_Drainage_2').

The reason I think to do this is because first sensor name is Zeitintervall_Drainage_1 and second is Zeitintervall_Drainage_2

All entity IDs are in lower case letters.
If your AI didn’t know that then it’s not much of an AI.

There is a template tool where you can test basic things.

Should be

I was wrong, don't read :)
{% set from = trigger.from_state.state %}
{% set to = trigger.to_state.state %}

Also, better not use “platform”, I think it’s deprecated, e.g.:

template:
  - trigger:
      - trigger: state
        [...]

No.

Read further down how he uses the variables.

Ah yes, sorry my bad!

You mean, it is ok to change

platform: state

to

trigger: state

Right?

This is doesn’t know, It wasn’t generated by AI.

Where I can find and test the template tool?

Yes, it’s the new syntax. Also, you could probably avoid some problems by doing:

template:
  - trigger:
      - trigger: state
        entity_id: sensor.shellyplusplugs_1_switch_0_power
        not_to: 
          - unavailable
          - unknown

You don’t need to check the trigger as much, since the sensor can only change based on that trigger. But if you want to keep the “defensive” code, I would modify it like this:

{% set from = trigger.from_state|default(none) if trigger is defined else none %}
{% set to = trigger.to_state|default(none) if trigger is defined else none %}

Since your current code may generate errors in the logs (btw: do you see any?)

And that’s what I mean, don’t use AI if it didn’t even know that very basic detail.

Depending on your version, it could be in the left side “developer tools” or in settings “developer tools” then press template.
It wouldn’t be possible to dump all this code in there but you can replace trigger variables with a set variable and kind off get stuff tested.
Triggered templates is hard to debug since they need a trigger to run.

I changed my code to:

template:
  - trigger:
      - trigger: state
        entity_id: sensor.shellyplusplugs_1_switch_0_power
        not_to: 
          - unavailable
          - unknown
    sensor:
      - name: "Zeitintervall_Drainage_1"
        unique_id: zeitintervall_drainage_1
        state: >
          {% set from = trigger.from_state %}
          {% set to = trigger.to_state %}
          {% set last = this.state %}
          {% if last in ['unknown', 'unavailable', None] %}
            {% set last = '0s' %}
          {% endif %}

          {# Initialisierung #}
          {% if from is none or to is none %}
            0s

          {% elif to.state | float == 0 %}
            {{ last }}

          {% elif from.state | float == 0 and to.state | float > 0 %}
            {% set diff = (as_timestamp(to.last_changed) - as_timestamp(from.last_changed)) | int %}

            {% if diff < 60 %}
              {{ diff }}s
            {% elif diff < 3600 %}
              {% set mins = diff // 60 %}
              {% set secs = diff % 60 %}
              {{ mins }}min {{ secs }}s
            {% else %}
              {% set hours = diff // 3600 %}
              {% set mins = (diff % 3600) // 60 %}
              {% set secs = diff % 60 %}
              {{ hours }}h {{ mins }}min {{ secs }}s
            {% endif %}

          {% else %}
            {{ last }}
          {% endif %}

  - trigger:
      - trigger: state
        entity_id: sensor.shellyplusplugs_1_switch_0_power
        not_to: 
          - unavailable
          - unknown
    sensor:
      - name: "Letzter_Trigger_Drainage_1"
        unique_id: letzter_trigger_drainage_1
        state: "{{ now().strftime('%d.%m.%Y %H:%M:%S') }}"

  - trigger:
      - trigger: state
        entity_id: sensor.shellyplusplugs_2_switch_0_power
        not_to: 
          - unavailable
          - unknown
    sensor:
      - name: "Zeitintervall_Drainage_2"
        unique_id: zeitintervall_drainage_2
        state: >
          {% set from = trigger.from_state %}
          {% set to = trigger.to_state %}
          {% set last = this.state %}
          {% if last in ['unknown', 'unavailable', None] %}
            {% set last = '0s' %}
          {% endif %}

          {# Initialisierung #}
          {% if from is none or to is none %}
            0s

          {% elif to.state | float == 0 %}
            {{ last }}

          {% elif from.state | float == 0 and to.state | float > 0 %}
            {% set diff = (as_timestamp(to.last_changed) - as_timestamp(from.last_changed)) | int %}

            {% if diff < 60 %}
              {{ diff }}s
            {% elif diff < 3600 %}
              {% set mins = diff // 60 %}
              {% set secs = diff % 60 %}
              {{ mins }}min {{ secs }}s
            {% else %}
              {% set hours = diff // 3600 %}
              {% set mins = (diff % 3600) // 60 %}
              {% set secs = diff % 60 %}
              {{ hours }}h {{ mins }}min {{ secs }}s
            {% endif %}

          {% else %}
            {{ last }}
          {% endif %}

  - trigger:
      - trigger: state
        entity_id: sensor.shellyplusplugs_2_switch_0_power
        not_to: 
          - unavailable
          - unknown
    sensor:
      - name: "Letzter_Trigger_Drainage_2"
        unique_id: letzter_trigger_drainage_2
        state: "{{ now().strftime('%d.%m.%Y %H:%M:%S') }}"

This works now for me. Do you see something I can optimize or I should change?

I did something like this but I used date/time helpers. Then Had an automation that would right {{ now() }} to them on a trigger. So when when my washing machine door is opened it takes a timestamp and when the washing machine is finished it takes a time stamp. Then I can compare those two time stamps and determine if someone has moved the wet clothes out of the wash.