What is better to use: timer/delay/for x minutes?

Hi. I was reading about timer component and here a is quick example

- alias: Timerswitch
  id: 'Timerstart'
  # Timer is started when the switch pumprun is set to on.
  trigger:
  - platform: state
    entity_id: switch.pumprun
    to: 'on'
  action:
  - service: timer.start
    entity_id: timer.test

# When timer is stopped, the time run out, another message is sent
- alias: Timerstop
  id: 'Timerstop'
  trigger:
  - platform: event
    event_type: timer.finished
    event_data:
      entity_id: timer.test
  action:
  - service: notify.nma
    data:
      message: "Timer stop"

I would use another trigger:

  trigger:
  - platform: state
    entity_id: switch.pumprun
    to: 'on'
    for:
      minutes: 5

Which example is better to use? Are they the same?

And in some cases I just use a script with services and delays between them. Is it better to use timer?

And little question about timer

Can I set a timer from UI?
Do not want to write exact value in configuration.yaml so I can change it in from UI

Depends what you’re trying to do.

Starting a timer when an entity changes to a certain state and then running an action when that timer completes is different from using the state trigger’s for option. The former will cause the action to run the specified period after the entity initially changes to the specified state, whether or not the entity stays in that state. However, the latter will only cause the action to run if the entity changes to, and then stays in, the specified state for the specified period.

So which one is “better” depends on how you want it to work.

Now I understand the difference
The only question left is setting up a timer from UI. Would like to change the value of timer from UI

P.S. Oh, sometimes it’s difficult for me to say something correct. What is the better way to say that in English?

To use, say, an input_number to specify the number of minutes the timer counts, the best way to do that is to use it in the timer.start service call. Something like this:

  - service: timer.start
    data_template:
      entity_id: timer.test
      duration:
        minutes: "{{ states('input_number.test_timer') | int }}"

The answer probably depends on the context, although one common answer would be “which”.

1 Like

And what if I would like to type leaving time, not minutes (using slider)

Like using input datetime to set waking up time and then set leaving home time

Wake up at: … …
Leave home at … …

Is it possible to do simple math in Home assistant? Leaving home - wake up time = … minutes. And then use these minutes in script?

Sorry if I am too annoying. Thank you

UPD:

Something like this. But working (because, obviously, mine doesn’t work)

  - service: timer.start
    data_template:
      entity_id: timer.leave
      duration:
        minutes: "{{ states('input_datetime.leave_timer') | int - states('input_datetime.alarm_morning') | int}}"

If you configure an input_datetime with “has_time: true” and “has_date: false”, then its timestamp attribute will be the number of seconds from midnight to the set time. If you have two input_datetime entities configured this way then you can use their timestamp attributes to calculate the time between them:

{{ state_attr('input_datetime.leave_home', 'timestamp') -
   state_attr('input_datetime.wake_up', 'timestamp') }}

This results in the number of seconds between them. If you want minutes, then obviously divide the result by 60:

{{ (state_attr('input_datetime.leave_home', 'timestamp') -
    state_attr('input_datetime.wake_up', 'timestamp')) / 60 }}

I did exactly that. Tried your example, got this in log TypeError: unsupported operand type(s) for -: 'str' and 'int' and unsupported operand type(s) for -: 'NoneType' and 'NoneType'

Here is the script

  alias: Testing the timer
  sequence:
  - service: timer.start
    data_template:
      entity_id: timer.leave
      duration:
        minutes: "{{ (state_attr('input_datetime.leave_home', 'timestamp') -
    state_attr('input_datetime.alarm_morning', 'timestamp')) / 60 }}"

And here is full issue from logs

2019-09-23 17:47:38 ERROR (MainThread) [homeassistant.components.script] Error executing script script.15217201925112. Unknown error for call_service at pos 1: 
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 209, in async_turn_on
    await self.script.async_run(kwargs.get(ATTR_VARIABLES), context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 162, in async_run
    await self._handle_action(action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 246, in _handle_action
    await self._actions[_determine_action(action)](action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 329, in _async_call_service
    context=context,
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 88, in async_call_from_config
    template.render_complex(config[CONF_SERVICE_DATA_TEMPLATE], variables)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in render_complex
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in <dictcomp>
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in render_complex
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in <dictcomp>
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 72, in render_complex
    return value.async_render(variables)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 215, in async_render
    return compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'
2019-09-23 17:47:38 ERROR (MainThread) [homeassistant.core] Error executing service <ServiceCall script.15217201925112 (c:16719b2a54894ab7ba1e5545a7b2ea14)>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1242, in _safe_execute
    await self._execute_service(handler, service_call)
  File "/usr/src/homeassistant/homeassistant/core.py", line 1259, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 142, in service_handler
    await script.async_turn_on(variables=service.data, context=service.context)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 214, in async_turn_on
    raise err
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 209, in async_turn_on
    await self.script.async_run(kwargs.get(ATTR_VARIABLES), context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 162, in async_run
    await self._handle_action(action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 246, in _handle_action
    await self._actions[_determine_action(action)](action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 329, in _async_call_service
    context=context,
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 88, in async_call_from_config
    template.render_complex(config[CONF_SERVICE_DATA_TEMPLATE], variables)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in render_complex
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in <dictcomp>
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in render_complex
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 71, in <dictcomp>
    return {key: render_complex(item, variables) for key, item in value.items()}
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 72, in render_complex
    return value.async_render(variables)
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 215, in async_render
    return compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for -: 'NoneType' and 'NoneType'

image

EDIT: However, if I have a typo in the template (e.g., I spell the name of the input_datetime incorrectly), then I’ll see the same error as you’re seeing. Are you sure those two input_datetime entities exist?

Yes, sorry, just understood that I have another input datetime

I have changes it.

  - service: timer.start
    data_template:
      entity_id: timer.leave
      duration:
        minutes: "{{ (state_attr('input_datetime.leave_timer', 'timestamp') -
    state_attr('input_datetime.alarm_morning', 'timestamp')) / 60 }}"

Another issue now…

Firstly, here are input datetimes:

Template works:

And here is timer entity_id:

and when I run the script I get this:

Error executing script script.15217201925112. Invalid data for call_service at pos 1: expected int for dictionary value @ data['duration']['minutes']

Error executing service <ServiceCall script.15217201925112 (c:3eafe71eabd449ebac9d736393f60b82)>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 1242, in _safe_execute
    await self._execute_service(handler, service_call)
  File "/usr/src/homeassistant/homeassistant/core.py", line 1259, in _execute_service
    await handler.func(service_call)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 142, in service_handler
    await script.async_turn_on(variables=service.data, context=service.context)
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 214, in async_turn_on
    raise err
  File "/usr/src/homeassistant/homeassistant/components/script/__init__.py", line 209, in async_turn_on
    await self.script.async_run(kwargs.get(ATTR_VARIABLES), context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 162, in async_run
    await self._handle_action(action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 246, in _handle_action
    await self._actions[_determine_action(action)](action, variables, context)
  File "/usr/src/homeassistant/homeassistant/helpers/script.py", line 329, in _async_call_service
    context=context,
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 98, in async_call_from_config
    domain, service_name, service_data, blocking=blocking, context=context
  File "/usr/src/homeassistant/homeassistant/core.py", line 1212, in async_call
    processed_data = handler.schema(service_data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.7/site-packages/voluptuous/schema_builder.py", line 432, in validate_mapping
    raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: expected int for dictionary value @ data['duration']['minutes']

If it expects an int, then give it an int:

  - service: timer.start
    data_template:
      entity_id: timer.leave
      duration:
        minutes: "{{ (state_attr('input_datetime.leave_timer', 'timestamp') -
    state_attr('input_datetime.alarm_morning', 'timestamp')) // 60 }}"

Yes, I understand that it is pretty obvious. Naively tried to write | int but that did not work. Now with “//60” script works. Thant you

HI,
could I borrow your eyes, just to be sure my error is with using a template (which is not described as an option for delay_off) and not the format for a delay_off ( in my use case) ? I have a related error

Invalid config for [binary_sensor.template]: expected int for dictionary value @ data['sensors']['poort_buiten_motion_sensor_timed']['delay_off']['seconds']. Got "{{states('input_number.presence_timer')|int }}\n". (See ?, line ?). Please check the docs at https://home-assistant.io/components/binary_sensor.template/

and I describe it here https://github.com/home-assistant/home-assistant/issues/26843 and in the community: Wait_template using delay_off in a template

I am even using an |int but maybe should try another way of writing this?

I’m guessing you didn’t use parentheses correctly. You’d need to do this:

  - service: timer.start
    data_template:
      entity_id: timer.leave
      duration:
        minutes: "{{ ((state_attr('input_datetime.leave_timer', 'timestamp') -
    state_attr('input_datetime.alarm_morning', 'timestamp')) / 60) | int }}"
1 Like

Doesn’t look like the delay_off option accepts a template.

yes fear as much. Hoped maybe I made a syntax mistake somehow …

glad I came across this post though, since it adds yet another config (timer: duration) thats uses the same format the delay_off/on should use

Not wanting to barge in here, please let me ask to hop over to my other post, so I can safely ask you how to create a PR for that… please?

You seem to be expecting consistency in a project that is loaded with inconsistencies. There are definitely efforts underway to go back and address some inconsistencies, but not so much in these areas, at least as far as I can see. What you want (i.e., the delay_off option of a template binary sensor to accept a template) is definitely a feature request at this point. Not sure what else to tell you.

Yes, that seems to be the common conclusion for now…

But, since PR’s tend to be more actively pursued by the dev-team than feature requests, I would hope to create a PR on this subject. But only if this could be somehow borrowed from the other already existing templates.

And, you might see it coming, I would hope you could point me in that direction. Ive tried to find where the code for both is, but couldn’t find either.

Need

  1. the code for the regular delay, or now maybe even the code you use here, for the timer, as an example how the template should be implemented.
    And
  2. the code for the delay_off/on in the template binary sensor, to be able to PR it.

If you want to submit a PR to add this feature yourself, then you need to understand how all this stuff works and you’d probably already know where all the relevant code is. :wink: If you need to ask, then … But seriously, if you want to try and do this, then you will need to understand it all, so it’s probably better for you to find your way around yourself than for me to point you in the right direction. It’s more involved than you might think. Good luck!