Template calculation returns non-numeric values

I am trying to subtract to entity states for an automation to shut off my water mains if too much water is used. I want to enter a value of 1-10M³, and when consumption reaches a threshold, an automation is triggered to switch off a relay and close a valve.

# Water M³ Template
  - platform: template
        friendly_name: "Water M³"
        unit_of_measurement: "M³"
        value_template: "{{ (states('sensor.testswitch_counter_today') | float * 0.01) | round(2) }}"

#The value_template below is troublesome!!!!!!!!

        value_template: ({{ (states('input_number.m3_cut_off')|float 
                         - states('sensor.testswitch_counter_today') | float * 0.01) }})

The troublesome value template above results in a value of (9.99) because it is wrapped in brackets, whereas if it is wrapped in quotes, it results in a value of “9.99”.
The developer tools say I should insert the value template as follows:

        value_template: {{ (states('input_number.m3_cut_off')|float 
                         - states('sensor.testswitch_counter_today') | float * 0.01) }}

I would be really grateful if anyone can tell me how to solve this.

Many thanks in advance.

Eh, you get a pulse to counter every 100m3 ?

No. I get a pulse per 10L.

Yep !, I see, I’ll look further

If you specify the value for value_template right next to it then it must be wrapped in quotes and all on one line like this:

value_template: "({{ (states('input_number.m3_cut_off')|float  - states('sensor.testswitch_counter_today') | float * 0.01) }})"

To specify a multi line template for value_template and not have to wrap it in quotes you must use YAML’s multi-line scalar format. So for example, like this:

value_template: >-
  ({{ (states('input_number.m3_cut_off')|float 
    - states('sensor.testswitch_counter_today') | float * 0.01) }})

The reason it seems to work in the template tab of developer tools is because that box is automatically assumed to be a multi-line template. When writing YAML you must tell it if your scalar is multi-line or not.

Thanks. I made the changes and restarted HAssOS. I will test it in 5-10 minutes when all is back up and running and let you know.

For future reference, you don’t need to restart HA if all you changed is a template sensor. From the server controls tab you can have it reload just template entities like template sensors without restarting HA using this option:

Thank you for both bits of useful information and for being kind enough to give pearls of wisdom to noobs.

In reality I have no idea of what I am doing and no plan. Everything is named test_this and test_that on my system. I hacked a python program the other day; the poor developpers, if they saw what I did they’d probably would call it butchery!

Thanks again for your help!

1 Like

Np! We’ve all been there. I’ve done mass refactors more times then I care to count :slight_smile:

I don’t think you should put round brackets around any template

I agree.

I don’t think that will work. I’m surprised that it didn’t throw an error of some kind.

Looking at what you have and what you want, I’m not sure I’d do it this way.

I would create the sensor as you suggest as that gives me how much I’ve used today (useful)
So : -

sensor:  #### not sure where you are putting your sensors, but this should be okay for both main config or packages.
#### If you have a sensor.yaml then you don't need the *sensor:* and indents go back two.
  - platform: template
        friendly_name: "Water"
        unit_of_measurement: "m³"
        value_template: "{{ (states('sensor.testswitch_counter_today') | float * 0.01) | round(2) }}"

This is almost exactly what you have. (why repeat the M3 bit ??? Also ‘metre’ units are ‘m’ not ‘M’)
Now, the next bit is where opinions may diverge …

I’d create a binary sensor that is ‘on’ when the sensor you just created exceeds a threshold you have in a given input_number (ie input_number.m3_cut_off - again, what you have, assuming you have 1 to 10 as your range, but whatever range you actually need)
so the binary sensor would be : -

  - platform: template
        value_template: >
          {% set limit = states('input_number.m3_cut_off') | float %}
          {% set current = states('sensor.water_m3') | float %}
          {{ current >= limit }}
        friendly_name: Water Shut Off/On
#### inverted would be : - {{ current < limit }} ## see further down

This ‘could’ be shortened (not always simplified) to : -

  - platform: template
        value_template: "{{ states('sensor.water_m3') | float >= states('input_number.m3_cut_off') | float }}"
        friendly_name: Water Shut Off/On

This way (with the binary sensor you can switch the valve ‘on’ and ‘off’ from one automation.
e.g. : -

  #water valve control
  - alias: au_switch_water_valve
    mode: restart
      - platform: state
        entity_id: binary_sensor.bs_water_control
      - service_template: switch.turn_{{trigger.to_state.state}}
        entity_id: switch.switch_water_valve

This assumes ‘exceeded’ cuts valve ‘off’ by turning the switch ‘on’ (otherwise invert the logic in the binary sensor) [Note it will also turn the valve back ‘on’ when the counter is reset]

I also assume you have an automation that fires every ‘midnight’ ??? to reset the counter ???

  - alias: au_water_reset
    mode: single
    max_exceeded: silent
      - platform: template
        value_template: "{{ states('sensor.time') == '00:01' }}"
#### Note: best to avoid '00:00' if you can, a lot of HA activity goes on at '00:00'
      - service: input_number.set_value
          entity_id: input_number.m3_cut_off
          value: 0

Note this is a template time trigger and is 60 times more efficient than a standard ‘time’ trigger as that evaluates every second.

@finity, can you please cast your eye over this, I hate posting code I can’t check

@jbizeray, I don’t use the Automation Editor so you version ‘may’ look a bit different, but at least this gives you a general structure to be aiming at.

Looks good to me.

Thankyou kind sir :smiley:

1 Like