Sensor - display last known value instead of 'unavailable'

I dont think that you can ref a template sensor within itself.

any other ideas?

Define a filter sensor with lower and upper bounds with a range filter. This will not display NaNs.

sensor:
- platform: filter
  name: "filtered zappi house"
  entity_id: sensor.zappi_house
  filters:
    - filter: range
      lower_bound: -20000
      upper_bound: 20000
2 Likes

I hade same problem and I have the solution only if you are connected to the cloud. So if your shelly is connected to the cloud you should create REST sensor which will pull data from the cloud.

  • platform: rest
    name: temp_cloud_db # temperature reading from shelly cloud
    unit_of_measurement: ‘°C’ #added unit of measurement, °C in my case
    resource: https://shelly-5-eu.shelly.cloud/device/status # my shelly cloud server
    method: POST
    payload: ‘auth_key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’ #you sholud retrieve your from the app
    scan_interval: 86400
    headers:
    User-Agent: Home Assistant
    Content-Type: application/x-www-form-urlencoded
    value_template: ‘{{ value_json.data.device_status.tmp.value }}’

With this I have new sensor in HA which retrieve temperature readings from the cloud.
Next step is creating TEMPLATE sensor for temperature which will take temperature from your shelly or in other case from cloud so You will never have NaN displayed.

  • platform: template #TEMPLATE temperature sensor
    sensors:
    temp_db_combined:
    friendly_name: “Temperatura dnevni boravak kombinirano”
    unit_of_measurement: ‘°C’
    value_template: >-
    {% if states(‘sensor.shelly_shht_1_58xxxf_temperature’) != ‘unavailable’ %}
    {{states(‘sensor.shelly_shht_1_58xxxf_temperature’)}}
    {% else %}
    {{states(‘sensor.temp_cloud_db’)}}
    {% endif %}´´´

I hope this will help You.

Be aware that formating is messed.

Regards.

1 Like

After updating to 2020.12.0, it stopped working, before it kept the value when the sensor was not available, now it shows unknown.

I’m facing a very similar issue. ESP32 board with BMP280 temperature + pressure sensor, turning on for 30 seconds and then going to deep sleep, running EspHome but communicating with HomeAssistant via MQTT. This “unavailable” is poor usability, especially on the phone where history graph is tough to hit for last recorded values.

There is an older thread about similar problem where it seems to have been fixed with value templates: Binary Sensor last known state when unavailable

I’m completely new to HomeAssistant so I’d be grateful for some pointers where should I click or which yaml files should I edit. As for now, I’m running an auto-generated Lovelace dashboard.

2 Likes

Yeah just noticed this, how annoying. Such a basic feature and it’s completely missing.

1 Like

I have a similar scenario looking for a solution: A Tasmota ESP8266 reporting the readings of HC-SR04 ultrasonic distance sensor via MQTT before going into DeepSleepTime.

On going into deep sleep, Tasmota obviously sends a MQTT LWT (Last Will Testament) indicating offline, which causes a value of unavailable. Here my typical readings:

I failed to find an easy solution. I tried:

Not working: Outlier filter

  - platform: filter
    name: "sensor.zisterne_echolot_sr04_distance.filtered"
    entity_id: sensor.zisterne_echolot_sr04_distance
    filters:
      - filter: outlier
        window_size: 5
        radius: 80

Not working: Declaring a template sensor

  - platform: template
    sensors:
      sensor_zisterne_echolot_sr04_distance_template:
        friendly_name: "Zisterne w/o unavailable"
        value_template: >
          {% if not states('sensor.zisterne_echolot_sr04_distance') in ['unavailable', 'unknown', 'none'] %}
            {{ states('sensor.zisterne_echolot_sr04_distance') | float }}
          {% else %}
            {{ states('sensor_zisterne_echolot_sr04_distance_template') | float }}
          {% endif %}
        unit_of_measurement: 'cm'

Both didn’t lead to a success.

Can anybody give me a hints for a simple solution?

Small side comment: I feel that I’m looking for sth. very trivial but my current two, failed approaches already feel quite clumsy & boiler-plate code.

To anyone still having this issue, I was able to solve it using the instructions in this thread:

This does not solve the root issue and unfortunately is also not an option for my Tasmota setup: Sorry – I was wrong.

If I get it right, the proposal in the referred thread is to reconfigure the MQTT sensor, so that HASS it no longer reacts on offline / online messages.

coming from a battery powered tasmota and some smart power meter i simply created my own sensor that fetches the latest mqtt value:

# --- power meter
- platform: mqtt
  state_topic: tele/tasmota_55D63F/SENSOR
  name: "Stromzaehler Total"
  unique_id: a30a8bd5-682e-449a-b49e-12e1a58a238e
  value_template: '{{ value_json["Wohnung"]["power_total"] }}'
  unit_of_measurement: "kWh"
- platform: mqtt
  state_topic: tele/tasmota_55D63F/SENSOR
  name: "Stromzaehler Curr"
  unique_id: 0d619efa-5f63-45a3-b226-e7d4e932cd3f
  value_template: '{{ value_json["Wohnung"]["power_curr"] }}'
  unit_of_measurement: "W"
1 Like

This seems to be working great for MQTT. Does anyone know of a solution that works with sensors that don’t get their value via MQTT?

Same problem here, but I have an idea:

  • Create one template sensor which takes the value of a template sensor below it in sensor.yaml
  • Create the lower template sensor which updates itself only when the referenced entity is not in [‘unavailable’, ‘unknown’], otherwise takes the value of the template sensor above
  • If template sensors are updated in series then there will be no circular reference. No idea if this is true, but I will try it.

You could probably do this with an automation that conditionally stores a value in an input_number helper, but that seems less elegant, and I already have too many automations as it is.

Sounds promising. Let us know how it goes.

Updated 29-12-2021

Ok, I’ve implemented the below in sensor.yaml (or configuration.yaml if you don’t have a sensor.yaml set up yet) and it works for my use case. In my case, I’m trying to send the last known uptime in a mobile notification when my router goes down (it’s going down a lot lately), and there’s only a brief period where my notification automation must be triggered by the data source entity going unavailable and then reporting its previously known value.

How it works:

  • Consists of:

    1. Data source entity whose last known value should be sent in a notification the moment it becomes unavailable
    2. Template sensor (lets call it primary) that uses if/else logic to take the value of the data source entity, or to take a secondary template sensor value when the data source entity becomes unavailable
    3. Secondary template sensor that just always takes the state of the primary template sensor
  • When home assistant reboots, the template sensors are reloaded with a none value that causes both template sensors to take the value “unknown” while the data source entity is “unavailable” (see here). If you don’t care about this temporary state at home assistant reboot, then this solution should still work for you.

  • When the data source entity initially becomes available after HA reboot, the template sensors start working as expected. Both primary and secondary template sensors keep the last known value of the data source entity when the data source entity becomes unavailable, and revert back to the value of the data source entity when it becomes available again.

Here is a generic version of the above:

# Store last known value of data source entity while it is unavailable
- platform: template
  sensors:
    primary_template_sensor:
      friendly_name: "Place to store last known value of DATA SOURCE ENTITY while it is unavailable"
      value_template: >-
        {% set data_source = states('INSERT DATA SOURCE ENTITY HERE') %}
        {% if data_source in ['unavailable', 'unknown'] %} 
          {{states('sensor.secondary_template_sensor')}}
        {% else %}
          {{data_source}}
        {% endif %}
    secondary_template_sensor:
      friendly_name: "Placeholder to avoid circular reference in primary_template_sensor if/else logic"
      value_template: >-
        {{states('sensor.primary_template_sensor')}}

Here is my implementation: Note that I’ve combined a solution for keeping the previously known uptime value with some extras for converting the uptime in seconds to a readable text string as discussed here. I also needed to filter uptime with the int() function when I set seconds in the value_template of rax_uptime_verbose in order to do the math operations below it without an error.

# Store last known RAX120 uptime when sensor becomes unavailable
- platform: template
  sensors:

    rax120_uptime_verbose:
      friendly_name: "Human-readable RAX120 uptime"
      icon_template: mdi:clock-start
      value_template: >-
        {% set uptime = states('sensor.rax120v2_gateway_uptime_2') %}
        {% if uptime in ['0', 'unavailable', 'none', 'unknown'] %} 
          {{states('sensor.rax120_uptime_placeholder')}}
        {% else %}
          {% set seconds = uptime|int %}
          {% set minutes = (seconds // 60)|int %}
          {% set hours = minutes // 60 %}
          {% set days = hours // 24 %}
          {% set minutes = minutes % 60 %}
          {% set hours =  hours % 24 %}
          {% set days = days % 7 %}
          {% macro phrase(value,name) %}
            {%- set value = value %}
            {%- set end = 's' if value > 1 else '' %}
            {{- '{} {}{}'.format(value,name,end) if value|int > 0 else '' }}
          {%- endmacro %}
          {% set text = [phrase(days,'day'),phrase(hours,'hour'),phrase(minutes,'min')]|select('!=','')|list|join(', ') %}
          {% set last_comma = text.rfind(',') %}
          {% if last_comma != -1 %}
            {% set text = text[:last_comma] + ' and' + text[last_comma + 1:] %}
          {% endif %}
          {{text}}
        {% endif %}

    rax120_uptime_placeholder:
      friendly_name: "Place to store RAX120 uptime when unavailable"
      icon_template: mdi:clock-start
      value_template: >-
        {{states('sensor.rax120_uptime_verbose')}}

If you really need the last known value of the data source entity to persist through a HA reboot (or the HA uptime entity is your data source entity), then you can use an automation and an input_text, input_number or input_date helper in place of the primary and secondary template sensors above. In this case, create the appropriate type of input sensor for your datatype via “helpers” in the HA configuration settings and use its respective set_value service call in your automation. The automation could look like the below with as many conditions as you desire (or a fancy combined template condition :stuck_out_tongue:):

alias: 'DATA SOURCE ENTITY persistent storage'
description: 'Update INPUT NUMBER to match DATA SOURCE ENTITY state unless unavailable or unknown'
mode: single
trigger:
  - platform: state
    entity_id: INSERT DATA SOURCE ENTITY
    id: Data source state updated
condition:
  - condition: and
    conditions:
      - condition: not
        conditions:
          - condition: state
            entity_id: INSERT DATA SOURCE ENTITY
            state: unavailable
      - condition: not
        conditions:
          - condition: state
            entity_id: INSERT DATA SOURCE ENTITY
            state: unknown
action:
  - service: input_number.set_value
    target:
      entity_id: INSERT INPUT NUMBER ENTITY

This automation will only update the value of the helper entity when the the data source entity is not unavailable and not unknown, and the helper entity should persist through a reboot. Note that the helper entity will be updated with the value of the data source entity when it becomes available again. I chose not to use this implementation because my data source entity updates every few seconds, and I didn’t want to use an automation that runs so frequently and clogs up my logs. But, perhaps this will do the job for others, especially if your data source entity changes states infrequently.

1 Like

Few options that pop to mind.

  1. Have an automation that posts a sensor value to an mqtt topic unless it’s unavailable / unknown. Make sure you set the retain flag on. Have a template sensor that pulls from the mqtt topic unless it’s unavailable / unknown
  2. Use the Var custom component
1 Like

Sorry for reviving an old topic, but I’m encountering this now. The answers below seemed rather complicated for such a silly small problem. The solution I’m using is to just publish “Online” to the LWT topic that published “Offline”. HA then switches from all relevant entities being “unavailable” to whatever data they last received.

So, in my case, tasmota goes into deep sleep, publishes it’s “tele/tasmota_xxxxxx/LWT Offline” message and HA sets all entities for that device to unavailable. I made a simple automation with the trigger mqtt topic “tele/tasmota_xxxxxx/LWT” payload “Offline”. The action is call service, MQTT publish topic “tele/tasmota_xxxxxx/LWT” payload “Online”. HA now thinks the device is online and displays whatever the last values each entity had.

2 Likes

@demondreamer : Thanks. Meets the need. I use Tasmota, and this seems to be the simplest way to make the values retained. If I ever wonder if the sensor is still working, I can check to see when the automation last ran. Good idea.

I tried this method because I have a temperature sensor for my pool that gets shutdown at this time of year. I’d like the dashboard to reflect the last known temp but instead I get the “Entity is currently unavailable:” message instead.
After creating and running the automation the dashboard still shows the same message. I’m using Guage card for this. Am I correct to think that by publishing the Online payload when it sees “Offline” that the gauge card would still show with the last known temp (before going offline)? I think I followed the process correctly, I saw the new payload “Offline” in the mqtt logs. I did not include the quotes ("") in the automation for either the payload or topic. Appreciate any thoughts here. Thanks!

Here’s a better way to show the last known value of a sensor:

Create a Trigger-based Template Sensor (the NOTE section of this post)

3 Likes