Binary sensor - delay_on / delay_off causing errors?

I’ve been using these YAML-configured sensors for several years. In the last week or so, my HA has been giving me some issues, so I’m attempting to squash some errors that have been building up.

This one, I don’t get:

Logger: homeassistant.components.template.template_entity
Source: components/template/template_entity.py:125
Integration: Template (documentation, issues)
First occurred: 8:11:57 AM (21 occurrences)
Last logged: 9:29:19 AM

Error validating template result 'minutes: 2' from template 'Template<template=({% if is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') %} minutes: 2 {% else %} minutes: 10 {% endif %}) renders=32>' for attribute '_delay_off' in entity binary_sensor.xxxxxxx_with_yyyyyyy validation message 'offset minutes: 2 should be format 'HH:MM', 'HH:MM:SS' or 'HH:MM:SS.F''

Here’s the relevant part of my template sensor configuration. Almost all of my template sensors are done in YAML; I may eventually move them to the UI config:

      delay_off: >
        {% if is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') %}
          minutes: 2
        {% else %}
          minutes: 10
        {% endif %}
      delay_on: >
        {% if (is_state('person.xxxxxxx', 'home') or (is_state('person.yyyyyyy', 'home'))) %}
          seconds: 0
        {% else %}
          minutes: 2
        {% endif %}

So… any insights into why these are suddenly throwing errors? Checking the template integration documentation makes me think I’ve got these configured correctly.

EDIT: I found a solution in Reddit… is it just a matter of doing this?

00:{{mm}}:00

…where “mm” is the numeric (like ‘02’ for 2 minutes)?

Thanks

The issue is that the your template ends up supplying a “dictionary-shaped” string instead of the expected dictionary or duration string. There are a number of ways to fix it…

Using a duration string:

delay_off: |
  00:{{- '02' if is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') else '10' }}:00

Templating the value for the minutes key:

delay_off:
  minutes: |
    {{- 2 if is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') else 10 }}
delay_off:
  minutes: |
    {%- if  is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') %}
      2
    {%- else %}
      10
    {%- endif %}

Templating the dictionary using flow-style:

delay_off: |
  {%- set x = 2 if is_state('person.xxxxxxx', 'home') or is_state('person.yyyyyyy', 'home') else 10 %}
  {{- {"minutes": x} }}

Giving this a try, thanks.

Flow-style template is a bust:

      delay_on:
        minutes: >
          {% set time = 0 if is_state('person.xxxx', 'home') or is_state('person.yyyy', 'home') else 2 %}
          {{ {"minutes": time} }}

…results in error:

Logger: homeassistant.config
Source: config.py:352
First occurred: 11:04:59 AM (9 occurrences)
Last logged: 11:13:22 AM

Invalid config for 'template' at templates/templates.yaml, line 921: expected float for dictionary value 'binary_sensor->0->delay_off->minutes', got "{% if is_state('person.xxxx', 'home') or is_state('person.yyyy', 'home') %}\n 2\n{% else %}\n 10\n{% endif %}\n"

That’s not what I showed… what you used would resolve to:

      delay_on:
        minutes:
          minutes: 2

Ahh, sure would. That’s an artifact from a previous attempt…

I wonder what this one means, then (fixed YAML):

      delay_off:
        {% set time = 2 if is_state('person.xxxx', 'home') or is_state('person.yyyy', 'home') else 10 %}
        {{ {"minutes": time} }}
      delay_on:
        {% set time = 0 if is_state('person.xxxx', 'home') or is_state('person.yyyy', 'home') else 2 %}
        {{ {"minutes": time} }}

And resulting error:

Configuration errors
Error loading /config/configuration.yaml: while scanning for the next token
found character '%' that cannot start any token
  in "/config/templates/templates.yaml", line 890, column 10

Likely, it’s because you left the multiline quote indicators out…

delay_off: vs. delay_off: |

Arrgh, thanks. It was in the minutes key I deleted…

That one checked out OK:

      delay_off: >
        {% set time = 2 if is_state('person.xxxx', 'home') or is_state('person.yyyy', 'home') else 10 %}
        {{ {"minutes": time} }}

Thanks for hanging in there with me.