Type confusion (number vs string) when passing script field parameters from automation

I am very confused how to control the type of a field parameter that I want to pass from an automation to a script.

I have an input_select with two numeric value options that I defined as strings:

  evcc_wallbox_phases_status:
    name: evcc Wallbox Phasenumschaltung
    icon: mdi:ev-station
    options:
      - "1"
      - "3"

I have an automation to fire a script when the input_select is changed:

  - id: evcc_wallbox_phases_status_changed
    alias: evcc Wallbox Phasenumschaltung ausgelöst
    trigger:
      - platform: state
        entity_id: input_select.evcc_wallbox_phases_status
    action:
      - service: script.evcc_wallbox_phase_switch_changed
        data:
          phases_selected: "{{ trigger.to_state.state }}"

In this case the field parameter will be passed to the script as a number:

From the script trace:

phases_selected: 1

If I pass the field parameter directly, it will be transferred as a string:

  - id: evcc_wallbox_phases_status_changed
    alias: evcc Wallbox Phasenumschaltung ausgelöst
    trigger:
      - platform: state
        entity_id: input_select.evcc_wallbox_phases_status
    action:
      - if:
          - condition: template
            value_template: "{{ trigger.to_state.state == '3' }}"
        then:
          - service: script.evcc_wallbox_phase_switch_changed
            data:
              phases_selected: "3"
        else:
          - service: script.evcc_wallbox_phase_switch_changed
            data:
              phases_selected: "1"

From the script trace:

phases_selected: '3'

Why is this inconsistent, it is very confusing. I tried to use filters |string but without effect.

Any ideas?

It’s not inconsistent.

This passes the value via a template and is therefore subjected to Home Assistant’s native typing.

phases_selected: "{{ trigger.to_state.state }}"

In other words, the template’s result is automatically assigned a type; the result appears to be numeric so its type is automatically assigned to be a number.

In contrast, this passes the value as a literal string.

phases_selected: "3"

Thanks, that is what I felt. Not sure whether I can agree though that it is consistent …

If I do an explicit string conversion

phases_selected: "{{ trigger.to_state.state | string }}"

the result will still be passed on to the script as number.

I tried putting additional single quotes around:

phases_selected: '"{{ trigger.to_state.state }}"'

This will be passed as string with additional quotes, which is actually correct in a sense, but again not what I am trying to achieve.

phases_selected: '"3"'

Can I somehow enforce that a string which is containing a numeric value is passed from the template as a string to the script? Or do I need to handle the conversion within the script?

Because native typing evaluates the template’s result and, based on the result’s appearance, sets its type. Therefore it doesn’t matter if you add a string filter; if the final result’s appearance is numeric then its type will be a number (int or float).

That would be the simplest way.

Also, why do you need to handle a numeric value as a string?


EDIT

You can also try to pass the service call’s data in JSON format.

    action:
      - service: script.evcc_wallbox_phase_switch_changed
        data: "{{ {"phases_selected": trigger.to_state.state} }}"

EDIT

Removed redundant string filter.

No need for the string filter there, the state will already be a string

1 Like

Thanks! I copy-pasted OP’s template and overlooked to remove the redundant string filter.

Thanks. Passing the json looks good to me. I still don’t think though that HA should do it’s own type evaluation of templates. If I say it’s a string, it’s because I want it to be :wink:

I had been using the same script with different inputs. Initially I used a switch that directly sent “1” and “3” as parameters, then I changed to an input_select and went for the template.

I am using HA for a couple of months now, my background is mostly C#. I still struggle with the way HA treats string, int and boolean types. Sometimes a number is a number, sometimes it’s a string. Sometimes off is the same as “off”, sometimes it’s not.

In previous versions (long ago) it didn’t. The result of every template was a string and only a string. That was far more limiting than the way it works now.

I can understand why someone would feel that way if they don’t understand how Home Assistant’s native typing works.

It works according to the simple rule: “If it looks like a duck, it’s a duck.” :slightly_smiling_face:

In your example, the template’s result looks like a number, so it’s a number.

1 Like

Yeah, maybe it’s just me coming from a strongly typed programming language … the whole yaml / jinja thing still makes my skin crawl :crazy_face: