Condition: when time is two hours BEFORE present time?

More or less beginner HASS user here. I am trying to make an automation where my car engine heater starts heating based on time that user has selected on UI, but based on what temperature it is outside. For example, if user has told HASS that he is going to leave at 7:00, HASS turns car heater on, say, 2 hours before (that is 5:00) IF temperature outside is below -10C, but only one hour before if temperature outside is below 0 but above -10C.

    trigger:
      - platform: template
        value_template: '{{ states.sensor.time.state == states.sensor.alarm_clock_time_long.state }}'

states.sensor.alarm_clock_time_long.state is input_number that user has selected as leaving time.

I was going to put separate triggers based on different conditions, but how should I write into this that “states.sensor.alarm_clock_time_long.state - 2 hours” ? :slight_smile:

Below is the code for my bedroom alarm clock package. The trigger for the automation is to activate fifteen minutes before the time it is set to. I do this so if there is bad weather then it wakes me up 15 minutes early, if not it waits 15 minutes and goes off at the time set.

In the template the “15 * 60” is the 15 minutes, so for two hours you would want 120 * 60.

Hope this helps.

link removed

1 Like

Thank you for this, I thought I could get my solution to work using your example, but although code seems to go through without errors, it does not work. Here’s the automation part:

  - alias: 'Heater on'
    hide_entity: false
    trigger:
      - platform: template
        value_template: "{{ states('sensor.time') == (((state_attr('sensor.alarm_clock3_time_long.state' , 'timestamp')) - (180 * 60))|timestamp_custom('%H:%M', false)) }}"
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: automation.heater_on
          state: 'on'
        - condition: numeric_state
          entity_id: sensor.temperature
          above: 2
    action:
      - service: switch.turn_on
            entity_id: switch.sonoff_pow_tallu
      - delay: '00:03:00'
      - service: switch.turn_off
        entity_id: switch.sonoff_pow_tallu

For testing purposes this automation should turn the switch on three minutes before set time, if outside temperature is above 2C (and it is :slight_smile: ). This automation works, if I use value_template line in my original post, but with this code I think it has something to do with values not being identical so this automation never triggers. I am not sure I am using the template editor / testing page right, but when the left part of that trigger shows current time correctly, the right part just returns “false”.

In fact, I thought for me it was easiest to add three automations with same trigger, but with different conditions and actions. In my unmodified code I want to trigger this automation three hours before set time IF outside temperature is below -10C, two hours before if temperature is below -5C and one hour before if temperature is below 0C. I think I could only check the temperature once three hours before, and then either turn switch on right away or delay it by one or two hours based on temperature, but even then I don’t know how to make that trigger work (so that states.sensor.time.state is equal to states.sensor.alarm_clock_time.long.state minus three hours) :confused:

I’m not quite sure I get you unfortunately.

When you say “but when the left part of that trigger shows current time correctly, the right part just returns “false”.” that would be correct because the time needs to be 3 hours ago for it to return true.

You have to be quite quick to test this template with the dev tool because it won’t update as time passes, so you can would need to set your alarm time for 3 hours and 1 minute from the current time, wait until the clock ticks over for 3 hours and then paste the template into the dev tool within 59 seconds.

If it is still returning false at this point, try changing the word false in the template to true and retest. If this doesn’t result in an epiphany, post us a couple of screenshots showing what your setting for the alarm tim is, and what the template is outputting and we can probably get to the bottom of it :+1:

I meant I tried to get some output from individual commands using template editor, as I noticed that is more or less the only way in hass.io I can “track code” so to speak, to see what values I am going to compare in trigger part. So when I type on the left side:

{{ states(‘sensor.time’) }}

Then on the right side window I get output:
14:59

for example. And that’s what I meant whenI said “left part of that trigger” :slight_smile: But when I pasted this on the left side:
{{ (((state_attr(‘sensor.alarm_clock3_time_long.state’ , ‘timestamp’)) - (180 * 60))|timestamp_custom(’%H:%M’, false)) }}
I get blank screen on the right side (so I remembered wrong when I said it says “false” on the right side, that probably happened when I tried only parts of that code). Sorry that this is confusing when I talk about left and right sides of template testing window and left and right side of trigger :smiley:

I am pretty sure this code of mine does not work because “the right side” of my trigger code:(((state_attr(‘sensor.alarm_clock3_time_long.state’ , ‘timestamp’)) - (180 * 60))|timestamp_custom(’%H:%M’, false))
never returns time as output, unlike the left side (states(‘sensor.time’)) and that’s why it can never trigger. Or how can I test, what actually that long line of code on the right side actually returns?

That’s what I’m saying, if you paste the whole template into the editor it should return true if the alarm time is exactly three hours from the current time, or false if it is not.

I’ve also realised that you’re using some calculation to create a ‘long’ for the alarm time, whereas I’m using an input_datetime for mine, so the attribute may not be correct for yours and may need to be tweaked.

At some point I thought “long” is not right but my automation trigger on my first post works correctly (there I just select time from slider). Like this:

But the thing is, that editor doesn’t return anything at all, if I put the whole trigger statement there, the whole preview windows goes blank:

Yeah, you probably need to convert the value of the sensor.alarm_clock_long to a timestamp,

So it will be

{{ (((states(‘sensor.alarm_clock3_time_long.state’) |timestamp) - (180 * 60))|timestamp_custom(’%H:%M’, false)) }}

Or something similar.

@petro - give me a clue as to what to pipe states('alarm_clock3_time_long.state’) to for the correct result please?

1 Like

Not sure if this would work in template editor, but when I tried to put it there, I got error saying "Error rendering template: TemplateAssertionError: no filter named ‘timestamp’ ".

Indeed, because the template is looking for an attribute that doesn’t exist at the moment.

What we have to do is convert the ‘long’ value in to a timestamp, but I’m not sure how to do it which is why I tagged @petro , who will no doubt fix it :slight_smile:

Is that timestamp supposed to be for today always?

{% set d = now().strftime("%m/%d/%Y ") %}
{% set t = strptime(d+sensor.alarm_clock3_time_long.state,"%m/%d/%Y %H:%M") %}
{{ ( as_timestamp(t) - 180*60 ) | timestamp_custom('%H:%M') }}

This should get you the time 3 hours beforehand, in the local timezone.

EDIT: To clarify, you need to add todays date to your sensor time to use the function as_timestamp in conjunction with strptime. Strptime will take a string and turn it into a datetime object. If you omit the date, it sets your date to be jan 1st 1970 at whatever time is placed into the strptime. So, just add todays date, convert to a timestamp, subtract the number of seconds, then convert back into a string.

2 Likes

Thank you @petro ! That code works perfectly in template editor (after I added states. in front of sensor, but that’s probably just because of how template editor works), and this outputs time that is exactly three hours before what user has selected on UI.

However, I seem to have trouble in where exactly I should put this code? I am thinking in value_template line under trigger (see my first post), in place of that states.sensor.alarm_clock_time_long.state but naturally it doesn’t work that way. Or maybe I should paste that code somewhere else (where?) and then use trigger something like as this?

 value_template: '{{ states.sensor.time.state == d }}' 

Sorry about stupid questions :blush:

Yeah, use it for the trigger like this

trigger:
  platform: template
  value_template: >
    {% set d = now().strftime("%m/%d/%Y ") %}
    {% set t = strptime(d+states.sensor.alarm_clock3_time_long.state,"%m/%d/%Y %H:%M") %}
    {{ ( as_timestamp(t) - 180*60 )|timestamp_custom('%H:%M') }}
1 Like

Thank you, but it doesn’t seem to work :expressionless: Code itself is valid, but switch is not turning on. Here’s the whole automation (I changed three hours to one minute for testing purposes:

automation:
  - alias: 'Heater on'
    hide_entity: false
    trigger:
      - platform: template
        value_template: >
          {% set d = now().strftime("%m/%d/%Y ") %}
          {% set t = strptime(d+sensor.alarm_clock3_time_long.state,"%m/%d/%Y %H:%M") %}
          {{ ( as_timestamp(t) - 1*60 )|timestamp_custom('%H:%M') }}

    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: automation.heater_on
          state: 'on'
        - condition: numeric_state
          entity_id: sensor.outsidetemp
          above: 2
    action:
      - service: switch.turn_on
        entity_id: switch.sonoff_pow_tallu
      - delay: '00:02:00'
      - service: switch.turn_off
        entity_id: switch.sonoff_pow_tallu

All switches and entities are right, so that shouldn’t be it. I am not sure if value expression is right, as configuration seems to be okay, no matter if I change it to value_template >- (as I have seen that as well in other configurations), or remove double brackets from as_timestamp -line , but the switch does not turn on, no matter what.

Are you trying to make it trigger at that time?

Yes, so I can see if this works or not :slight_smile: For example, I set clock slider on UI to five minutes from now, then with this code I assume the automation should trigger four minutes from now, turn my switch on for 2 minutes and then the switch turns off again. But it never turns on :confused:

Wish I understood all these time comparison functions :smile:

Try this…

automation:
  - alias: 'Heater on'
    hide_entity: false
    trigger:
      - platform: template
        value_template: >
          {% set d = now().strftime("%m/%d/%Y ") %}
          {% set t = strptime(d+sensor.alarm_clock3_time_long.state,"%m/%d/%Y %H:%M") %}
          {{ state('sensor.time') == ( as_timestamp(t) - 1*60 )|timestamp_custom('%H:%M') }}
    condition:
      - condition: state
        entity_id: automation.heater_on
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.outsidetemp
        above: 2
    action:
      - service: switch.turn_on
        entity_id: switch.sonoff_pow_tallu
      - delay: '00:02:00'
      - service: switch.turn_off
        entity_id: switch.sonoff_pow_tallu
1 Like

Oh, me too, for sure! :smiley: Unfortunately, this didn’t work either. Switch doesn’t turn on when it should :confused:

On the 9th line, first word, change it to states (with an S on the end)

That makes sense, but it didn’t fix it :confused: