Is it possible to have an array of ids in ESPHome?

Hi all,

Here’s what I want to do. I have a fan that has 5 speeds (0-4), which I’m going to control with an IR transmitter. The transmitter is finally working, so now I’m moving on to the hardware interface.

Rather than have 5 buttons, I’d rather just have 2: Up and Down, for increasing and decreasing the fan speed.

In my head, it works like this. I have already set up all the necessary IR codes as switches with their own switch IDs. I would create an array of these IDs (if such a thing is possible in ESPhome), such that the array ID correlates to speed. So speedz[0] calls the fan_off switch, speedsz[4] calls the fan_speed4 switch.

Then I have a global int currentSpeed that represents the current speed. Clicking the up button will call currentSpeed++ (up to a max of 4), and then call whatever switch is at the speedz[currentSpeed] array index. Clicking the down button works the same, but in reverse.

The obvious problem is that I’m not sure that ESPhome supports an array of switch IDs. Does it?

If it doesn’t, then I think I’m stuck with doing a huge-ass lamba of if statements for both the up and down button.

Can you think of a better implementation of this idea?

Thank you.

What about a series of if then statements. In pseudo code

on press up button
  if fanstate = 0 then set fanstate to 1, else
  if fanstate = 1 then set fanstate to 2, else
  if fanstate = 2 then set fanstate to 3, else.... etc
1 Like

Thanks @nickrout. That’s pretty much what I’m working on now, I just hoped that there was a more elegant approach, because I like tiny code :smile:

esphome reproduces a lot of home assistant concepts, and when I have seen similar problems handled in automations they do it in a similar way as I have suggested. It is only 5 states, reproduced for up and down. Pretty simple really. If there 100 states I would look for another solution.

In the end, here is what I came up with. I’m just posting the relevant switches because the IR codes are crazy long, so, assume that I’ve already defined switches called fan_0, fan_1 etc etc, and a global variable called fanspeed.

So I have a single unnamed button with an id of set_fan_speed that uses five if statements to set the fan speed based on the current value of a global variable. Then I have named buttons for Up and Down that use a lambda to set the global variable and then call the set_fan_speed button. I’m using switches like methods now.

Can you see any way I could make this smaller/cleaner?

  - platform: template
    name: "Fanspeed Up"
    id: speed_up
    turn_on_action:
      then:
        - lambda: |-
            id(fanspeed) ++;
            if(id(fanspeed) > 4){
              id(fanspeed) = 4;
            }
        - switch.turn_on: set_fan_speed
  - platform: template
    name: "Fanspeed Down"
    id: speed_dn
    turn_on_action:
      then:
        - lambda: |-
            id(fanspeed) --;
            if(id(fanspeed) < 0){
              id(fanspeed) = 0;
            }
        - switch.turn_on: set_fan_speed
  - platform: template
    id: set_fan_speed
    turn_on_action:
      then:
        - if:
            condition:
              lambda: |-
                if (id(fanspeed)==0) {
                  return true;
                } else {
                  return false;
                }
            then:
              - switch.turn_on: fan_0
        - if:
            condition:
              lambda: |-
                if (id(fanspeed)==1) {
                  return true;
                } else {
                  return false;
                }
            then:
              - switch.turn_on: fan_1
        - if:
            condition:
              lambda: |-
                if (id(fanspeed)==2) {
                  return true;
                } else {
                  return false;
                }
            then:
              - switch.turn_on: fan_2
        - if:
            condition:
              lambda: |-
                if (id(fanspeed)==3) {
                  return true;
                } else {
                  return false;
                }
            then:
              - switch.turn_on: fan_3
        - if:
            condition:
              lambda: |-
                if (id(fanspeed)==4) {
                  return true;
                } else {
                  return false;
                }
            then:
              - switch.turn_on: fan_4
2 Likes

You are well ahead of me in programming!.

I say, if it is working, go for it. And if it is working, don’t fix it!