Automation - platform:state not triggerring on state change

I’m doing temperature monitoring, and I want to know when the system goes out of valid, as well as when it recovers.

I’ve tried it a couple of different ways, but the way that ‘seems’ the most appropriate is using a sensor template

sensor:
 - platform: template
    sensors:
      temp_status:
        unit_of_measurement: "status"
        value_template: >-
          {% if is_state('sensor.temp', 'unknown') %}
            unknown
          {% elif states('sensor.temp')|float < 60 %}
            low
          {% elif states('sensor.temp')|float > 80 %}
            high
          {% else %}
            valid
          {% endif %}

Note, there is a (working) sensor at ‘sensor.temp’ reading the temperature, no issues there.

This gives me something I can trigger on when the state changes. So, I created an automation as follows, which I thought would trigger on state ‘changes’. (ie; trigger platform state)

automation:
  - id: templow_notification
    alias: 'Temp Notification (Low)'
    trigger:
      platform: state
      entity_id: sensor.temp_status
      to: 'low'
    action:
      service: notify.mail
      data_template:
        title: "Temperature is too low"
      message: "Monitored temperature is too low {{ states.sensor.temp.state }}"

 - id: tempnotlow_notification
    alias: 'Temp Notification (Low->Valid)'
    trigger:
      platform: state
      entity_id: sensor.temp_status
      from 'low'
      to: 'valid'
    action:
      service: notify.mail
      data_template:
        title: "Temperature has recovered"
      message: "Monitored temperature is now valid {{ states.sensor.temp.state }}"

I’ve got two similar automations to identify high and recovery from high temperature.

Unfortunately, I’m now CONSTANTLY bombarded with messages every 10-15 minutes telling me that my temperature is too low. Note, I intentionally only added the to: ‘low’ in the temp alert, because if I restart home assistant, it loses the sensor.temp value until it gets a new one, so the template sensor goes into ‘unknown’ status. And, I don’t want to duplicate the alert from ‘valid’ -> ‘low’ and ‘unknown’ -> ‘low’ since they are identical, I just want to know when the state changes from anthing to ‘low’.

Per the docs
### STATE TRIGGER

Triggers when the state of a given entity changes. If only  `entity_id`  is given trigger will activate for all state changes, even if only state attributes change.

That implies that it should only trigger at state changes, but if the temperature is too low, the automation is run every few minutes, constantly bombarding me with notifications. I know it’s too low, so I want it to just notify me when the state changes, not just when it gets another non-changing sensor update.

Thanks in advance!

Nate

This is confusing. Which is it?

just add a condition checking the state

  condition:
  - condition: template
    value_template: "{{ trigger.from_state.state != trigger.to_state.state }}"

That will only fire on state changes and you won’t have to specify a ‘from’.

So if your trigger is this:

    trigger:
      platform: state
      entity_id: sensor.temp_status
      to: 'low'

it won’t fire if the state updates from ‘low’ to ‘low’ it won’t trigger but will trigger if ‘x’ to ‘low’.

@tom_l Sorry, it should have read:

I’m NOW constantly bombarded

Instead of I’m not constantly …
(:facepalm)

1 Like

did you attempt to include the condition?

Thanks, I’ll try that. However, I would assert the documentation is misleading, because it’s triggerring on non-state changes if only one of from or to is provided. The above suggestion causes it to filter out non-state changes which is a great suggestion to avoid having to duplicate the code.

Nate

@petro - Unfortunately, that didn’t appear to work. I updated to include the change, and I just got another ‘too low’ notification.

This is my automation currently.

- id: templow_notification
  alias: 'Temp Notification (Low)'
  trigger:
    platform: state
    entity_id: sensor.garage_temp_status
    to: 'low'
  condition:
  - condition: template
    value_template: "{{ trigger.from_state.state != trigger.to_state.state }}"
  action:
    service: notify.mail
    data_template:
      title: "Temperature is too low"
      message: "Monitored temperatureis too low {{ states.sensor.
garage_temp.state }}"

change your message to

- id: templow_notification
  alias: 'Temp Notification (Low)'
  trigger:
    platform: state
    entity_id: sensor.garage_temp_status
    to: 'low'
  condition:
  - condition: template
    value_template: "{{ trigger.from_state.state != trigger.to_state.state }}"
  action:
    service: notify.mail
    data_template:
      title: "Temperature is too low"
      message: "Monitored temperatureis too low {{ trigger.from_state.state }} -> {{ trigger.to_state.state }}"

Good catch. I know what happened. When I restarted, the from_state == ‘unknown’ until a message went through. Then, it went from ‘unknown’ -> ‘low’ and triggerred (correctly as I want). Now, I have to wait for a few minutes to see if it triggers again.

So, I may have jumped the gun saying this didn’t work, when it was behaving as expected.

I’ll know more in about 15 minutes when another reading is made.

But, I think this is working now. Thanks again!

Nate

1 Like

Followup:

Thanks to the suggestion from @petro, it turns out that it’s all my fault. I moved the sensor to a remote location with expensive IP connectivity, so I changed the update frequency from once/minute to once/5 minutes.

Why should that matter? In my sensor description above, if the sensor value is invalid/not known, it changes the state to ‘unknown’. So, if I lost a single sensor value and/or the timing was just right (wrong?), then the state changed from ‘low’ -> ‘unknown’, and then it kept triggerring again from ‘unknown’ -> 'low.

The solution:

   - platform: mqtt
     name: "Garage Temp"
     state_topic: "garage/sensor"
-    expire_after: 300
+    expire_after: 600

Doing this fixed the issue so that the state changes to unknown don’t happen as often, so I think I can remove the condition now.

However, I would have never thought that, so thanks again for the help, and now I know more about both condition and the ‘trigger.from_state’ capability.

Well, glad you got it sorted out.