How to write a loop to detect the index of equal strings

Hi there, I’m a pretty newby with yaml and struggling with creating a loop-sequence that compares two strings: one from a list and one given.

The initial part is then:

alias: analog_audio_amplifier_irremote
fields:
  fncmsg:
    description: remote control button/function related to an ir-code
    example: toggleonoff
variables:
  ircodes:
    - name: toggleonoff
      value: LONG_IR_SEQUENCE_STRING_1
    - name: volume_up
      value: LONG_IR_SEQUENCE_STRING_2
    - name: volume_down
      value: LONG_IR_SEQUENCE_STRING_3
  index: -1

I tried the following:

sequence:
  - repeat:
      count: "{{ ircodes|length }}"
      sequence:
        - choose:
            - conditions:
                - "{{ ircodes[loop.index - 1].name == fncmsg }}"
              sequence:
                - service: variable.set_variable
                  data:
                    variable: index
                    value: "{{ loop.index - 1 }}"

[ Unable to find service variable.set_variable ]

and

sequence:
  - repeat:
      count: "{{ ircodes|length }}"
      sequence:
        - choose:
            - conditions:
                - "{{ ircodes[repeat.index-1].name == fncmsg }}"
              sequence:
                - variables:
                    index: "{{ repeat.index - 1 }}"

[ nothing works ]

and

sequence:
  - repeat:
      while: "{{ {{ ircodes[repeat.index-1].name == fncmsg }} and repeat.index <  {{ ircodes|length }}  }}"
      sequence:
      - variables:
          index: "{{ repeat.index - 1 }}"

[ Message malformed: Expected a dictionary @ data[‘sequence’][0][‘repeat’][‘while’][0] ]

non of these works. What is the proper way?

Many thanks in advance.
regards,
Kees

I know how to solve this but I need to understand why you want to get the matching name’s index instead of its corresponding value.

In other words, if the value of fncmsg is toggleonoff, why do want to return 0 instead of LONG_IR_SEQUENCE_STRING_1?

That’s because variable.set_variable isn’t a native service call. It’s part of a custom integration that implements global variables.

Here are two ways to do it, neither requires the use of repeat - count.

The first way uses the same data structure you created (a list containing three dictionary items). If there’s no match, the value of index is -1.

variables:
  ircodes:
    - name: toggleonoff
      value: LONG_IR_SEQUENCE_STRING_1
    - name: volume_up
      value: LONG_IR_SEQUENCE_STRING_2
    - name: volume_down
      value: LONG_IR_SEQUENCE_STRING_3
  index: >
    {% set n = ircodes | selectattr('name', 'eq', fncmsg ) 
      | first | default('', true) %}
    {{ ircodes.index(n) if n != '' else -1 }}

The second way uses a simpler data structure (a dictionary containing three items). As a bonus, this example also reports the name of the matching value. If there’s no match, index is -1 and name is unknown. Feel free to remove the name variable if it’s unnecessary for your application.

variables:
  ircodes:
    toggleonoff: LONG_IR_SEQUENCE_STRING_1
    volume_up: LONG_IR_SEQUENCE_STRING_2
    volume_down: LONG_IR_SEQUENCE_STRING_3
  index: >
    {% set n = ircodes.keys() | list %}
    {{ n.index(fncmsg) if fncmsg in n else -1 }}
  name: "{{ ircodes.get(fncmsg, 'unknown') }}"

Hi Taras,
thank you for your time and effort.

Actually, I want to have the index, so I can use that to transfer the proper value afterwards.
From a table or list of contextual names and a corresponding ircode value, I want to use the index to send an ir-code-sequence to a Tuya-IR-remote.

I used ChatGPT to translate py-code to yaml :wink: which have been useful before. But now, I stuck unfortunately :frowning: .
I’ll proceed with your help and advice.
Thanks again!

Then both of the two examples I posted above will report the index value.

If you want to send the IR code that corresponds to the value of fncmsg then you don’t need the index value, just the corresponding IR code.

Post the service call that you intend to use to send the IR code. I’ll show you how to use a template to send the IR code that corresponds to the value of fncmsg.

Dear Taras,
thank you very much for your help. I appreciate your time en effort very much.

I have quite some difficulties with the yaml scripting language. I recognize the structure of a loop or a statement in yaml but I couldn’t figure out these things myself. Even with experience with Matlab, Python and C. I already created some more extensive scripts for HA in python but in case of some simple automatons it can be an advantage to implement these in yaml.

With you help, this is the result … and it works :star_struck:

alias: denon_irremote
fields:
  fncname:
    description: remote control button/function name related to an ir-code
    example: toggleonoff
variables:
  irmsgcodes:
    toggleonoff: >-
      CSEBEAMhAVYH7wBABwEQA8AH4AMLA+8AVgdAD4ADgAsJRAEQAyEB+rQhAUAHA1YH7wBAB8ADAVYHwAMF7wBWByEBQBdAB0ADARADgBNAC+AFPwXvABADIQGAA8ALgAdAKwEQA4AD4AML4A0/Ae8AQCOAA0ALBO8AEANE4AAPCxADIQFWByEBVgchAQ==
    volume_up: >-
      D78AIwO/AFkHGAEjA+sAIwNABwEYAYAPQAcF6wBZBxgBQAvAA4APCesAIwMYAQexGAFABwFZB0APAL8gE0ADgAsFWQcYASMDgANACwFZB0ATAUcBQBMBWQdAAwLrAAfgAD9AFwXrACMDGAFAAwlZBxgBIwPrAFkHQANAG0APgAMLWQcYASMDGAEjA+sA
    volume_down: >-
      CwYBJwMGATcH2gAnA0ADAQYBgAOACwI3BzVgAwInAwYgA8ATQAuAAwnrsAYBJwPaADcHQCNAA0APATUBQA8BNwdAC4ADATcHQA+AA0ATwAsD67A1AYAPAAZgB0ALBScD2gAnA0AHBAYBNwc1YAMBJwPgAQMLNwfaACcD2gAnAwYB
    volume_mute: >-
      CekA+wIkAU4HJAFAB8ADQA8BTgfAG4AH4AMbwAsD9bAkAUALA04HJAFAB+ABA4AzAU4HQAcAUSAHgAtAB4APQBML6QD1sOkA+wLpAE4HgBcB+wKABwFOB0ADC+kA+wLpAE4HUQH7AuABAwtOB1EB+wJRAfsCUQE=
    source_aux: >-
      CykBAANTAUkH7QAAA0ALQAfAAwApIBcBKQFABwIAA1MgA4AHgBMBUwFAAwG/sMAT4AEzBwAD7QBJBykBQAMFAANTAUkH4AEPQAsBAANAB4ADCb+wUwEAA1MBSQdAF4ADAE+gBwAAIAcGSQcpAQADUyADwAcNUwFJB1MBAANTAQADUwE=

  index: >
    {% set n = irmsgcodes.keys() | list %} 
	{{ n.index(fncname) if fncname in n else -1 }}
  name: "{{ irmsgcodes.get(fncname, 'unknown') }}"
sequence:
  - service: mqtt.publish
    data:
      payload: >-  
        {"ir_code_to_send": """ {{ name }} """} 
      topic: zigbee2mqtt/IRRemoteControl (Livingroom)/set

mode: single
icon: mdi:remote

Glad to my suggestion solved the problem.

Please consider marking my post above with the Solution tag. It will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. This helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.