Weird state inconsistency

Hello. Faily new home-assistant user here, but I write software for a living so writing the configurations and automations feel pretty natural.

However I’ve got a weird thing going on - I’m trying to have a rest sensor update a few times a day, using its’ last_updated timestamp in the url (the api requires a since=timestamp parameter, and it seems like a good idea to set that to when the sensor was last updated).

The thing is, I can’t get the timestamp!

As far as I understand the code should be api/endpoint?since={{state_attr('sensor.my_rest_sensor', 'last_updated')}}, but that always returns None.
In the template editor I can get it using {{ states.sensor.my_rest_sensor.last_updated }}, but that doesn’t work in the sensor config. My guess is that it just isn’t available yet when the sensor is initialized and initialization fails.

So can someone tell me a) why those two don’t return the same value and b) how to solve it? Of course I could just set the timestamp to something like utcnow()-timedelta(hours=3) but it’d be better with the timestamp, for example if updating fails due to some connection problem then it’d get the missing values next time.

And another question related to the same thing. How do I not set the sensor value in certain cases, for example if the api returns an error or there simply isn’t any data since the last update?
Do I just have to check for such cases and return {{ states('sensor.my_rest_sensor') }} or is there some way to just skip it and keep the previous value? If not, what’s the easiest way to fall back to the previous value, is there a way to check if the template hasn’t returned anything yet and return the previous value in that case?

Post your sensor config, need to see what you’re talking about.

last updated is a property on the state object, it’s not an attribute in the attribute property on a state object.

use this.state to reference a previous state. Build your logic to return this.state when you don’t want it to update. Keep in mind, this.state is only available in template entities, not rest entities. So you can’t use that in a rest sensors value_template field.

Also keep in mind that this.state does not exist at startup which can lead to problems. My goto when outputting this.state is to use this line of code

{{ this.state if this.state is defined else none }}

that will keep the value unavailable during the startup sequence because it returns none when it can’t find a state to use. You can also change none to any value if you want it to have a default value.

1 Like

Ah, I saw you replying with that same link in another post, but somehow I thought it wasn’t related. How embarassing, I gotta learn to read :flushed:

Ok, so now I understand why the values aren’t the same - because they aren’t the same. And so to get the last_updated value I’m gonna have to wrap that part in a {{% if ... is defined %}} block, I guess.

that actually won’t work with state objects coming from the state machine because all state objects will appear to be defined, that’s why you should post your code. You may be able to get away with states.<domain>.<object_id>.last_updated is defined as a state object that’s not in the state machine will be none and therefore last_updated will not be defined.

Here’s what I’m doing:

rest:
  - resource_template: >
      {% if states.sensor.rest_sensor.last_updated is defined %}
        {% set timestamp = states.sensor.rest_sensor.last_updated.strftime('%Y-%m-%dT%H:%M:%SZ') %}
      {% else %}
        {% set timestamp = (utcnow()-timedelta(days=1)).strftime('%Y-%m-%d') %}
      {% endif %}
      https://api?since={{ timestamp }}
    headers:
      x-access-token: !secret rest_jwt
      Content-Type: "application/json"
      User-Agent: Home-Assistant
    scan_interval: 3600
    sensor:
      - name: "Rest Sensor"
        unit_of_measurement: "€/l"
        value_template: >
          {% if value_json %}
            {% for entry in value_json[-1:][0].prices %}
              {% if entry.tag == '95' %}
                {{ entry.value }}
              {% endif %}
            {% endfor %}
          {% else %}
            {{ states('sensor.rest_sensor') }}
          {% endif %}

I just changed the timestamp to what I said before and it seems to work.