Background:
Home Assistant currently ignores sensor updates when the value that is reported is the same as the previous value. This saves space in the database since there is presumably no value in storing redundant data. Some integrations have a force_update
option which overrides this behavior; normally with the stated goal of having “meaningful graphs” (e.g. MQTT).
Problem:
Many issues are caused by the choice to ignore repeated values:
- Sensors that look at a defined history window or max age or sample size (statistics, history stats, filter) will have incorrect values calculated and/or can change to
unknown
when their source sensors are reporting normally - Derivative sensors can never result in a value of zero
-
Reimann sum integrals will yield incorrect results when
trapezoidal
orright
is chosen formethod:
- State triggers (whether in automations or trigger-based template sensors) will not trigger when a new but duplicate value is read. Often triggering is not desired, but if it is, there is no workaround.
Problem Examples
Example 1: A derivative sensor whose source sensor is a temperature sensor, and the last 3 temperature readings are 5, 10, and 10 deg C, each reported one minute apart. The user would expect to see a derivative of zero since there was no change between the last two readings. The current implementation results in a derivative of 5degC/minute because the last reading is ignored.
Example 2: An average sensor which averages a water meter’s reading over the past two hours. Assume no water has been used for several hours, and therefore the water meter sensor reports the same meter reading of 15,850 gallons every two minutes. The expected average would be 15,850 gallons. The current implementation results in “unknown” because there is no data in the past 2 hours and therefore no data to calculate an average.
Example 3: A sensor which takes a rain gauge sensor’s reading to calculate total rainfall. (This could be done with a trigger-based template sensor, or with a utility_meter using the delta_values
setting.) If the rain gage reports two readings of 10mm rainfall, the template sensor / utility_meter will calculate a total rainfall of 10mm, instead of the correct value of 20mm.
Proposed Solution
Rather than having each of the many affected integrations trying to address this problem in unique ways, my proposal is to have a single common way of dealing with this issue:
- Add
Expected update interval
as an option to devices and entities. - Default
Expected update interval
toinfinite
so that this is not a breaking change - Implement it similarly to areas, where it can be assigned to a device or to individual entities.
- Update the developer documentation so that integration developers know how to utilize this parameter (see explanation below).
Explanation:
This change would do nothing upon implementation, but integrations and visualizations would be able to read this parameter and utilize it. It would not affect when the entity is marked unavailable
. This setting would only be used as an input to other integrations which consume the data of the entity in question. The logic for graphs and integrations would be: If there is a gap in data points larger than expected_update_interval
then assume a repeated data point exists every expected_update_interval
. Sensors which refer to other source entities would be updated upon every update of that source sensor (just as they are today) and also every time the expected_update_interval
passes without a source update. Since the default to this value is inifinte, it makes no difference to the current handling of updates.
Before/After Visualization, using ‘derivative’ as an example:
Caveats & Issues
- Since timing is never perfect, a sensor which is supposed to push an update every 2 minutes may in fact push an update after 2 minutes and 1 second. There may need to be a hard-coded heuristic “extra delay” before the logic assumes the first data point is missing. Something like
min(expected_update_interval + 30 sec, max(expected_update_interval * 0.25, 1 sec))
. My thinking is that if the sensor is supposed to push every 24 hours, then a 30 sec buffer seems reasonable. If the sensor is supposed to push every 1s, then a 1s buffer seems reasonable. - The “last updated” attribute of an entity should ideally include the logic using the
expected_update_interval
however this would waste database storage space since this value would be stored every time it is changed. Suggest leaving “last_updated” unchanged.
Benefits
- Does not increase the size of the database
- Enables a common, logical way of handling this known issue for all integrations
- Is not a breaking change
Related Issues and Requests that this would address:
Issues & PR’s
HA Issue: Statistics - Inaccurate Stats With Max_Age
HA Issue: Statistics sensor doesn’t handle zero values correctly
HA Issue: Derivative integration gives incorrect values when source does not change
HA PR: Add statistics preserve_last_value option
Feature Requests
Request to add ‘force_update’ to template sensors
Forum Posts
Calculating average water consumption
Statistics sensor becomes intermittent
Average sensor (includes discussions on issues with the statistics platform)