Total_increasing sensors sum

Hey,

i tried to build a sum of energy sensors. The sensors are created by the powercalc integration. The sum of the sensors I build bey the following code. that sensor values should be shown in the energy dashboard.
The values are set to zero if I am restarting HA. Is there a way to prevent that behavior? I tried to use the availability option. But this is not working right. What an I do?

    - name: "Device Self Sum Venergy"
      unique_id: xxxxxx_1111111
      unit_of_measurement: "kWh"
      device_class: energy
      state_class: total_increasing
      availability: >
        {{ 
          states
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | map(attribute='name')
          | list
          | count > 35
        }}
      state: >-
        {{ 
          states
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | map(attribute='state')
          | map('float', 0)
          | sum
        }}

Your availability template is not going to help. It counts the number of names but even sensors with an unavailable state will still have a name.

You need it to search the all the energy sensor states for any occurrence of unavailable or unknown.

Search for unknown or unavailable? The entity should NOT be unknown or unavailable?

How to do that?

| is_number

doesnt work.

I think removing that default to 0 should be enough (and will be better approach).

That will work, for the state, not the name.

What default?

Zero in map('float', 0)

  1. You should limit the it to use only sensors, not all entities (you can do that to start with states.sensor instead of just states. This will also make sure your template sensor updates once per second, and not once per minute
  2. Use either is_number on the state, or has_value on the entity_id to check for availibility of the source sensors

Using is_number

        {{ 
          states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | selectattr('state', 'is_number')
          | list
          | count > 35
        }}

Using has_value

        {{ 
          states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | selectattr('entity_id', 'has_value')
          | list
          | count > 35
        }}

Note that if you want to use this on the Energy Dashboard you need to ensure that all those entities are available (not just more than 35 in case there are more than 36 entities). Otherwise you will have spikes in your Energy Dashboard every time one of those entities is unavailable (but the total number still exceeds 35) or after every restart.

2 Likes

thanks. I got a solution by counting all energy sensors and comparing the count of the available.

      availability: >
        {% 
          set count_valid = states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | selectattr('state', '>', '0')
          | rejectattr('state', 'in', ['unavailable', 'unknown', 'none'])
          | map(attribute='state')
          | map('float')
          | list
          | count
        %}
        {%
          set count_invalid = states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | map(attribute='name')
          | list
          | count
        %}
        {% if count_valid == count_invalid %}
          true
        {% else %}
          false
        {% endif %}        
      state: >-
        {{ 
          states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | selectattr('state', 'is_number')
          | map(attribute='state')
          | map('float', 0)
          | sum
        }}

The templates can be simplified:

      availability: >
        {%
          set sensors = states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | list
        %}
        {{ sensors | selectattr('state', 'is_number') | list | count == sensors | count }}
      state: >-
        {{ 
          states.sensor
          | selectattr('attributes.device_class', 'eq', 'energy')
          | selectattr('entity_id', 'search', '_device_energy')
          | map(attribute='state')
          | map('float')
          | sum
        }}

If you ever see yourself doing something like

{% if some test %}
  true
{% else %}
  false
{% endif %}

you can simple do:

{{ some test }}

@TheFes

What’s the difference between

 selectattr('state', 'is_number')

and

 selectattr('state', 'has_value')

and

selectattr('state', '>', '0')

The first one is correct, and checks if the state represents a number (so either a numeric value, or a string representing the number (the last one is the thing you want for a state as they are always a string)). It can be used on any value, and not necessarily an entity state.

The second one is incorrect, has_value checks if an entity_id has a valid state (so basically if it’s not unavailable or unknown) so it should be used on the entity_id and not on the state. has_value can be used on other entities as well, also when they don’t have a numeric state.

But as already mentioned above, if applied correctly both using is_number and has_value will have the same result in your use case.

The third one is a string comparison on the state value and the string "0" which doesn’t make much sense to me, and which I therefor also removed in my post above. Why should entities with a state of "0" be excluded from your availability check? It will basically always return true unless the state is actually "0" (or negative, which shouldn’t normally be the case for an energy sensor).

1 Like