Home Assistant MQTT outlier filter template
A Home Assistant template to filter out weird/outlier values received by a TASMOTA controlled sensor.
Introduction
Recently my analog electricity meter was recplaced by a digital one, in my case, Landis+Gyr E220. This inspired me to try it to connect it with my current Home Assistant setup to receive live data about my electricity and power consumption.
Looking for available interfaces to read data from the meter, I found this kit on Amazon, which included all the needed components and even provides support in case one needs it. After building and installing it, everything was working perfectly until I noticed, that rarely, but still often enough, I would receive outlier (bogus) values in the total consumption data, which would lead to major errors in Home Assistant dashboards and calculations.
To circumvent this issue, I wrote following value_template
for MQTT sensor in Home Assistant, which only updates the sensor’s value if it deviates by 5% from previous reading.
Solution
mqtt:
- sensor:
name: 'Electricity total consumption'
state_topic: 'tele/electricity/SENSOR'
value_template: >
{% set v = value_json.E220.total_consumption %}
{% set old = states('sensor.electricity_total_consumption') %}
{% if is_number(old) %}
{% set old = old | float %}
{% if (v > 0.95 * old) and (v < 1.05 * old) %}
{{ v }}
{% else %}
{{ old }}
{% endif %}
{% else %}
{{ v }}
{% endif %}
unit_of_measurement: 'kWh'
suggested_display_precision: 4
device_class: energy
state_class: total_increasing
It takes the current reading from MQTT payload and variable (value_json.E220.total_consumption
, which I defined in TASMOTA console script) and compares it to previously received value stored in HA sensor.electricity_total_consumption
.
After a restart of Home Assistant, that old value is empty or more specifically not a number (because it is a MQTT sensor), so we need to handle that case with if
block (the new value will be taken without outlier filtering), but afterwards, all incoming values are being cheked to lie within 5% range of the previous value.
This solution helped me to avoid random occurances, where I would for whatever reason get 0
, 0.3
or 1245856.5
readings.
Hope this helps!