Updating template sensors

Hi there, I’m fairly new with homeassistant and tried to build my own sensors to simulate a battery. Basically I want to have data on how much energy from my solar panels I could use if I had a 1.92 kWh battery. Therefore, I installed a shelly Pro 3EM. I generated a inverted sensor, so it shows me the power that would actually charge the battery. Further, I generated the follwoing sensors in the templates.yaml:

- trigger:
  - platform: time_pattern
    seconds: "/30"
  - platform: state
    entity_id:
      - sensor.shellypro3em_power
  sensor:
    - name: "Shelly Power invertiert"
      unique_id: shelly_power_inverted
      unit_of_measurement: "W"
      device_class: power
      state_class: measurement 
      state: >
        {{ (states('sensor.shellypro3em_power') | float(0)) * -1 }}
- trigger:
  - platform: time_pattern
    seconds: "/10" 
  - platform: state
    entity_id: 
      - sensor.shelly_power_invertiert
      - sensor.battery
  sensor:
    - name: "effektiv_power"
      unit_of_measurement: "W"
      state: >
        {% set p = states('sensor.shelly_power_invertiert') | float() %}
        {% set b = states('sensor.battery') | float(0) %}
        {% if b <= 0 %}
          {{ [p, 0] | max }}
        {% elif b >= 1.92 %}
          {{ [p, 0] | min }}
        {% else %}
          {{ p }}
        {% endif %}
    - name: "power safed"
      unit_of_measurement: "W"
      state: >
        {% set p = states('sensor.shelly_power_invertiert') | float() %}
        {% set b = states('sensor.battery') | float(0) %}
        {% if b < 1.92 %}
          {{ [p, 0] | max }}
        {% elif b >= 1.92 %}
          0
        {% endif %}
    - name: "power over battery"
      unit_of_measurement: "W"
      state: >
        {% set p = states('sensor.shelly_power_invertiert') | float() %}
        {% set b = states('sensor.battery') | float(0) %}
        {% if b >= 1.92 %}
          {{ [p, 0] | max }}
        {% else %}
          0
        {% endif %}

In my configuration.yaml I have following integration sensors:

sensor:
  - platform: integration
    name: Battery
    source: sensor.effektiv_power
    unit_prefix: k
    round: 3
    max_sub_interval: 
      seconds: 30
  - platform: integration
    name: "additional power"
    source: sensor.power_safed
    unit_prefix: k
    round: 3
    max_sub_interval: 
      seconds: 30
  - platform: integration
    name: "lost power"
    source: sensor.power_over_battery
    unit_prefix: k
    round: 3
    max_sub_interval: 
      seconds: 30

So far so good. I figgured, that the sensor.shelly_power_invertiert updated as I desired. Meaning, when I gave it a time_pattern trigger only, it triggerd accordint to this time patter, if it had a entity_id-trigger, it used that. When I wanted to do the same for the other sensors, they do not get a update if they stay at the same value.
Usually, that wouldn’t really be a problem, however, since I want to integrate the power that was saved in my battery, it seems that the integration doesn’t do what I want it. Basically, when the last change was at 17:00 and the next update comes at 10:00, the integration sensor extrapolates and assumes, that during this time there was power produced. This then leads to the problem, that, especially if the first reading is high, my Battery assumes it is full instantly. To avoid this, I though I could somehow force the sensors to update, but unitl now, I couldn’t really find a workaround.

I’d be very thankful for your help!

Home assistant in general suppresses like-states. You can’t get around this.

max_sub_interval is what you use to have integration sensors update after a given period with a new calculation.

1 Like

In addition to that, Left Riemann integration is what fits a sensor that stays the same for a long time and then updates when the value changes. This is not the default. If you use left, the integral calculates the right value (pun intended). It will however only update when a new value cones in, so the max_sub_interval is still useful. For derivative sensors it is even crucial.

1 Like

Thank you very much for your response! I’ve tried the max_sub_interval before (as shwon in the battery integration sensor), however it seems like it is not safing the newly generated values.
I’ve generated some graphs using Grafana, that show my issue, sadly I can only post one image after another.
Battery jumps to over 10kWh in the morning:

While the sensor, that was integrated (sensor.effective_power) only showed one high value (after sunrise), leading to the high battery integration.
Also after adding the max_sub_interval, I do not get a update for the battery integration within the set interval, so it at least dosn’t safe new “0” values.
If the max_sub_interval should do the trick, I will just wait until the next sunny day and see if I dont have the same issues anymore :slight_smile: I just wanted to make sure that my issue gets understood :smiley:
Thank you so much for your help!

That’s also something I came across within the documentation. The thing that made me hessitant is that the left method is accurate for load jumps, that stay consistant. My load, however, jumps up and down all the time. Therefore, I’m not sure if “left” is also providing the right values after the inital value.

Just so I get it right. With max_sub_interval I should get values every defined time interval (in my case every 30 seconds). The probably simple question here is, why don’t I?
Here is todays Battery graph using the max_sub_interval as shown in the code above

changes you make to existing sensors aren’t retroactive.

Trapezoid is theoretically the best for sensors that update on regular timed intervals, but only if those values are actually stored. As said, HA does not store values unless they change.

Trapezoid will give extreme wrong values for sensors that are constant a long time, which is especially true for solar production, or power measurements that can be off for long times. This by far corrupts any slight accuracy improvements when power is non zero. Remember that when power is non zero, values are stored frequently, so there is not much error there whatever integration method is used.

I’m aware of that, that’s why I posted the Battery values from yesterday, which were supposed to update in a 30 second interval, but didn’t.
Therefore I thought the max_sub_interval didnt work (or I misunderstand what it’s supposed to do).

Yep, I thought there was a way I could force HA to store the values ^^

I will generate a second sensor using the left Riemann sum so I can compare how much difference it actually makes. I just read the error is bigger if values change, but I’ve no clue, what that actually means for the generated values. If I have 1% error, I don’t really care and as you said, it updates frequently, so it also makes sence that there’s not a huge difference.

Thank you both for your help!

What was probably meant was: after a long period of no change, the first incoming value after that creates a big spike when using Trapezoid.

Lets say a light was off for 8 hours, then it is turned on at 10 watts. The moment it is turned on, there should hardly be any increase in the integral, because the time it was on is practically 0. It has been off for 8 hours, and on for a fraction of a second. But instead, Trapeziod assumes a gradual increase from o to 10 watts over an 8 hour period, equating to 40 Wh at that instant.

Left Riemann however does exactly what happened: assume the light was off until the new measurement came in. If there would have been a gradual increase, those changes would have been registered regularly by HA and left Riemann would have counted it correctly.

1 Like

Yes, exactly that. Looks like that’s exactly what I need :wink: Thank you!

1 Like