How do I convert HH:MM:SS to minutes (in integer format, including hours), from "trigger.for" within an automation?

Hello,

I am trying to announce when my fridge or freezer is operating outside of its normal power consumption signature. I am able to make it work correctly, just that the HH:MM:SS format from “trigger.for” doesn’t sound too well with my TTS (Text To Speech).

Here’s my automation:

  - id: probleme_congelateur_frigidaire
    alias: Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème
    trigger:
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        below: 90
        for:
          minutes: 80 #80
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        above: 90
        for:
          minutes: 70 #70
      - platform: numeric_state
        entity_id: sensor.congelateur
        below: 80
        for:
          minutes: 140 #140
      - platform: numeric_state
        entity_id: sensor.congelateur
        above: 80
        for:
          minutes: 45 #45
    condition:
    action:
      - service: notify.emailtomathieu
        data_template:
          title: Problem Fridge or Freezer
          message: >
            {% if trigger.below | int > 0 %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.entity_id }}, unit was OFF for {{ trigger.for }} ."
            {% else %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.entity_id }}, unit was ON for {{ trigger.for }} ."
            {% endif %}
      - service: input_text.set_value
        data_template:
          entity_id: input_text.prochain_rappel_a_annoncer
          value: >
            {% if trigger.below | int > 0 %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil n'a pas fonctionné pendant {{ trigger.for.split(':')[0]|int*60 + trigger.for.split(':')[1]|int }} minutes."
            {% else %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil a fonctionné sans interruption pendant {{ trigger.for.split(':')[0]|int*60 + trigger.for.split(':')[1]|int }} minutes."
            {% endif %}

The helper “input_text.prochain_rappel_a_annoncer” is the one that’s driving the TTS. Scouting the forums and I really can’t find anything about using “.split” with “trigger.for”. I know from the other action “notify.emailtomathieu” that the output of “trigger.for” is HH:MM:SS, such as “1:45:00”. Playing with Dev tools / Template yield something correct for the following:

 {% set mytime = "1:45:00" %}
 "l'appareil a fonctionné sans interruption pendant {{ mytime.split(':')[0]|int*60 + mytime.split(':')[1]|int }} minutes."

Output:

"l'appareil a fonctionné sans interruption pendant 105 minutes."

However I’m getting this error when the automation triggers (I am not forcing execution from configuration, it is being triggered by one of the triggers)

Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème: Error executing script. Unexpected error for call_service at pos 1: Error rendering data template: UndefinedError: 'trigger' is undefined
While executing automation automation.tester_si_le_frigidaire_ou_le_congelateur_reste_ouvert_ferme_trop_longtemps_indiquant_un_probleme
Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème: Error executing script. Unexpected error for call_service at pos 2: Error rendering data template: UndefinedError: 'datetime.timedelta object' has no attribute 'split'

Can you help figure out what’s missing ?

Thanks !

According to the docs the trigger.for variable is a tmiedelta type.

So to get the number of minutes this should work:

          value: >
            {% if trigger.below | int > 0 %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil n'a pas fonctionné pendant {{ ( trigger.for.total_seconds() / 60 )|round(0) }} minutes."
            {% else %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil a fonctionné sans interruption pendant {{ ( trigger.for.total_seconds() / 60 )|round(0) }} minutes."
            {% endif %}

I suppose you were missing a “|” just before round(0), I fixed on my side.

Trying now. Waiting for it to trigger.

Yeah sorry, fixed. I also edited it to use total_seconds() in case the the value was greater than a day.

1 Like

There seems to be another error that I don’t fully understand:

Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème: Error executing script. Unexpected error for call_service at pos 2: unsupported operand type(s) for /: 'builtin_function_or_method' and 'int'
While executing automation automation.tester_si_le_frigidaire_ou_le_congelateur_reste_ouvert_ferme_trop_longtemps_indiquant_un_probleme

Try this:

  value: >
    {% if trigger.below | int > 0 %}
      "Attention, problème avec {{ trigger.entity_id }}, l'appareil n'a pas fonctionné pendant {{ ( trigger.for.total_seconds()|int / 60 )|int }} minutes."
    {% else %}
       "Attention, problème avec {{ trigger.entity_id }}, l'appareil a fonctionné sans interruption pendant {{ ( trigger.for.total_seconds()|int / 60 )|int }} minutes."
    {% endif %}
  • I suggest using trigger.to_state.name to get the entity’s friendly_name (instead of its entity_id).
  • If you want to check if the trigger contained trigger.below then use trigger.below != none
  • The phrase is almost identical in both cases so just substitute the part that’s different.
      - service: input_text.set_value
        data:
          entity_id: input_text.prochain_rappel_a_annoncer
          value: >
            {% set m = "n'a pas fonctionné" if trigger.below != none else "a fonctionné sans interruption" %}
            Attention, problème avec {{ trigger.to_state.name }}, l'appareil {{ m }} pendant {{ (trigger.for.total_seconds() / 60) | int }} minutes.

Not sure if that was part of your edit or if I missed it from the beginning; the error was caused by the absence of parenthesis here: trigger.for.total_seconds()

Including those, without the “int” is now working.

Thank for your help, that was it!

The full working code:

  - id: probleme_congelateur_frigidaire
    alias: Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème
    trigger:
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        below: 90
        for:
          minutes: 80 #80
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        above: 90
        for:
          minutes: 70 #70
      - platform: numeric_state
        entity_id: sensor.congelateur
        below: 80
        for:
          minutes: 140 #140
      - platform: numeric_state
        entity_id: sensor.congelateur
        above: 80
        for:
          minutes: 45 #45
    condition:
    action:
      - service: notify.emailtomathieu
        data_template:
          title: Problem Fridge or Freezer
          message: >
            {% if trigger.below | int > 0 %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.entity_id }}, unit was OFF for {{ trigger.for }} ."
            {% else %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.entity_id }}, unit was ON for {{ trigger.for }} ."
            {% endif %}
      - service: input_text.set_value
        data_template:
          entity_id: input_text.prochain_rappel_a_annoncer
          value: >
            {% if trigger.below | int > 0 %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil n'a pas fonctionné pendant {{ ( trigger.for.total_seconds() / 60 ) | round(0) }} minutes."
            {% else %}
              "Attention, problème avec {{ trigger.entity_id }}, l'appareil a fonctionné sans interruption pendant {{ (trigger.for.total_seconds() / 60 ) | round(0) }} minutes."
            {% endif %}

Taras, thank for the suggestion, it will indeed be cleaner with the friendly name rather than the entity_id, especially for TTS. I’ll look at the other changes a little later today, baby needs attention :slight_smile:

1 Like

Using “trigger.to_state.name” is indeed much cleaner. Thanks for the suggestion.

Final code:

  - id: probleme_congelateur_frigidaire
    alias: Tester si le frigidaire ou le congélateur reste ouvert/fermé trop longtemps, indiquant un problème
    trigger:
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        below: 90
        for:
          minutes: 80 #80
      - platform: numeric_state
        entity_id: sensor.refrigerateur
        above: 90
        for:
          minutes: 70 #70
      - platform: numeric_state
        entity_id: sensor.congelateur
        below: 80
        for:
          minutes: 140 #140
      - platform: numeric_state
        entity_id: sensor.congelateur
        above: 80
        for:
          minutes: 45 #45
    condition:
    action:
      - service: notify.emailtomathieu
        data_template:
          title: Problem Fridge or Freezer
          message: >
            {% if trigger.below | int > 0 %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.to_state.name }}, unit was OFF for {{ trigger.for }} ."
            {% else %}
              "At {{ states('sensor.time') }}, problem with {{ trigger.to_state.name }}, unit was ON for {{ trigger.for }} ."
            {% endif %}
      - service: input_text.set_value
        data_template:
          entity_id: input_text.prochain_rappel_a_annoncer
          value: >
            {% if trigger.below | int > 0 %}
              "Attention, problème avec {{ trigger.to_state.name }}, l'appareil n'a pas fonctionné pendant {{ ( trigger.for.total_seconds() / 60 ) | round(0) }} minutes."
            {% else %}
              "Attention, problème avec {{ trigger.to_state.name }}, l'appareil a fonctionné sans interruption pendant {{ (trigger.for.total_seconds() / 60 ) | round(0) }} minutes."
            {% endif %}

You’re welcome. You should also consider the other suggestion. There’s no need to repeat the entire sentence twice when only a portion of it is different. Also, data_template was deprecated in favor of data many versions ago.

About {% if trigger.below | int > 0 %}, I’m assuming that when trigger.below is greater than zero, then it means trigger.above is, by definition, not greater than zero (i.e. equal to “none”)? The opposite is, I’m assuming, also true?

Unless I’m missing something, this is exactly the same result as testing for “trigger.below != none” ?

Can you elaborate on this “data_template was deprecated in favor of data many versions ago.” ? I was under the impression that “data_template” was required when using a template, like in this case?

Not since 0.115, released in September 2020:

1 Like