Automation based calculated variables/times

Hi,

i’d like to send out notifications for the following usecase:

  • Window is open and outside temperature < 20°C
  • calculate the time for ventilation based on outside temperature +5mins
  • send out a notification when calculated time is due

Without calculating times based on outside temperatures, i’m ready to send notifications

- id: '1001'
  alias: Window still open!
  trigger:
  - entity_id: binary_sensor.hmsecsco_oeq1555241_state
    from: off
    platform: state
    to: on
  condition:
    condition: template
      value_template: '{{ sensor.dark_sky_temperature < 20 }}'
  action:
  - data:
      data:
        priority: 0
        sound: pianobar
      message: Close window!
      title: Window warning
    service: notify.pushover

But calculating doesn’t seem to be possible… any ideas? Perhaps integrating a shell script or webservice?

Greets
Peter

that condition will not work. it needs to be like:
`value_template: ‘{{ states(“sensor.dark_sky_temperature”) | int < 20 }}’

What is the formula that you want to use? If you share I can help convert it into yaml

Hi,

thanks for the hint - i will look after the condition. The formular would be “sensor.dark_sky_temperature + 5 minutes” for all outside temperatures below 20…

Thanks
Peter

You almost had the time, I think this works

‘{{ states(“sensor.dark_sky_temperature”) | int +5 }}

and set upper and lower condition limits, like if < -15C , shut the window

also, you can use this to try your statements

1 Like

I think you’ve highlighted the wrong icon!
Didn’t you mean this one?
image

…the template works when checking it via the template editor, but i can’t use it as a value for the “for”-statement:

- id: '1501'
  alias: Fensterwarnung
  trigger:
  - entity_id: binary_sensor.hmsecsco_oeq1555241_state
    for: 
      minutes: value_template: "{{ states('sensor.dark_sky_temperature') | int +5 }}"
    from: 'off'
    platform: state
    to: 'on'
  condition:
  - below: '20'
    condition: numeric_state
    entity_id: sensor.dark_sky_temperature
  action:
  - data:
  data:
    priority: 0
    sound: pianobar
  message: Fenster im Wohnzimmer offen
  title: Fensterwarnung
service: notify.ios_peters_iphone_xs

If i type “minutes: 5”, everythings works fine except that it’s limited to a 5 minute delay instead of a calculation… any more ideas on this?

Thanks
Peter

What you’re trying to do is not possible. You cannot place a value template anywhere you want. It can only go into specific sections in automations. Those sections are:

platform templates:

trigger:
  - platform: template
    value_template: {{}}

conditional templates

condition:
  - condition: template
    value_template: {{}}

data_templates, service_templates, delay, and wait_template:

action:
  - service_template: {{}}
    data_template:
      some_attribute: {{}}
  - delay: {{}}
  - wait_template: {{}}

Also, take a second and think about what you are trying to do. When it’s below 20 minutes, you want to send a message 20 + 5.

What happens when the temperature is dropping rapidly? I.E. 1 degree a minute? Does the trigger reset each time the temperature drops?

If you’re 1 minute away from trigger and the temp jumps up 5 but is still below 20. Do you add 5 or reset the timer?

If you’re 1 minute away from the trigger and the temp drops 5 degrees. Do you trigger immediately or reset?

This type of automation is very complicated and it would need something other than a normal automation. In the end, is this really what you want to do?

Are there any attributes of an entity (for example a binary sensor) that are accessible that gives a timestamp of the last time the entity changed state?

If so that could be used in the template trigger value_template.

Oh yeah, but they aren’t attributes, they are python properties. State objects have the following properties:

property description
state.state String representation of the current state of the entity. Example off .
state.entity_id Entity ID. Format: <domain>.<object_id> . Example: light.kitchen .
state.domain Domain of the entity. Example: light .
state.object_id Object ID of entity. Example: kitchen .
state.name Name of the entity. Based on friendly_name attribute with fall back to object ID. Example: Kitchen Ceiling .
state.last_updated Time the state was written to the state machine. Note that writing the exact same state including attributes will not result in this field being updated. Example: 2017-10-28 08:13:36.715874+00:00 .
state.last_changed Time the state changed. This is not updated when there are only updated attributes. Example: 2017-10-28 08:13:36.715874+00:00 .
state.attributes

Documented here:

EDIT:

They can’t be accessed using methods, they can only be access via the object. What do I mean by that?

These types of methods will not work because they only access the state.state property and the state.attributes property:

states('light.laundry')
state_attr('light.laundry','attribute')
is_state('light.laundry','on')

The only way to access those other properties is through the object itself:

states.light.laundry.state
states.light.laundry.entity_id
states.light.laundry.domain
states.light.laundry.object_id
states.light.laundry.name
states.light.laundry.last_updated
states.light.laundry.last_changed
states.light.laundry.attributes
1 Like

then, based on the info above from @petro try something like this in your trigger:

trigger:
  - platform: template
    value_template: '{{ (as_timestamp(states.binary_sensor.hmsecsco_oeq1555241.last_changed)|timestamp_custom("%m")|int) + states('sensor.dark_sky_temperature') | int   }}'

that should extract the number of minutes since the last change and add 5 minutes + the darksky temp to that number and then trigger.

Then you’ll have to add in a condition that only allows it to run if the state was changed to ‘on’ or it will also run when the state changes to ('off + temp + 5):

condition: state
entity_id: hmsecsco_oeq1555241
state: 'on'

That value template needs to return a true/false and it could work but a device that updates regularly will hard to work with. Also, there’s really no way to track the state before during and after, which is pretty much the problem. You’ll always be checking at the start and at the end or just at the end.

Crap! you’re right of course. I forgot to add that bit from my test template

This should be better:

trigger:
  - platform: template
    value_template: '{{ ((as_timestamp(states.binary_sensor.hmsecsco_oeq1555241.last_changed)|timestamp_custom("%m")|int) + states('sensor.dark_sky_temperature') | int + 5 ) == now().strftime("%m")|int }}'

But should it matter how often it updates as long as you just care whether it has been longer than x minutes since the last change?

Not really following you here.

Yeah, but he’s trying to make sure it’s below 20 for x minutes. If the device updates, the value template gets re-evaluated and starts over. Plus, last_updated will be zero at that point in time (because it just updated).

You gotta be able to check last updated periodically. But if you do that and it’s always updating, then it’s essentially worthless because your last_updated vrs now will always be a static value.

Well his original goal was to make sure that the temperature was below x for x minutes, but he wants the minutes to be variable.

The combination of the 2 is a very difficult automation. Personally, I can’t think of a way to make the variable time work on the fly. Even with a more powerful automation tool, I can’t really think of a way.

I guess he could make a template sensor that monitors the temperature and use the sensor.time component

sensor:
  - platform: template
    sensors:
      window_temperature_status:
        value_template: > 
          {{ is_state('binary_sensor.hmsecsco_oeq1555241_state','on') and states('sensor.dark_sky_temperature') | float < 20 }}

  - platform: time_date
    display_options:
      - 'date_time'

Then in his automation could do this that checks every minute:

- alias: Window Notification
  trigger:
    - platform: template
      value_template: >
        {% set now_seconds = as_timestamp(strptime(states.sensor.date__time.state, "%Y-%m-%d, %H:%M")) %}
        {% set sensor_seconds = as_timestamp(states.switch.laundry.last_updated) %}
        {{ (now_seconds-sensor_seconds) / 60 > ( states('sensor.dark_sky_temperature') | float + 5 ) }}
  action:
  - service: notify.pushover
    data:
      message: Close window!
      title: Window warning
      data:
        priority: 0
        sound: pianobar

that’s why I’m using “last_changed” not “last_updated”

I’m not sure that’s correct.

I think they want to use the following formula for the minutes:

then check that that the binary sensor has been on for that long before triggering the automation.

But also make sure the temp is less than 20. They have that in the condition already.

At least that’s what I’m getting from reading the info in posts 1, 3 & 6.

and the variable that they want to use is the darksky temperature, which I’ve included in the template.

I guess we need to let the OP post back with clarification on what they want exactly.

Hi guys,

thanks very much for all input you’ve shared here, much appreciated. @finity is right, the delay for the trigger to start should be “sensor.dark_sky_temperature + 5 minutes” for all temperatures below 20°C.

To explain this: I want the rooms to be ventilated but avoid cooling down the flat too much in winter time. If it’s summer (everything above 20°C is fine), windows can stay open as long as anyone wants. But in winter time i would spend to much energy heating up the rooms to 18-20°C when the windows are open for a longer time than needed to ventilate them. The time needed to ventilate must be variable since the recommendation for ventilating rooms is that outside temperature +5mins rule… which isn’t very exact since it will fail for minus temperatures which occur sometimes in winter… but forget that, i would take care of that later when the basic automation works. Also what happens if someone closes the window again, the trigger should stop and not send any notifications…

Since i don’t expect outside temperature drops of more than 3-4°C within 30 minutes i wouldn’t say that iterating the changes of the outside temperature are nothing i have to look at. If temperature drops more than that, open windows should be my least problem :joy:

I’m going to experiment with the suggestions, many thanks so far - i will update the thread asap.

Best
Peter

Ok, this automation should do it for you. It checks the window every minute when it’s open. When you’ve reached the temperature+5 minutes from the last time it changed, it will trigger.

- alias: Window Notification
  trigger:
    - platform: template
      value_template: >
        {% if is_state('binary_sensor.hmsecsco_oeq1555241_state','on') %}
          {% set now_seconds = as_timestamp(strptime(states.sensor.date__time.state, "%Y-%m-%d, %H:%M")) %}
          {% set sensor_seconds = as_timestamp(states.binary_sensor.hmsecsco_oeq1555241_state.last_changed) %}
          {{ (now_seconds-sensor_seconds) / 60 > ( states('sensor.dark_sky_temperature') | float + 5 ) }}
        {% else %}
          False
        {% endif %}
  action:
  - service: notify.pushover
    data:
      message: Close window!
      title: Window warning
      data:
        priority: 0
        sound: pianobar
1 Like

Perfect, you got it - many thanks!

Added %} after the first if-Statement and it worked immediately.

Best regards
Peter

Oops, made that change.