Trying to setup a rotary encoder along with a WS2812 LED ring. The encoder both controls the volume on the device, and the LED creates a visual representation of the volume level (1-12). Which is to say, when the volume on the encoder is 6, 6 LEDs are turned on, etc. Similar functionality to what you see here Would like to keep the logic to the ESP32 board as HA automation would likely have latency, and I may build more devices like this in the future.
I’ve tried a few methods but nothing compiles except for this brute force method below; which does everything correctly at the log level, but does not actually seem to control the turning on and off of lights.
id(circular_led).addressable_set(i, Color(255,255,255)); → doesn’t exist.
id(circular_led).set_pixel(i, 255, 255, 255); → no such method.
id(circular_led).get()[i] = esphome::Color(255,255,255); → doesn’t exist
I have a feeling I’ve been fighting this too long and can’t see the forest through the trees. Any help is appreciated.
# -------------------- ROTARY ENCODER (VOLUME CONTROL) --------------------
sensor:
- platform: rotary_encoder
name: "Volume Level"
id: volume_level
pin_a: GPIO17
pin_b: GPIO16
min_value: 0
max_value: 12
resolution: 1
filters:
- debounce: 5ms
on_value:
then:
- lambda: |-
ESP_LOGD("encoder", "Volume Level Changed: %d", (int) id(volume_level).state);
int volume = (int) id(volume_level).state;
ESP_LOGD("encoder", "Turning on LEDs up to index: %d", volume);
id(led_1).turn_off();
id(led_2).turn_off();
id(led_3).turn_off();
id(led_4).turn_off();
id(led_5).turn_off();
id(led_6).turn_off();
id(led_7).turn_off();
id(led_8).turn_off();
id(led_9).turn_off();
id(led_10).turn_off();
id(led_11).turn_off();
id(led_12).turn_off();
for (int i = 0; i < volume; i++) {
ESP_LOGD("encoder", "Turning on LED %d", i);
switch (i) {
case 0: id(led_1).turn_on(); break;
case 1: id(led_2).turn_on(); break;
case 2: id(led_3).turn_on(); break;
case 3: id(led_4).turn_on(); break;
case 4: id(led_5).turn_on(); break;
case 5: id(led_6).turn_on(); break;
case 6: id(led_7).turn_on(); break;
case 7: id(led_8).turn_on(); break;
case 8: id(led_9).turn_on(); break;
case 9: id(led_10).turn_on(); break;
case 10: id(led_11).turn_on(); break;
case 11: id(led_12).turn_on(); break;
}
}
# -------------------- LED FEEDBACK (VOLUME INDICATOR) --------------------
light:
- platform: neopixelbus
type: GRB
variant: WS2812
pin: GPIO14
num_leds: 12
name: "Full LED Ring"
id: full_led_ring
internal: true # Hide the full ring from Home Assistant to prevent conflicts
# -------------------- PARTITIONED LIGHT CONTROL --------------------
- platform: partition
name: "LED 1"
id: led_1
segments:
- id: full_led_ring
from: 0
to: 0
- platform: partition
name: "LED 2"
id: led_2
segments:
- id: full_led_ring
from: 1
to: 1
- platform: partition
name: "LED 3"
id: led_3
segments:
- id: full_led_ring
from: 2
to: 2
- platform: partition
name: "LED 4"
id: led_4
segments:
- id: full_led_ring
from: 3
to: 3
- platform: partition
name: "LED 5"
id: led_5
segments:
- id: full_led_ring
from: 4
to: 4
- platform: partition
name: "LED 6"
id: led_6
segments:
- id: full_led_ring
from: 5
to: 5
- platform: partition
name: "LED 7"
id: led_7
segments:
- id: full_led_ring
from: 6
to: 6
- platform: partition
name: "LED 8"
id: led_8
segments:
- id: full_led_ring
from: 7
to: 7
- platform: partition
name: "LED 9"
id: led_9
segments:
- id: full_led_ring
from: 8
to: 8
- platform: partition
name: "LED 10"
id: led_10
segments:
- id: full_led_ring
from: 9
to: 9
- platform: partition
name: "LED 11"
id: led_11
segments:
- id: full_led_ring
from: 10
to: 10
- platform: partition
name: "LED 12"
id: led_12
segments:
- id: full_led_ring
from: 11
to: 11