Combine 2 template sensors (simplify into one sensor)

Hi everyone,

I’m wondering if i could combine these two sensors into one (essentially integrate the second into the first), so i have only one sensor? (For sakes of simplicity and to keep the amount of sensors low).

The first one essentially adds up all sorts of power and gives me a value of power usage of my home (solar power and solar battery included). This works fine, but sometimes gives me a negative value, which makes no sense here (i think this is happening, when some sensor returns “unavailable” or so.

For this reason i use the second sensor. This one takes every value lower than 0 and returns a 0.
This works fine too.

- name: "Haus Watt now"
  unique_id: "haus_watt_now" 
  unit_of_measurement: 'W'
  device_class: power
  state_class: measurement
  state: >-
    {{ states ('sensor.grid_power_2') | float
     - states ('sensor.battery_power_charge_total') | float 
     + states ('sensor.battery_power_discharge_total') | float
     - states ('sensor.metering_power_supplied') | float 
     + states ('sensor.metering_power_absorbed') | float}}
- name: "Haus Watt now >0"
  unique_id: "haus_watt_now_>0" 
  unit_of_measurement: 'W'
  device_class: power
  state_class: measurement
  state: >-
    {% if states ('sensor.haus_watt') | int > 0 %}
              {{ states ('sensor.haus_watt') }}
            {% else -%}
              0
            {% endif %}

So my goal would be to incorporate the second one (>0) into the first and get rid of the second one.

Thanks a lot!

You need to define a default value for your float filters. There will be warnings about this in the log. In future your template may fail to load.

You should also define an availability template to avoid reporting the value when one of the sensors is not available.

- name: "Haus Watt now"
  unique_id: "haus_watt_now" 
  unit_of_measurement: 'W'
  device_class: power
  state_class: measurement
  state: >
    {{ states ('sensor.grid_power_2') | float(0)
     - states ('sensor.battery_power_charge_total') | float(0)
     + states ('sensor.battery_power_discharge_total') | float(0)
     - states ('sensor.metering_power_supplied') | float(0) 
     + states ('sensor.metering_power_absorbed') | float(0) }}
  availability: >
    {{ states ('sensor.grid_power_2') | float(none) != none and
       states ('sensor.battery_power_charge_total') | float(none) != none and
       states ('sensor.battery_power_discharge_total') float(none) != none and
       states ('sensor.metering_power_supplied') float(none) != none and
       states ('sensor.metering_power_absorbed') | float(none) != none }}
2 Likes

Thank you very much,

if you don’t mind me asking:

  1. the float(0) is defaulting this sensors state to “0” if no data from this sensor is delivered at all, right?
  2. due the availability:-part, the state-calculations are not performed, if one of the sensors delivers no float (i.e. unavailable or something like that), right?

I would like do do the state:-calculations even if ONE sensor is delivering no data and in that case use a “0” for the calculation.

Or am i misinterpreting the above?

  1. Yes. If the float filter cant find anything it can convert to a number in this case it is replaced with 0, you can use other options.

  2. Not yet. At the moment the state template is evaluated but the availability template replaces the state with unknown if the availability is false. I believe there is a PR in the works to actually prevent the state template being evaluated if the availability is false. This should prevent things like division by zero errors being reported. Which is what happens now even when the state is unavailable.

Then you may end up with a

It is the availability template’s job to prevents this.

Ok, i think i’m getting it now.
I’m going to implement your suggestion and diving a bit more into this.
Still and always a lot to learn :slight_smile:

Thanks for your help and explantions, very much appreciated!

After pasting this into the developer tools → templates, i got an error but found the missing | after sensor 3 and 4 in the code below.
Always these simple things and one have to stare 5 minutes at this. :slight_smile:

I still get sporadic negative values (i think this happens, when one of the sensors is a bit “late” with it’s values).
That’s no big problem, but i still would like to “cap” these negative values to 0 (no negatives).

So the question remains:
Is it possible to integrate my second template sensor (see above) into the first one?
I would like to have only one sensor for both jobs (“add the sensors up” and "if result is negative → replace result with 0, otherwise show result).

  state: >
    {{ [0, states ('sensor.grid_power_2') | float(0)
     - states ('sensor.battery_power_charge_total') | float(0)
     + states ('sensor.battery_power_discharge_total') | float(0)
     - states ('sensor.metering_power_supplied') | float(0) 
     + states ('sensor.metering_power_absorbed') | float(0) ]|max }}

Ah, that works just brilliant!
Thank you very much.

Just one last question: The leading 0, and the |max at the end - i suppose they work together?
What exactly do they do? Maybe i’m a bit slow on this, but i cannot “read and interpret” this for me.

I wanna learn something and understand what i’m writing into my yaml… :slight_smile:

The max fitlter selects the maximum value of a list. So [0, -4]|max would return 0.

1 Like

Thank you!

Pro tip: If you want to bound something between two limits use the sort function (which sorts by numerical size) then pick the middle one.

e.g to bound a value between 0 and 10

{{ ( [0,10, your_value]|sort )[1] }}

the list index starts counting from 0 so [1] is the middle item.

This is much easier than using

{{ [ [ your_value, 0 ]|max, 10 ]|min }}

The form user 123 (taras) pointed out this tip.

1 Like

Hi @cpo this was exactly wat I was looking for and what lacked in the energy dashboard in my opinion!
Now I can combine tariff 1 and tariff 2 (WAF factor) to be a better overview.

How did you put these sensors in your configuration.yaml? I am not that experienced and cannot get a valid confg. Any advice would be very appreciated!

Below my configuration.yaml with the sensors based on your input commented out.

# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:

# Text to speech
tts:
  - platform: google_translate

automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml

# google home
google_assistant:
  project_id: domoindepuntjes-39bd2
  service_account: !include SERVICE_ACCOUNT.json
  report_state: true

# Example configuration.yaml entry to enable the cloud component
cloud:

# Lampen in groepen
light:
  - platform: group
    name: Alle tuinverlichting
    entities:
      - light.afdak_1
      - light.afdak_2
      - light.afdak_3
      - light.afdak_4
      - light.afdak_5
      - light.boom_1
      - light.boom_2
      - light.boom_3
      - light.boom_4

# Sensoren
sensor:
  - platform: command_line
    name: CPU Temperature
    command: "cat /sys/class/thermal/thermal_zone0/temp"
    # If errors occur, make sure configuration file is encoded as UTF-8
    unit_of_measurement: "°C"
    value_template: "{{ value | multiply(0.001) | round(1) }}"
  - platform: afvalbeheer
    wastecollector: ROVA
    resources:
      - gft
      - papier
      - pmd
    postcode: 8032TV
    streetnumber: 30
    dateformat: '%d %b'
    dateonly: 0
    nameprefix: 0
    builtinicons: 1
    dutch: 1

#    name: "Panelen totaal"
#    unique_id: "panelen_totaal" 
#    unit_of_measurement: 'W'
#    device_class: power
#    state_class: measurement
#    state: >
#      {{ states ('sensor.energy_production_tarif_1') | float(0) | round(0)
#       + states ('sensor.energy_production_tarif_2') | float(0) | round(0)}}
#    availability: >
#      {{ states ('sensor.energy_production_tarif_1') | float(none) != none and
#         states ('sensor.energy_production_tarif_2') | float(none) != none }}
#
#    name: "Stroomverbruik essent"
#    unique_id: "stroomverbruik_essent" 
#    unit_of_measurement: 'W'
#    device_class: power
#    state_class: measurement
#    state: >
#      {{ states ('sensor.energy_consumption_tarif_1') | float(0) | round(0)
#       + states ('sensor.energy_consumption_tarif_2') | float(0) | round(0)}}
#    availability: >
#      {{ states ('sensor.energy_consumption_tarif_1') | float(none) != none and
#         states ('sensor.energy_consumption_tarif_2') | float(none) != none }}#
#
#    name: "Stroomverbruik netto"
#    unique_id: "stroomverbruik_netto" 
#    unit_of_measurement: 'W'
#    device_class: power
#    state_class: measurement
#    state: >
#      {{ states ('sensor.energy_production_tarif_1') | float(0) | round(0)
#       - states ('sensor.energy_consumption_tarif_1') | float(0) | round(0)
#       + states ('sensor.energy_production_tarif_2') | float(0) | round(0)
#       - states ('sensor.energy_consumption_tarif_2') | float(0) | round(0) }}
#    availability: >
#      {{ states ('sensor.energy_production_tarif_1') | float(none) != none and
#         states ('sensor.energy_consumption_tarif_1') | float(none) != none and
#         states ('sensor.energy_production_tarif_2') | float(none) != none and
#         states ('sensor.energy_consumption_tarif_2') | float(none) != none }}

# Luxaflexen
cover:
  - platform: mqtt
    name: "Luxatest"
    command_topic: "Luxatest/blindsCommand"
    set_position_topic: "Luxatest/positionCommand"
    position_topic: "Luxatest/positionState"
    retain: true
    payload_open: "OPEN"
    payload_close: "CLOSE"
    payload_stop: "STOP"
    position_open: 0
    position_closed: 36
    
# heating
climate:
  - platform: generic_thermostat
    name: Badkamertest
    heater: switch.radiator_badkamer
    target_sensor: sensor.knmi_domoindepuntjes_gevoelstemperatuur
    min_temp: 10
    max_temp: 30
    ac_mode: false
    #target_temp: 5
    cold_tolerance: 0.5
    hot_tolerance: 0.0
    min_cycle_duration:
      seconds: 20
    initial_hvac_mode: "heat"
    precision: 0.5

Give this a try, replace all your commented out section

template:
  - sensor:
      - name: "Panelen totaal"
        unique_id: "panelen_totaal" 
        unit_of_measurement: 'W'
        device_class: power
        state_class: measurement
        state: >
            {{ states ('sensor.energy_production_tarif_1') | float(0) | round(0)
            + states ('sensor.energy_production_tarif_2') | float(0) | round(0)}}
        availability: >
            {{ states ('sensor.energy_production_tarif_1') | float(none) != none and
                states ('sensor.energy_production_tarif_2') | float(none) != none }}

      - name: "Stroomverbruik essent"
        unique_id: "stroomverbruik_essent" 
        unit_of_measurement: 'W'
        device_class: power
        state_class: measurement
        state: >
            {{ states ('sensor.energy_consumption_tarif_1') | float(0) | round(0)
            + states ('sensor.energy_consumption_tarif_2') | float(0) | round(0)}}
        availability: >
            {{ states ('sensor.energy_consumption_tarif_1') | float(none) != none and
                states ('sensor.energy_consumption_tarif_2') | float(none) != none }}#

      - name: "Stroomverbruik netto"
        unique_id: "stroomverbruik_netto" 
        unit_of_measurement: 'W'
        device_class: power
        state_class: measurement
        state: >
            {{ states ('sensor.energy_production_tarif_1') | float(0) | round(0)
            - states ('sensor.energy_consumption_tarif_1') | float(0) | round(0)
            + states ('sensor.energy_production_tarif_2') | float(0) | round(0)
            - states ('sensor.energy_consumption_tarif_2') | float(0) | round(0) }}
        availability: >
            {{ states ('sensor.energy_production_tarif_1') | float(none) != none and
                states ('sensor.energy_consumption_tarif_1') | float(none) != none and
                states ('sensor.energy_production_tarif_2') | float(none) != none and
                states ('sensor.energy_consumption_tarif_2') | float(none) != none }}
1 Like

@Holdestmade working like a charm, many thanks!!

Sorry, seen it too late. But @Holdestmade wrote it exactly as i have in my configuration.
I have nothing mor to add to this :slight_smile:

Good morning,

I am still new to yaml and I cannot seem to get this resolved.

In my configuration.yaml file, I included the line:
sensor: !include sensor.yaml

In my sensor.yaml file I have:

- platform: template
  sensors:
    name: "Combined PV power"
    unique_id: "combined_pv_power"
    unit_of_measurement: "W"
    device_class: power
    state_class: measurement
    state: >
      {{ states ('sensor.solarman_pv1_power') | float(0) | round(0)
      + states ('sensor.solarman_pv2_power') | float(0) | round(0)}}
    availability: >
      {{ states ('sensor.energy_production_tarif_1') | float(none) != none and
          states ('sensor.energy_production_tarif_2') | float(none) != none }}

When i check configuration, I get the following error.

Invalid config for [sensor.template]: expected dictionary for dictionary value @ data[‘sensors’][‘availability’]. Got “{{ states (‘sensor.energy_production_tarif_1’) | float(none) != none and\n states (‘sensor.energy_production_tarif_2’) | float(none) != none }}\n”
expected dictionary for dictionary value @ data[‘sensors’][‘device_class’]. Got ‘power’
expected dictionary for dictionary value @ data[‘sensors’][‘name’]. Got ‘Combined PV power’
expected dictionary for dictionary value @ data[‘sensors’][‘state’]. Got “{{ states (‘sensor.solarman_pv1_power’) | float(0) | round(0) + states (‘sensor.solarman_pv2_power’) | float(0) | round(0)}}\n”
expected dictionary for dictionary value @ data[‘sensors’][‘state_class’]. Got ‘measurement’
expected dictionary for dictionary value @ data[‘sensors’][‘unique_id’]. Got ‘combined_pv_power’
expected dictionary for dictionary value @ data[‘sensors’][‘unit_of_measurement’]. Got ‘W’. (See ?, line ?).

Please can someone assist?
Thank you