Question on Riemann Integral

I have a binary sensor which tracks when my geyser (“boiler”) heating element is switched on (binary_sensor.geyserwise_max_work_state below). I then calculate the power (in Watts) of the geyser as a template sensor using the rating of the element (2000W) and then I integrate to get the energy consumed by the element using the integration platform. I use method: left as recommended.

sensor:
  - platform: integration
    source: sensor.geyser_element_power
    name: geyser_element_energy_consumed
    method: left
    unit_time: h
    unit_prefix: k
    round: 3
template:
  - sensor:
      - name: geyser_element_power
        unit_of_measurement: "W"
        device_class: "power"
        state:  >
          {% if is_state('binary_sensor.geyserwise_max_work_state', 'on') %}
            {{ 2000 }}
          {% else %}
            {{ 0 }}
          {% endif %}

They element switches on for a period of time but I’m surprised how the geyser_element_energy_consumed sensor then behaves.

It plots all energy consumed as a step function as opposed to what I would expect a linearly increasing amount of energy consumed while the element is on. Here is an example from when the element was on but all the energy consumed is allocated to the moment the element switched off.

How do I get the expected linear pattern? The only other way I can think of is to track the time the element is on and calculate roughly 2kW * hours_on ?

I guess the template sensor only updates when the binary sensor changes. And the integral only “fires” when the template sensor changes value? So that’s why this is happening?

I’m used OpenHAB and this seems to be related to a sensor receiving an update vs. changing. The underlying binary sensor actually receives updates roughly every minute I think though it’s state doesn’t change. Anyway to force the Riemann to fire on updates as opposed to changes?

I’d highly recommend using the Powercalc custom integration:

It can do exactly what you’re trying to do as well as a ton more.