How to handle an error with a REST sensor while offline?

Hi there,

I’m using a rest sensor for access to a REST API like this. (This is Tibber, yes, but this isn’t about Tibber.)

sensor:
  - platform: rest
    name: "Tibber Price"
    resource: https://api.tibber.com/v1-beta/gql
    method: POST
    payload: '{ "query": "{ viewer { homes { currentSubscription { status priceInfo { today { total startsAt } tomorrow { total startsAt } } } } } }" }'
    json_attributes_path: "$.data.viewer.homes[0].currentSubscription.priceInfo"
    json_attributes:
      - today
      - tomorrow
    value_template: "ok"
    scan_interval: 900
    headers:
      Authorization: **-enter-auth-code-here-**
      Content-Type: application/json
      User-Agent: REST
      unit_of_measurement: EUR/kWh

However, my internet connection can be spotty sometimes and my home can be offline for a few minutes at night when my ISP gives me a new IP address.

So, how do I properly handle being offline with a REST sensor? What I want to happen is that the REST sensor doesn’t switch to unavailable and just keeps its old value and attributes while offline.

And if I don’t do this here and the source values, how do I properly handle this with other template sensors using the REST sensor when the latter turns temporarily unavailable?

In my case, several template sensors use the REST sensor result to calculate a schedule when to turn various devices on or off. One night while the REST sensor became unavailable for 15 minutes, the schedule was discarded and the heatpump was turned off because of it, instead of the heatpump just staying on its pre-calculated schedule.

Thanks!

If the goal is to avoid any sensor reporting unavailable then you have a few options:

Only allow the REST sensor to poll the website when it is available

To keep the REST sensor itself from becoming unavailable, the only option is to ensure it doesn’t update when the resource is unavailable. To do that:

  • Set the scan interval to some obscenely large number (or just disable polling entirely)
  • create an automation that will trigger the update using the action homeassistant.update_entity documented here. You would want to only call that service when the resource is available, so perhaps using the ping integration and only running the action if the ping sensor is on. You can trigger a manual update of the ping sensor immediately before you manually update the REST sensor.

Create a new sensor that stores the last “good” value of the REST sensor

Input helpers and trigger-based template sensors are the only native entities in HA that can be used to store persistent data that survives restarts. Of those, trigger-based template sensors are the only ones that allow you to define attributes. So, you can create a trigger-based template sensor that updates whenever your REST sensor updates but then ignores the unavailable state. You would have to create that in YAML. All your other template sensors would then refer to this sensor instead of the REST sensor.

Alternatively, if you’re not worried about the failure mode of starting up HA while the template sensor is unavailable, you can create a normal template sensor, but it will still have to be done in YAML in order to define attributes.

In either case, you’d test for the state to be unavailable. Something like this (untested):

template:
  - trigger:
      - platform: state
        entity_id: sensor.rest_sensor
        attribute: today
    sensor:
      - name: Always available REST sensor
        unique_id: f700e52a-1304-4d47-8bea-5b2c8f4049fe
        state: 'ok'
        attributes:
          today: >
            {{ trigger.to_state.attributes.today if trigger.to_state.state == 'ok' else this.attributes.today }}
          tomorrow: >
            {{ trigger.to_state.attributes.tomorrow if trigger.to_state.state == 'ok' else this.attributes.tomorrow }}

Change all of your template sensors to ignore the unavailable state

Similar to the previous idea, but this is just making the change another step downstream.