Problem with automation (numeric state and specific time)

Hi all,

I’ve got a automation rule for traffic observation and notify if the value of my google_travel_time sensor is bigger than 25 min. This notification should be only executed an work days and for example between 6 and 8 am.

This is what I’ve done:

- alias: Home to work
  trigger: 
    - platform: numeric_state
      entity_id: sensor.traffic_home2work
      above: 25
  condition:
    condition: and
    conditions:
      - condition: time
        after: '06:00:00'
        before: '08:00:00'
        weekday:
        - mon
        - tue
        - wed
        - thu
        - fri
  action:
    service: notify.telegram
    data_template:
      message: > 
        Much traffic on the road. {{ states("sensor.traffic_home2work") }} min.

It works but I’ve got a few advanced requirements:

  • If traffic sensor is above 25 min BEFORE 6:00 the automation won’t be executed yet. For example traffic sensor changes to 26 min on 5:45 and stays until 6:00 so I would like to be notified on 6:00.
  • Execute automation only if the sensor state changes by 5 minutes. For example if the sensor changes from 26 to 27 it is not a big deal but if it changes from 26 to 31 I would like to be notified.

Do you have any suggestions?

Thanks,
sti0

The first question should be fairly easy, just add a trigger at 6:00 and a condition to check the value. Try this:

- alias: Home to work
  trigger: 
    - platform: numeric_state
      entity_id: sensor.traffic_home2work
      above: 25
    - platform: time
      at: '06:00:00'
  condition:
    - condition: and
      conditions:
        - condition: numeric_state
          entity_id: sensor.traffic_home2work
          above: 25 
        - condition: time
          after: '06:00:00'
          before: '08:00:00'
          weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    service: notify.telegram
    data_template:
      message: > 
        Much traffic on the road. {{ states("sensor.traffic_home2work") }} min.

As for the second question, I’ll have to think about the easiest way to do that…

For the second part, are you wanting it to trigger when it changes 5 in a single update, or 5 from the last time you were notified? If it’s the former, you can use a template condition with {{ abs(trigger.to_state.state - trigger.from_state.state) >= 5 }}. For the latter, you’d probably need to save the value off somehow every time the automation executes. I can think of several ways to do that, but none of them are exactly trivial to do from an automation (e.g. MQTT, write to a file, use REST API to update a sensor value, etc).

@brg468

Thank you. It works like a charm!

@tboyce1
Great idea. I would like to be notified if the state changes more than 5 minutes after last notification. I have to think about the implementation. Beside the last notified value, I need further information like last notify timestamp (e.g. 5 minute rule should be ignored on the next day and should notify immediatly). Another possibility is to reset the sensor value to 0 after 8:00 am…I think I will try it with MQTT.

Thank you so much.

Hey guys,

I just wanna give a update on my implementation. As mentioned by @tboyce1 I used a MQTT sensor to save the old drive time. The sensor with the old drive time is set to 0 at 8:01 in a second automation.

My automation looks like this now:

  automation: 
    - alias: Home to work
      trigger: 
        - platform: numeric_state
          entity_id: sensor.traffic_home2work
          above: 25
        - platform: time
          at: '06:00:00'
      condition:
        - condition: and
          conditions:
            - condition: numeric_state
              entity_id: sensor.traffic_home2work
              above: 25 
            - condition: time
              after: '06:00:00'
              before: '08:00:00'
              weekday:
              - mon
              - tue
              - wed
              - thu
              - fri
        - condition: template
          value_template: "{% if states('sensor.traffic_home2work') | float > states('sensor.traffic_home2work_old') | float %}true{% else %}false{% endif %}"
      action:
        - service: notify.telegram
          data_template:
            message: > 
              Much traffic on the road. {{ states("sensor.traffic_home2work") }} min.
        - service: script.turn_on
          data:
            entity_id: pub_mqtt_traffic_home2work

  - alias: reset_mqtt_traffic_home2work
    trigger:
      - platform: time
        at: '08:01:00'
    action:
      - service: script.turn_on
        data:
          entity_id: pub_mqtt_traffic_home2work

script:
  pub_mqtt_traffic_home2work:
    sequence:
      - service: mqtt.publish
        data:
            payload_template: "{% if  now().strftime('%H:%M') >= '08:01' %} 0 {% else %} {{ states('sensor.traffic_home2work') }} {% endif %}"
            qos: 0
            retain: true
            topic: home/traffic/home2work

Thank you again for your help, @brg468 and @tboyce1 :slight_smile:

Assuming sensor.traffic_home2work_old is your MQTT sensor and is only updated whenever you publish a new value, you don’t necessarily need to reset the value at 8:00. Another option is to use the last_updated attribute of the sensor to tell if it was updated recently enough to use it.

If you change your condition to

value_template: {{ (now() - states.sensor.traffic_home2work_old.last_updated).total_seconds() / 3600 > 3 or states('sensor.traffic_home2work') | float > states('sensor.traffic_home2work_old') | float }}

then it will trigger if traffic_home2work_old hasn’t been updated in the last 3 hours (since it only updates in a 2 hour window, this would mean it hasn’t updated since the day before, with a small buffer so it doesn’t falsely trigger at the end of the window) or if the value is greater than the last time reported.

Then you can remove reset_mqtt_traffic_home2work automation and the if/else check in pub_mqtt_traffic_home2work.

Going a bit further, you can probably even use a template sensor for traffic_home2work_old:

sensor:
  sensors:
    # If the time is between 6:00 and 8:00, update the value only if traffic_home2work
    # has increased above the last trigger value, otherwise leave it unchanged.
    # If the time is not between 6:00 and 8:00, reset the value to 0.
    traffic_home2work_trigger:
      entity_id: sensor.traffic_home2work
      unit_of_measurement: min
      value_template: >
        {%- if '06:00' <= now().strftime('%H:%M') <= '08:00' -%}
          {%- if states('sensor.traffic_home2work') | float > states('sensor.traffic_home2work_trigger') | float -%}
            {{states.sensor.traffic_home2work}}
          {%- else -%}
            {{ states.sensor.traffic_home2work_trigger }}
          {%- endif -%}
        {%- else -%}
          0
        {%- endif -%}
        
automation:
- alias: Home to work
  trigger: 
    - platform: numeric_state
      # Use traffic_home2work_trigger here, that way we don't need the template condition anymore
      entity_id: sensor.traffic_home2work_trigger
      above: 25
    - platform: time
      at: '06:00:00'
  condition:
    - condition: and
      conditions:
        - condition: numeric_state
          # Leave this using traffic_home2work so it works for the time-based trigger
          entity_id: sensor.traffic_home2work
          above: 25 
        - condition: time
          # Probably don't need after or before since the trigger sensor will always be 0 outside of that range
          after: '06:00:00'
          before: '08:00:00'
          weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
  action:
    - service: notify.telegram
      data_template:
        message: > 
          Much traffic on the road. {{ states("sensor.traffic_home2work") }} min.

Note: I haven’t tested this so the syntax may a bit off or there may be some issues but it should give you the general idea if you want to try to go this route.

Thanks, for your advice @tboyce1.

I’ve implemented this but didn’t get the right result today (implemented it in a slightly different other way). Will double check this at the weekend and test it next week and finally report my solution back :slight_smile:

Have a great weekend!

@tboyce1,
I’ve tested your solution but this won’t work the way it is meant to be.

I think the template sensor updates it self immediately after the update of the traffic sensor. Therefore the sensors are always the same value (except the time is out of range, than the template sensor is 0). There is nothing to compare with For now I stay with the MQTT solution which runs very well.

Maybe I come back to this topic later. I appreciate your help! Thanks!