Aqotec RM360 over Modbus, Part 2: The Energy Counter Workaround
Why the RM360 energy register is kept raw first, then filtered into a stable total_increasing sensor for Home Assistant.
Part 1 created a small read-only Modbus setup for the Aqotec RM360. One value deserves special treatment: the energy counter.
Home Assistant’s Energy Dashboard expects a stable, monotonic sensor. In practice, Modbus reads can occasionally return bad values: a brief glitch, a reset-looking value, or a jump that is not physically plausible.
So I split the value in two:
rm360_energy_raw: the direct Modbus readrm360_energy: the filtered sensor used by dashboards and long-term statistics
Raw Modbus sensor
- name: rm360_energy_raw
unique_id: rm360_energy_raw
address: 43750
scan_interval: 720
unit_of_measurement: "kWh"
data_type: float32
precision: 1
The raw sensor is useful for debugging. It should not be the value used by the Energy Dashboard.
Filtered template sensor
The filtered sensor keeps the old value when the new raw value is invalid, lower than the previous value, or jumps by more than 1000 kWh at once.
template:
- triggers:
- trigger: state
entity_id: sensor.rm360_energy_raw
- trigger: homeassistant
event: start
sensor:
- name: "RM360 Energy"
default_entity_id: sensor.rm360_energy
unique_id: rm360_energy_filtered
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
state: >
{% set new = states('sensor.rm360_energy_raw') | float(none) %}
{% set old = this.state | float(none) %}
{% if new is none or new < 0 %}
{{ old if old is not none else none }}
{% elif old is none %}
{{ new }}
{% elif new >= old and (new - old) <= 1000 %}
{{ new }}
{% else %}
{{ old }}
{% endif %}
attributes:
raw_value: >
{{ states('sensor.rm360_energy_raw') }}
rejected: >
{% set new = states('sensor.rm360_energy_raw') | float(none) %}
{% set old = this.state | float(none) %}
{{
new is not none
and old is not none
and (
new < old
or (new - old) > 1000
)
}}
rejection_reason: >
{% set new = states('sensor.rm360_energy_raw') | float(none) %}
{% set old = this.state | float(none) %}
{% if new is none %}
invalid_or_unavailable
{% elif new < 0 %}
negative_value
{% elif old is not none and new < old %}
counter_decreased
{% elif old is not none and (new - old) > 1000 %}
increase_over_1000_kwh
{% else %}
none
{% endif %}
maximum_increase_kwh: "{{ 1000 }}"
Why this workaround matters
The Energy Dashboard stores long-term statistics. Once a bad spike lands there, cleaning it up is much more annoying than filtering it before it enters the statistics pipeline.
The raw sensor remains visible, so debugging is still possible. The filtered sensor is the one you chart, use for statistics, and expose to the Energy Dashboard.
Next up: writing values back to the RM360 safely.
Series navigation
Previous step: Aqotec RM360 over Modbus, Part 1: Read-Only Home Assistant Sensors
Next step: Aqotec RM360 over Modbus, Part 3: Safe Writes and Automations