Keep getting templating warnings, sensor unknown and unsupported operand

Hi all,

Since version 0.94 I’m getting warnings and errors in the log files, the sensors do work by the way.

I suspect that the warnings and error are because of the state not being populated (None/unknown), but I’ve tried numerous options. The warning in the frontend is:

Could not render template Temperatuur Woonkamer, the state is unknown.

The warning in homeassistant.log is the same, but the errors in the docker/portainer log are different:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 220, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 375, in async_device_update
    await self.async_update()
  File "/usr/src/homeassistant/homeassistant/components/template/sensor.py", line 191, in async_update
    self._state = self._template.async_render()
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 191, in async_render
    return self._compiled.render(kwargs).strip()
  File "/usr/local/lib/python3.7/site-packages/jinja2/asyncsupport.py", line 76, in render
    return original_render(self, *args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 1008, in render
    return self.environment.handle_exception(exc_info, True)
  File "/usr/local/lib/python3.7/site-packages/jinja2/environment.py", line 780, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/usr/local/lib/python3.7/site-packages/jinja2/_compat.py", line 37, in reraise
    raise value.with_traceback(tb)
  File "<template>", line 1, in top-level template code
TypeError: unsupported operand type(s) for +: 'float' and 'str'

I’ve tried these config variations:

{{
  not is_state('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature', 'unknown') and 
  ( states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature') | float
     + states('sensor.temperature_22') | float
  )  / 2 | round(2) 
}}
{% if states('sensor.temperature_22') %}
  {{ ( states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature') | float
       + states('sensor.temperature_22') | float
     ) / 2 | round(2)
  }}
{% endif %}        
{{
  ( (float(states.sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature.state)
    + float(states.sensor.temperature_22.state)
  ) / 2) | round(2)
}}  

What am I missing here?

not sure yet… trying with 2 sensors here:

{{
  ( (float(states.sensor.attic_motion_sensor_temperature.state)
    + float(states.sensor.attic_sensor_temperature.state)
  ) / 2) | round(2)
}}  

works fine. What happens when you enter the template in dev-template?

apparently one of the sensors is returning a string and not a float…

if still not sure, enter them separately in dev-template

{{states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature')|float}}

and

{{states('sensor.temperature_22') | float}}

and see what gives.

1 Like

Hi @Mariusthvdb,

The error is right after a restart of HA, so it must be that at some point the sensor is None or unknown. If I enter the code below in the dev-template window it works.

{{
  not is_state('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature_2', 'unknown') and
  ( (float(states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature_2'))
    + float(states('sensor.temperature_28'))
  ) / 2) | round(2)
}}

In line 2, I tried to catch the unknown state but this doesn’t seem to work.

The result of this template is pretty weird also: 26.0 #26.0 #26.0 #26.0

I also found a hint to change the code to: Like: states('sensor.temperature_22') | float(-1)

Full template:

{{
    not is_state('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature', 'unknown') and
    ( (states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature') | float(-1)
        + states('sensor.temperature_22') | float(-1)
    ) / 2) | round(2)
}}

But this doenst work neither :frowning:

The states() function will return 'unknown' if the entity is not in the state machine, or if it is but has a state of 'unknown'. If you then pass that value into the float() function, it will just pass that value through since it can’t be converted to a float. So,

float(states('sensor.X'))

will evaluate to 'unknown', which you can’t add to a float.

But, the |float filter behaves differently. It will return zero (by default) if the value cannot be converted to a float. Or, you can specify a different value to use in this case using |float(X), where X is the value you want it to use when the input cannot be converted to a float.

So, basically, this is what you want:

((states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature')|float
  + states('sensor.temperature_22')|float) / 2)|round(2)
2 Likes

Hi @pnbruckner, (edited…)

Your solution removed the python exception in my docker log! :slight_smile: There are some things left though:

  1. What to do with this warning, can I prevent this?
    2019-07-01 20:04:11 WARNING (MainThread) [homeassistant.components.template.sensor] Could not render template Temperatuur Woonkamer, the state is unknown.

  2. The next code results in a state with content: 24.5

{{
  ((float(states.sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature.state)
  + float(states.sensor.temperature_22.state)) / 2) | round(2)
}}
  1. And this code results in a state with content: 25.85 #25.85 #25.85 #25.85
{{
  ((states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature')|float
  + states('sensor.temperature_22')|float) / 2)|round(2)
}}

Thanks for your help! :slight_smile:

Could you post the entire definition of sensor Temperatuur Woonkamer, not just the value_template?

Sure, no problem:

  - platform: template
    sensors:
      livingroom_avg_temperature:
        friendly_name: 'Temperatuur Woonkamer'          
        unit_of_measurement: "°C"
        value_template: >-
          {{
            ((float(states.sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature.state)
            + float(states.sensor.temperature_22.state)) / 2) | round(2)
          }}
          #{{
          #  ((states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature')|float
          #  + states('sensor.temperature_22')|float) / 2)|round(2)
          #}}

You have to use the states() function, as I suggested, if you want to avoid warnings/errors.

If sensor.X is not in the state machine – which can happen when HA starts, because that sensor might not have updated yet before the template sensor gets a chance to update – states.sensor.X.state will generate an error, resulting in the warning you’re seeing, and the template sensor will not update.

If, however, in this same scenario, you use states('sensor.X'), that will not cause an error, and the template will be evaluated successfully, and the template sensor will update. Of course, since the state does not exist, the |float filter will return zero, which will be reflected in the value of the template sensor.

Your comment about the | float and another test made me start al over again. But I figured it out. The weird values were a couple of ( ) at the wrong places. I started again with the states() | float for both sensors. Added them then like (sensor1 + sensor 2) and then divided them by 2.

This resulted in:

(
  states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature')|float
   + states('sensor.temperature_22')|float
) / 2 | round(2)

And this is passing whithout any errors and the value of the sensor is now correct!! :slight_smile:

Sharing is caring they say :wink: , so here is the final solution for the sensor template:

{%
set c = (
  ((
    states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature_5') | float +
    states('sensor.temperature_31') | float
  ) / 2 ) | round(1) | string
).split('.')
%}
{{ c[0] ~ '.' ~ c[1][0:1] }}

I discussed the results of the sensor with @pnbruckner on Discord and told him that the sensor values jumped from 2 decimals to 10 or more decimals. He said that could be related to the float and that converting the whole thing to a string should do the job.

So to explain the template:
The ‘core’ config is shown below (which is familiar). It uses the states machine to catch unknown or None errors in the log when the sensors aren’t available yet. These values are being converted with float and divided by 2 to get a average. Then we want to show the temperature with one decimal.

( (states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature_5') | float +
states('sensor.temperature_31') | float ) / 2 ) | round(1)

Then to prevent the weird stuff happening with all the decimals @pnbruckner came with this:

{%
set c = (
  <% template-code-here %> | string # <-- See note 1
).split('.') # <-- See note 2
%}
{{ c[0] ~ '.' ~ c[1][0:1] }} # See note 3
  • Note 1: Convert the result of the template to a string
  • Note 2: Create a array of the string by splitting it a the ‘.’, the result wil be like: array ( 0 = "22", 1 = "50023238858");
  • Note 3:
    c[0] Pick the value of item 0 ( 22 ).
    ~ '.' ~ convert the first and second to a string if necessary and then join them with a period.
    c[1][0:1] Pick the value of item 1 ( 50023238858 ) and select only the first character.

Instead of the string-splitting, list-creating, string-concatenating gymnastics, why not just use format to specify the (float) number’s appearance?

Screenshot%20from%202019-07-03%2012-07-45

{% set c = (
            ( states('sensor.eurotronic_eur_spiritz_wall_radiator_thermostat_temperature_5') | float +
              states('sensor.temperature_31') | float
            ) / 2
           ) | round(1) %}
{{ '{:.1f}'.format(c) }}
1 Like