Rest platform and error handling (with automation)

I have a rest sensor that gets my public ip address :

    sensor:
      - platform: rest
        resource: !secret endpoint_public_ip
        name: public_ip
        value_template: '{{ value_json.ip }}'

and I have an automation on it to warn me when its value changes :

      - id: public_ip_change
        alias: public ip change
        trigger:
          platform: state
          entity_id: sensor.public_ip
        condition:
          - condition: template
            value_template: '{{ states.sensor.public_ip is defined }}'
        action:
          - service: notify.notify
            data:
              ...

It usually works well and as intended.
Except when the rest call stumbles on an error. (timeout, or any other)
In that case, the sensor.public_ip value becomes “unavailable”.
And of course, it triggers the automation.
This is usually very short in time and then the rest call works again and the sensor.public_ip is back as before…
Which triggers the automation again.
This is very annoying and makes my use-case (beeing notified that my public ip changes) not possible.

Any idea on how to fix this ?

Emmanuel

You could try something like this for the template condition:

value_template: >
  {{ trigger.from_state.state not in [none, 'unavailable'] and
     trigger.to_state.state not in [none, 'unavailable'] and
     trigger.to_state.state != trigger.from_state.state }}

EDIT: Actually this might be better:

value_template: >
  {{ trigger.from_state not none and trigger.to_state not none and
     trigger.from_state.state != 'unavailable' and
     trigger.to_state.state != 'unavailable' and
     trigger.to_state.state != trigger.from_state.state }}

the correct syntax is

      value_template: '{{ trigger.from_state != none and trigger.to_state != none and
      trigger.from_state.state != ''unavailable'' and trigger.to_state.state != ''unavailable'' and
      trigger.to_state.state != trigger.from_state.state }}'

(‘not’ is not recognized)

I’m trying this, but I’d prefer a way to fix the rest sensor directly, is there a way ?

Sorry, it was a typo. I meant trigger.from_state is not none, but trigger.from_state != none works, too.

I checked the RESTful Sensor code, and are you sure you’re getting ‘unavailable’? The code sets the state to ‘unknown’ when the REST query fails. So I think my suggested code would be the following instead:

value_template: >
  {{ trigger.from_state is not none and trigger.to_state is not none and
     trigger.from_state.state != 'unknown' and
     trigger.to_state.state != 'unknown' and
     trigger.to_state.state != trigger.from_state.state }}

But, to answer your question, what do you mean exactly by “fix”? I’m pretty sure by design the state is set to “unknown” when the query fails. If you would rather it left the state as-is in that case, then you could copy the code to custom_components/sensor/rest.py in your HA config folder and modify it to do what you want.

Oh, you’re probably right about unknown (my interface is in French).
I changed it, I’m waiting for the issue to reproduce.

By fixing I mean, having the ability to just ignore the data points in the sensor where it is unknown.
Would it be possible with a template sensor ? I searched for it but couldn’t find.

That’s what the automation condition does. :slight_smile:

But to answer your question, the only way I can think of to not have the RESTful Sensor go to a state of unknown when the REST query fails is to change the code. If you want to have another sensor that ignores this sensor’s unknown values, you’d probably have to do that with an input_text and an automation, and the automation would probably have to have the same condition as what I suggested for your original automation. I’m not sure it’s worth the effort.

But maybe someone else reading this topic will think of something that’s not coming to my mind.

I meant ignoring it directly into the sensor, which would solve the problem at the source.
I’d rather not make a custom rest sensor just for this case, so I’m keeping on trying the “automation fix”.

The “unknown” didn’t work (I got a notification when waking up), so I’m adding ‘unavailable’ to the conditions, hoping it’ll work.

the following condition seems to work:

      value_template: >
        {{ trigger.from_state is not none and trigger.to_state is not none and
           trigger.from_state.state != 'unknown' and trigger.to_state.state != 'unknown' and
           trigger.from_state.state != 'unavailable' and trigger.to_state.state != 'unavailable' and
           trigger.to_state.state != trigger.from_state.state }}

It doesn’t trigger on ‘unavailable’.
I’ll have to wait a few weeks/months to see if it still triggers on an actual public ip change, though.

Nice.

For what it’s worth, you could slightly simplify it (and make it easier to exclude other unwanted states) this way:

      value_template: >
        {% set ignore = ['unknown', 'unavailable'] %}
        {{ trigger.from_state.state not in ignore and
           trigger.to_state.state not in ignore and
           trigger.to_state.state != trigger.from_state.state }}

This also seems to correctly handle the situation where trigger.from_state or trigger.to_state are none.