Input_number type inconsistency

Why is it that when using an input_number in a template it is read as a string but when writing to it with input_number.set_value, it needs to be a number?

e.g.

Has to be cast as an int - because it is read as a string:

   - condition: template
      value_template: "{{ states('input_number.cinema_lights') | int == 0 }}"

Has to be set as a number:

  action:
  - service: input_number.set_value
    data_template:
      entity_id: input_number.cinema_lights
      value: 100

That last one threw me for a loop because I had specified it as value: "100" and all sorts of weird behaviour was happening.

Everything works that way, not just input numbers. Just check your sensors, they’ll behave the same way. So if you have any logic that requires them to be numbers, you should be casting them.

Yeah but when not using templates they are treated as numbers. Is that not inconsistent?

No, it’s that way inside templates too…

You are saying that it’s not inconsistent because templates treat everything as strings.

I’m saying it is inconsistent because outside the template numbers are numbers but inside templates they are treated as strings.

Maybe you are confusing attributes with the state of an object?

Attributes return the correct type, states always return strings.

So on an input number the min attribute will return a float:

Strings multplied by 2 will result in double string
{% for input_number in states.input_number %}
{{ input_number.entity_id }} state multiplied by 2
  object without cast: {{ input_number.attributes.min * 2 }}
  method without cast: {{ state_attr(input_number.entity_id,'min') * 2 }}
{% endfor %}

All ‘main’ states in home assistant everywhere are strings. I’m not sure why this was done, but that is the case. My guess is that it was done because Jinja only returns strings.

I’m not sure. Take my input_number as an example, this is the way I see it:

It has these attributes:

min: 0 max: 100 step: 25 mode: slider unit_of_measurement: % friendly_name: Cinema Lights icon: mdi:lightbulb

Some attributes are strings and some are numbers.

But it’s ‘main’ state can be any of the following numbers, 0, 25, 50, 75 or 100. And if I want to set that state in an action I have to supply a number, not a string.

But as you can see in my example above the ‘main’ state of an input_number is not a string.

I’m not trying to be argumentative by the way. Just trying to understand, and I appreciate your patience in helping with my lack of understanding because it is things like this that keep tripping me up when configuring HA.

There’s really nothing to understand here other than all ‘main’ states that you grab in home assistant are strings.

The inputs themselves are driven by yaml. When you use ‘value: 100’ in the input, while it may look like a number to you, it’s actually a string when pulled into yaml. Now this is all conjecture, but homeassistant or the yaml library in python most likely has a method to detect which kind of python type the object is. When you place quotes on it, it most likely says “Hey this is a string, not a number because it has quotes”. So leaving out the quotes in the yaml is most likely casting it as an integer.

Can you see how this looks illogical to me and why I keep stuffing it up?

Reading a state is a string, but supplying a state looks like a number. Especially for something called ‘input_number’.

I understand it’s illogical. But what your seeing is a nuance of the yaml python library (which tries to make yaml easier by strongly typing your inputs, I.E. converting inputs to the correct type). See documentation:

And then you are also seeing what was a decision made by the hass team: All ‘main’ states are strings.

I do not know why this was done and I could make guesses. I would wager that because templates (jinja) only returns strings, and user interfaces only display strings, that the logical method to store states is as a string.

1 Like