Energy integrator not integrating properly

Hey there,

I have a couple of templates that split my total power consumption in peak and off-peak hours:

  - name: power_total_offpeak_template
	unique_id: power_total_offpeak_template
	device_class: power
	unit_of_measurement: W
	state: >
	  {% set p = states('sensor.z2m_power_main_power_a') | float(0) %}
	  {% set now = now() %}

	  {# --- Time windows --- #}

	  {# 1: 12:30 β†’ 15:30 #}
	  {% set w1_start = now.replace(hour=12, minute=30, second=0) %}
	  {% set w1_end   = now.replace(hour=15, minute=30, second=0) %}

	  {# 2: 02:00 β†’ 07:00 #}
	  {% set w2_start = now.replace(hour=2, minute=0, second=0) %}
	  {% set w2_end   = now.replace(hour=7, minute=0, second=0) %}

	  {# --- Output only during valid windows --- #}
	  {% if (w1_start <= now <= w1_end) or (w2_start <= now <= w2_end) %}
		{{ p }}
	  {% else %}
		0
	  {% endif %}    
	  
	  
  - name: power_total_peak_template
    unique_id: power_total_peak_template
    device_class: power
    unit_of_measurement: W
    state: >
      {% set p = states('sensor.z2m_power_main_power_a') | float(0) %}
      {% set now = now() %}
    
      {# --- Time windows --- #}
    
      {# 1: 12:30 β†’ 15:30 #}
      {% set w1_start = now.replace(hour=12, minute=30, second=0) %}
      {% set w1_end   = now.replace(hour=15, minute=30, second=0) %}
    
      {# 2: 02:00 β†’ 07:00 #}
      {% set w2_start = now.replace(hour=2, minute=0, second=0) %}
      {% set w2_end   = now.replace(hour=7, minute=0, second=0) %}
    
      {# --- Output only during valid windows --- #}
      {% if (w1_start <= now <= w1_end) or (w2_start <= now <= w2_end) %}
        0
      {% else %}
        {{ p }}
      {% endif %}  

And then a couple of integrators which integrate each of these to get the total energy during each time period. Ultimately I use a utility_meter and the energy prices to calculate monthly costs.

- platform: integration
  name: energy_house_total
  unique_id: energy_house_total
  source: sensor.z2m_power_main_power_a
  unit_prefix: k
  round: 3
  
- platform: integration
  name: energy_house_total_peak
  unique_id: energy_house_total_peak
  source: sensor.power_total_peak_template
  unit_prefix: k
  round: 3

energy_house_total_peak_monthly:
  source: sensor.energy_house_total_peak
  cycle: monthly
  unique_id: energy_house_total_peak_monthly
  
energy_house_total_offpeak_monthly:
  source: sensor.energy_house_total_offpeak
  cycle: monthly
  unique_id: energy_house_total_offpeak_monthly

The power templates work fine, but the energy integrator messes up whenever the power goes from 0 up to whatever it currently is. It seems to integrate that power over the period during which it was zero, which is obviously wrong. You can see it clearly in the plot here (check the jump at 7AM):

I’m guessing it integrates over whatever period the last datapoint was received, instead of at a fixed time interval as a proper numeric integrator. Any tips on how I might fix this? Thanks!

Like as documented here? Integral - Home Assistant

Ah, perfect, thanks! I was unaware that I could define the integration mode :slight_smile: In this case defining the method as left should fix my issue, I guess.

Alternatively I could keep trapezoidal but add a max_sub_interval of 10s or so. What would you say is the best option for an energy sensor?

Thanks!

I have no idea, only that not using the max_sub_interval caused the same issue for me :sweat_smile: I’m using it to get an idea of current natural gas usage by my hybrid heat pump/boiler where all I have is its absolute (metered) usage.

So in your case you kept the calculation trapezoidal and just added the max_sub_interval?

Either way, thanks again :wink:

Correct. Seems to be working fine for me at the moment.

Don’t split the power. Split the energy.

Create one integrator for your total power sensor, integrating all the time. Make sure to use the method: left option to minimise approximation errors.

Feed this energy sensor to a Utility meter with peak and off peak tariffs. This will create two energy sensors for you.

See: How to use Utility Meter Tariffs to conditionally measure things

3 Likes

Thank you, that does save me quite a bit of yaml! :smiley: