Updating template sensor on attribute change?

Hi,
I am feeding the battery levels of my sensors into InfluxDB to generate nice graphs using Grafana.
To achieve this, I’m using template sensors to create sensors whose state reflects the battery_level attribute of the actual sensors, e.g. like this:

 bat_aeotec_ms6_kitchen:
    value_template: '{{ states.zwave.aeotec_ms6_kitchen.attributes.battery_level | int }}'
    unit_of_measurement: '%'

This sensor only updates when the battery level of the actual device changes, but not when the device updates its state with the battery level unchanged.

The result is that in InfluxDB new data points are only inserted when the the battery level changes.
As Grafana only uses data points that are within the displayed time range, this could lead to graphs not being drawn at all due to not enough data points being available.

Is it somehow possible to update a template sensor whenever the underlying device updates, even if the updated attribute is not within the scope of the template sensor?

Sebastian

you could add an entity_id based on the date_time sensor so that the template sensor would update whenever that sensor updates (either daily for sensor.date or every minute for sensor.time)

  bat_aeotec_ms6_kitchen:
    entity_id: sensor.time
    value_template: '{{ states.zwave.aeotec_ms6_kitchen.attributes.battery_level | int }}'
    unit_of_measurement: '%'

Great idea, thanks!

Sebastian

Hm, apparently that does not work in my case.
For one, the entity_id option for template sensors seems to have been deprecated about a year ago (see here).
It’s still in the docs, so I tried it, but my sensor is not updating.

Then I was looking to find some info about this “sensor.time” sensor, but couldn’t find anything.
Putting {{ states("sensor.time") }} into /dev-template renders to “unknown”. Hm.

My template sensor looks like this:

platform: template
sensors:
  bat_pronto:
    value_template: >
      {% if is_state_attr("device_tracker.pronto", "battery", "charging") %}
        110
      {% else %}
        {{ state_attr("device_tracker.pronto", "battery") | int }}
      {% endif %}
    unit_of_measurement: '%'

with device_tracker.pronto having only two attibutes “battery” and “last_update” where the value of the latter is a time stamp that changes regularly.
I would like to update the template sensor at least each time the last_update value changes, so a new data point gets sent to InfluxDB.

Sebastian

EDIT: I also just noticed that adding “entity_id: sensor.time” completely prevents the template sensor from updating, i.e. after restarting HA its value stays “0” even if the device tracker updates its state.

There’s a service called homeassistant.update_entity (see documentation).

Create an automation that triggers at a regular time interval (such as every minute) then runs homeassistant.update_entity for the desired sensor.

I think you might be using it in the wrong place. see here for what I was referring to:

https://www.home-assistant.io/components/sensor.template/#entity-ids

so basically the template sensor would look like this:

platform: template
  sensors:
    bat_pronto:
      entity_id: sensor.time
      value_template: >
        {% if is_state_attr("device_tracker.pronto", "battery", "charging") %}
          110
        {% else %}
          {{ state_attr("device_tracker.pronto", "battery") | int }}
        {% endif %}
      unit_of_measurement: '%'

But that would also require you to actually create the sensor.time which is created by adding the following to your configuration:

sensor:
  - platform: time_date
    display_options:
      - time
      - date
      - date_time
      - time_date
1 Like

Thanks, @finity - my bad, I was under the impression that sensor.time would be some kind of builtin entity.
I now created the sensor and added the entity_id statement to the template sensor definition.
Unfortunately, this still does not cause the sensor to be updated every minute (I checked using {{ states.sensor.bat_pronto.last_updated }}) and also no additional data points are written to InfluxDB.

@123, also calling homeassistant.update_entity for my sensor does not change the “last_updated” attribute or create any additional data points.

Even updating the device_tracker sensor with a new time stamp does not cause an update of the template sensor as no attributes would change there.

Sebastian

So by periodically requesting an update for zwave.aeotec_ms6_kitchen, you’re saying it does not create a new data-point (battery_level) for sensor.bat_aeotec_ms6_kitchen?

Yeah, I just tried it by creating a sensor and using the sensor.time as an update entity it doesn’t work. That’s definitely strange since that is the exact example the docs give for a periodic update of a template sensor.

I’ve never needed to use it so I don’t know if it ever worked that way but it was a pretty recent change that required it. Maybe you should file an issue on github about it.

Exactly - either that or the update_entity service through /dev-service is not working.
The sensor for the zwave device in my first post was only an example - my actual issue is with the “bat_pronto” sensor that’s fed by the device tracker - but I tried with both, it makes no difference either way.
Also the issue is the same with my zwave battery sensors, I just didn’t bother.

Sebastian

Well, according to the post I referred to earlier, I’d say that the entity_id option is deprecated.
I’ve never needed it until now, so I’m probably not up to speed regarding the current state of the development.
Maybe @balloob could shed some light on this?

Sebastian

Darn! I thought this new service (homeassistant.update_entity) was designed for this precise purpose (updating a sensor’s status independently of its scan_interval). Disappointing to hear it didn’t do the trick in this case.

1 Like

Yes, my “fix” or your “fix” were supposed to be the way this is now supposed to be done according to the breaking change a few releases back and according to the current docs.

no.

It changed in v81 in Oct 2018 to require either a specifically configured entity_id or a call to the update_entity service if the template couldn’t determine an entity to automatically update on. that post that you referenced was from jan 2018 which was before the requirement was implemented.

The current docs reflect that requirement. Unfortunately it doesn’t seem to work correctly

I see, thanks for the clarification!

Sebastian

EDIT: I reported it as a bug:
https://github.com/home-assistant/home-assistant/issues/22197

I faced the same issue today, where I want to calculate the number of hrs my heating is triggered using exported influx data of a virtual template sensor. The virtual sensor was just report 1, if the thermostat change to on, and zero when thermostat turn off. it was only report to influx data when the sensor change state. This was making my integral function in influx/grafana showing extra hours…

A work around, I made hacky transition between the virtual sensor state 1/0. For example, when heating is turn on, the sensor state will change from 0 to 0.001, then from 0.001 to 1. Also, when heating turn off, the sensor state will change from 1 to 0.999, and then to 0… in that way in influx/grafana, the data will show ~ as staircase and I could make use of the integral function in influx without any problem.

Here is my sensor config:

  • platform: template
    sensors:
    living_thermostat_operation:
    friendly_name: “Living Thermostat Operation”
    unit_of_measurement: ‘thermostatOperation’
    value_template: >
    {% if state_attr(‘climate.living’, ‘hvac_action’) == ‘heating’ and ( states.sensor.living_thermostat_operation.state |float ) == 0.0 %}
    0.001
    {% elif state_attr(‘climate.living’, ‘hvac_action’) == ‘heating’ %}
    1
    {% elif state_attr(‘climate.living’, ‘hvac_action’) != ‘heating’ and ( states.sensor.living_thermostat_operation.state | float ) == 1.0 %}
    0.999
    {% else %}
    0
    {% endif %}

You may achieve the same with the battery sensor by increasing the sensor with small amount like 0.1 then decrease it again, but with time base like every minute or 5 minute.