Custom sensor - availability / home battery SoC

Hi, I have created this sensor ‘soc predicted charge’, and need support for it to default, to 45 if the source sensor becomes unavailable. I have tried with availability but cannot get the code to work.

  - platform: template
    sensors:  
      soc_predicted_charge:
        friendly_name: "soc predicted charge"
        unit_of_measurement: "%"
        value_template: >-
         {% if states("sensor.energy_production_today")|float >= 12 %}
          30
         {% elif states("sensor.energy_production_today")|float >= 8 %}
          40
         {% elif states("sensor.energy_production_today")|float >= 7 %}
          50
         {% elif states("sensor.energy_production_today")|float >= 5 %}
          50
         {% elif states("sensor.energy_production_today")|float >= 3 %}
          70
         {% elif states("sensor.energy_production_today")|float >= 2 %}
          80
         {% elif states("sensor.energy_production_today")|float >= 1 %}
          90
         {% else %}
          30
         {% endif %}

Here’s my attempt using modern format — if you wanted to stick with the legacy format you have, just steal the template section.

Note that you have two 50s in your output — I assume you meant 60 for the second one and have adjusted to hopefully correct:

template:
  - sensor:
      - name: SoC predicted charge
        unit_of_measurement: "%"
        state: >
          {% set m = {12:30,8:40,7:50,5:60,3:70,2:80,1:90,0:30,-99:45} %}
          {{ m[m|select('<=',states("sensor.energy_production_today")|float(-99))|first] }}

First line defines the input:output mapping; second line pulls the output from your other sensor, set to default to a “flag” value of -99 if it is not available.

This assumes that your other sensor doesn’t go below 0 — it will return 45 for any negative value from -0 to -99, and break for any value below -99. Adjust the mapping to suit if that assumption is wrong.

An alternative would have been a simple addition to the start of your existing template:

         {% if not(states("sensor.energy_production_today")|is_number) %}
          45
         {% elif states("sensor.energy_production_today")|float >= 12 %}
          30
(etc)
1 Like

Thanks that’s really helpful, I was unaware of the mapping function, everyday is a school day.

It’s just a Jinja2 / Python dictionary, a set of key:value pairs. You’ll usually encounter it with string keys and possibly more complex structures in the values — I’ve used it with numbers on both sides here.

The inside of the square brackets returns the first key that is less than or equal to the other sensor; the line as a whole returns the associated value.

1 Like