How Can You Render Lists from data_template

I’m working on an automation for switching an HDMI switcher. I have a broadlink RM Mini 3 to control it.

I set up an input_selector for the choices and then an automation to use the switch.broadlink_send_packet service on change. The problem is, this service expects a list of packets, not just a string. And the data_template seems to be returning a string no matter what.

I’ve tried a million combos in the data template, but none of them seem to work. Here’s what I have configured currently, and the resulting log from the automation and resulting log of a good working service call. They look the same, but I think the service call from the automation is using a string not an actual list.

Thanks so much if anyone can help me out with this!

Config

input_select:
  rack_hdmi_switcher:
    name: Rack HDMI Switcher
    options:
      - Fire TV 4K
      - Apple TV
      - Shield
      - Fire TV
    icon: mdi:video-input-hdmi

automation:
  - alias: Select Input
    trigger:
      - platform: state
        entity_id: input_select.rack_hdmi_switcher
    action:
      service: switch.broadlink_send_packet_192_168_1_184
      data_template:
        packet: >
            {% if is_state("input_select.rack_hdmi_switcher", "Fire TV 4K") %}
              {{ ['JgBOAJWTFBESEhMREzcTERMSEhITERMSEhITERM3ExETEhISExETNxM2EzcTNhITEhITERMSEhITERMSEhITNxM2EzcTNhMABkuVkxM3EwANBQAAAAAAAAAAAAA=='] }}
            {%-elif is_state("input_select.rack_hdmi_switcher", "Apple TV") %}
              {{ ['JgBOAJWTExETEhISEzcSEhMRExISEhMRExISEhM2ExISEhMRExITERM3ExETERM3ExETEhISEzYTEhM2EzcTERM3EzYTNxMABkuVkxM2EwANBQAAAAAAAAAAAAA=='] }}
            {%-elif is_state("input_select.rack_hdmi_switcher", "Shield") %}
              {{ ['JgBOAJWTExISEhMREzcTERMRExITERMRExITERM3EhITERMSEhITNxISExETNxM2ExITERMRExISNxM3EhITERM3EzYTNxMABkuVkRU2EwANBQAAAAAAAAAAAAA=='] }}
            {%-elif is_state("input_select.rack_hdmi_switcher", "Fire TV") %}
              {{ ['JgBWAJWTExISEhMREzcTERMSEhITERMSEhITERM3ExETEhISExETNxM2EzcTNhM3ExETEhISExETEhISExETEhI3EzcTNhMABkuVjhg3EwAMM5WTEzYTAA0FAAA=='] }}
            {%-elif is_state("input_select.rack_hdmi_switcher", "Input 5") %}
              {{ ['JgBOAJSUEhITERQREjcTEhISExETEhISExEUERI3ExEUERISExETEhMREzcSNxM3ExETERMSEzYTNxMRExISEhM2EzcTNhMABkyUkxM3EwANBQAAAAAAAAAAAAA=='] }}
            {% else %}
              none
            {% endif %}

Log

2018-02-08 12:36:08 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=switch, service=broadlink_send_packet_192_168_1_184, service_data=packet=[‘JgBOAJWTFBESEhMREzcTERMSEhITERMSEhITERM3ExETEhISExETNxM2EzcTNhITEhITERMSEhITERMSEhITNxM2EzcTNhMABkuVkxM3EwANBQAAAAAAAAAAAAA==’], service_call_id=139788500585664-31>

Log of a good working service call

2018-02-08 04:07:19 INFO (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=switch, service=broadlink_send_packet_192_168_1_184, service_data=packet=[‘JgBOAJWTExISEhMREzcTERMRExITERMRExITERM3EhITERMSEhITNxISExETNxM2ExITERMRExISNxM3EhITERM3EzYTNxMABkuVkRU2EwANBQAAAAAAAAAAAAA==’], service_call_id=140610925919424-42>

Unfortunately I am experiencing the same. Didn’t see your topic as I was busy writing mine for some time now: Two almost identical scripts: one works, one not

I guess the problem looks pretty similar to me.

Have you tried like this?

{% if is_state("input_select.rack_hdmi_switcher", "Fire TV 4K") %} JgBOAJWTFBESEhMREzcTERMSEhITERMSEhITERM3ExETEhISExETNxM2EzcTNhITEhITERMSEhITERMSEhITNxM2EzcTNhMABkuVkxM3EwANBQAAAAAAAAAAAAA==

OK, it turns out you can’t do this. You can’t return lists.

Templates return strings, period.

If anyone comes across this looking for how to do this for broadlink, a patch just went through that ensures the input to the broadlink_send_packet service is wrapped in a list.

This allows you to just call it with a string, and the component will ensure it gets put in a list. This means you can use a data_template just fine by returning a simple string, and it will just work.

Just a quick follow up. Templates itself can indeed not return lists. If you want to return a list, construct the data_template to contain lists and they will be preserved.

Here is an example of using data_template to create a script to set color based on input value:

script:
  dynamic_light:
    sequence:
      service: light.turn_on
      entity_id: light.kitchen_lights
      data_template:
        rgb_color:
          - "{% if color == 'red' %}255{% else %}0{% endif %}"
          - "{% if color == 'green' %}255{% else %}0{% endif %}"
          - "{% if color == 'blue' %}255{% else %}0{% endif %}"

rgb_color will be passed as a list to the turn_on service.

4 Likes

Is this also possible for lists in lists? E.g. [[item1a,item2a,item3a], [item1b, item2b, item3b]] and if yes, how can I do it?

sc_set_yorkac_test:
  sequence: 
    - service: switch.broadlink_send_packet_192_168_x_x
      data_template:
        data: 
          packet:
            - "{%- if is_state('sensor.climate_york_temp' , '25.0' ) -%}JgDKAJGQEjYSEhI1EzUTERMREzUSEhISEjYAAAA=={%- elif is_state('sensor.climate_york_temp' , '26.0' ) -%}JgDKAJKPEzUSEhI2EjUTERMREzUSEAAAAAAAA=={%- else -%}JgDKAJGREjYSEhE2EzUTERISEjYSEhIdafafffAAAA=={% endif %}"

I tried and it did not working.
throw error data is not list

Also tried spliting into multiline

    - service: switch.broadlink_send_packet_192_168_x_x
      data_template:
        data: 
          packet:
        - "{%- if is_state('sensor.climate_york_temp' , '26.0' ) -%}JgDKAJGQEjYSEhI1EzUTERMREzUSEhISEjYSEhISEjAA=={%- endif -%}"
        - "{%- if is_state('sensor.climate_york_temp' , '27.0' ) -%}JgDKAJKPEzUSEhI2EjUTERMREzUSEhISEjYSEhAAA=={%- endif -%}"

throws error list cannot be empty.
Please note i truncated the code ir code to made it readable here

Anyone got a good working sample ?

Hello,

Do you have an example how to do this? An automation that sends packet based on input select.

Thank you in advance!

I had the same problem, but thanks to this thread and this stackoverflow page https://stackoverflow.com/questions/23657086/yaml-multi-line-arrays I ended up finding these solutions:

Option 1:

press_ir_button:
  alias: Press IR Button
  sequence:
  - data_template:
      packet:
        - "{% if button == 'sat_power' %}JgBQAAABKZQTNxM3EhMTEhMSExMSExMSExITExI3EzcTNhM3EzcTNhM3ExMSExMSEzcTEhMSExMSExM2EzcTNxMSEzcTNhM3EwAFJwABKEoTAA0FAAAAAAAAAAA=
          {% elif button == 'tv_power_off' %}JgBGAJOVEDoQOhA6DxYPFhAVEBUQFRA6ETkROREUERQRFBEUEBUQFREUERQRORE5EBUQFRE5ETkRORE5ERUQFRA6DzsPFhAADQUAAA==
          {% else %}{% endif %}"
    service: switch.broadlink_send_packet_xxx_xxx_xxx_xxx

Option 2:

press_ir_button:
  alias: Press IR Button
  sequence:
  - data_template:
      packet:
        - "{% if button == 'sat_power' %}JgBQAAABKZQTNxM3EhMTEhMSExMSExMSExITExI3EzcTNhM3EzcTNhM3ExMSExMSEzcTEhMSExMSExM2EzcTNxMSEzcTNhM3EwAFJwABKEoTAA0FAAAAAAAAAAA={% else %}{% endif %}"
        - "{% if button == 'tv_power_off' %}JgBGAJOVEDoQOhA6DxYPFhAVEBUQFRA6ETkROREUERQRFBEUEBUQFREUERQRORE5EBUQFRE5ETkRORE5ERUQFRA6DzsPFhAADQUAAA=={% else %}{% endif %}"
    service: switch.broadlink_send_packet_xxx_xxx_xxx_xxx

Personally, I prefer the option 1, because with second one you can get many empty items in the array.

Hope it helps someone…