Compilation fails unless code is correct!

Hi

I try to build a sketch to do a clock with LED rings. Here is code below that I used and after the error while compiling. Any ideas what’s wrong there ? If code is validated it should compile no ? Just for infos I have already compiled few esp sketches before so I know my ESPHome setup is good (running 1.14.3).

Thanks for your ideas

Vincèn

Sketch for ESPHome:

esphome:
  name: rgb_ring
  platform: ESP8266
  board: d1_mini
  on_boot:
    priority: -10
    then:
      # enable clock effect after boot
      - light.turn_on: 
          id: light_ring
          brightness: 50%
          effect: Clock

wifi:
  ssid: "Mywifi"
  password: "Mypasswd"

web_server:

# Enable Home Assistant API
api:

ota:

globals:
  - id: clock_brightness
    type: int
    restore_value: yes
    initial_value: '255'
  - id: clock_indicators_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'
  - id: clock_seconds_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'

time:
  - platform: homeassistant
    id: sntp_time

switch:
  - platform: template
    name: "Clock Indicators"
    icon: mdi:progress-clock
    lambda: !lambda |-
      return id(clock_indicators_enabled);
    turn_on_action:
      globals.set:
        id: clock_indicators_enabled
        value: 'true'
    turn_off_action: 
      globals.set:
        id: clock_indicators_enabled
        value: 'false'
  - platform: template
    name: "Clock Seconds"
    icon: mdi:update
    lambda: !lambda |-
      return id(clock_seconds_enabled);
    turn_on_action:
      globals.set:
        id: clock_seconds_enabled
        value: 'true'
    turn_off_action: 
      globals.set:
        id: clock_seconds_enabled
        value: 'false'

light:
  - id: light_ring
    internal: False
    platform: fastled_clockless
    rgb_order: GRB
    chipset: WS2811
    pin: D5
    num_leds: '24'
    name: "LED Ring"
    color_correct: [90%, 90%, 90%]
    effects:
      - lambda:
          name: "Clock"
          update_interval: 32ms
          lambda: |-

            static boolean initialized;
            static ESPColor clock_ring_colors [60];
            if (initialized == false) {
              std::fill_n(clock_ring_colors, it.size(), ESPColor::BLACK);
              initialized = true;
            }
            auto time = id(sntp_time).now();
            if (!time.is_valid()) {
              return;
            }
            // calculate led indices
            int second_idx = (int) (time.second * (it.size() / 60));
            int minute_idx = (int) (time.minute * (it.size() / 60));
            int hour_idx = (int) ((time.hour % 12) * (it.size() / 12));
            int hour_inc_min_idx = hour_idx + (int) (((float) time.minute / 12) * (it.size() / 60));
            // fade out old colors
            for (int i = 0; i < it.size(); i++) {
              ESPColor old_color = clock_ring_colors[i];
              // fade out color
              int amount = 5;
              int red = old_color.red;
              int green = old_color.green;
              int blue = old_color.blue;
              int white = old_color.white;
              if (red < amount) { red = 0; } else { red -= amount; }
              if (green < amount) { green = 0; } else { green -= amount; }
              if (blue < amount) { blue = 0; } else { blue -= amount; }
              ESPColor new_color = ESPColor(red, green, blue, 0);
              clock_ring_colors[i] = new_color;
            }
            int indicator_brightness = id(clock_brightness) / 3;
            ESPColor indicator_color = ESPColor(indicator_brightness, indicator_brightness, indicator_brightness);
            // calculate colors
            ESPColor second_color = ESPColor(id(clock_brightness), 0, 0);
            ESPColor minute_color = ESPColor(0, id(clock_brightness), 0);
            if (minute_idx == second_idx) {
              minute_color += second_color;
            }

            ESPColor hour_color = ESPColor(0, 0, id(clock_brightness));
            if (hour_inc_min_idx == minute_idx) {
              // if seconds are also the same this will already contain the second color
              hour_color += minute_color;
            } else if (hour_inc_min_idx == second_idx) {
              hour_color += second_color;
            }
            if (id(clock_indicators_enabled)) {
              for (int i = 0; i < it.size(); i += (int) ((float) it.size() / 12)) {
                clock_ring_colors[i] = indicator_color;
              }
            }
            // set colors
            if (id(clock_seconds_enabled)) {
              clock_ring_colors[second_idx] = second_color;
            }
            clock_ring_colors[minute_idx] = minute_color;
            clock_ring_colors[hour_inc_min_idx] = hour_color;
            // apply colors to light
            for (int i = 0; i < it.size(); i++) {
              it[i] = clock_ring_colors[i];
            }
      - addressable_rainbow:
          name: "Rainbow Spinner"
          speed: 8
          width: 24
      - addressable_rainbow:
          name: "Rainbow Fader"
          speed: 3
          width: 24
      - random:
          name: "Random Slow"
          transition_length: 30s
          update_interval: 30s

Compilation log:

INFO Reading configuration /config/esphome/rgb_ring.yaml...
INFO Detected timezone 'CET' with UTC offset 1 and daylight savings time from 28 March 02:00:00 to 31 October 03:00:00
INFO Generating C++ source...
INFO Compiling app...
INFO Running:  platformio run -d /config/esphome/rgb_ring
Processing rgb_ring (board: d1_mini; framework: arduino; platform: [email protected])
--------------------------------------------------------------------------------
HARDWARE: ESP8266 80MHz, 80KB RAM, 4MB Flash
Dependency Graph
|-- <ESPAsyncTCP-esphome> 1.2.2
|   |-- <ESP8266WiFi> 1.0
|-- <ESPAsyncWebServer-esphome> 1.2.6
|   |-- <ESPAsyncTCP-esphome> 1.2.2
|   |   |-- <ESP8266WiFi> 1.0
|   |-- <Hash> 1.0
|   |-- <ESP8266WiFi> 1.0
|   |-- <ArduinoJson-esphomelib> 5.13.3
|-- <ESP8266WiFi> 1.0
|-- <ArduinoJson-esphomelib> 5.13.3
|-- <ESP8266mDNS> 1.2
|   |-- <ESP8266WiFi> 1.0
|-- <FastLED> 3.2.9
|   |-- <EspSoftwareSerial> 5.0.4
Compiling /data/rgb_ring/.pioenvs/rgb_ring/src/main.cpp.o
src/main.cpp: In lambda function:
src/main.cpp:358:40: error: 'it' was not declared in this scope
         std::fill_n(clock_ring_colors, it.size(), ESPColor::BLACK);
                                        ^
src/main.cpp:366:46: error: 'it' was not declared in this scope
       int second_idx = (int) (time.second * (it.size() / 60));
                                              ^
*** [/data/rgb_ring/.pioenvs/rgb_ring/src/main.cpp.o] Error 1
========================== [FAILED] Took 4.13 seconds ==========================

Not necessarily, if you have lambdas:

Screenshot_2020-04-28 Automations and Templates

1 Like

Still killing my head trying to get that code running ! I took it from a github repo where owner states code compiles in his ESPHome but it’s not on mine and I don’t understand why :frowning:
Here’s code:

esphome:
  name: rgb_ring
  platform: ESP8266
  board: d1_mini
  on_boot:
    priority: -10
    then:
      - light.turn_on: 
          id: light_ring
          brightness: 50%
          effect: Clock

wifi:
  ssid: "XXXXX"
  password: "YYYYY"

web_server:

api:

ota:

globals:
  - id: clock_brightness
    type: int
    restore_value: yes
    initial_value: '255'
  - id: clock_indicators_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'
  - id: clock_seconds_enabled
    type: bool
    restore_value: yes
    initial_value: 'true'

time:
  - platform: homeassistant
    id: sntp_time

switch:
  - platform: template
    name: "Clock Indicators"
    icon: mdi:progress-clock
    lambda: !lambda |-
      return id(clock_indicators_enabled);
    turn_on_action:
      globals.set:
        id: clock_indicators_enabled
        value: 'true'
    turn_off_action: 
      globals.set:
        id: clock_indicators_enabled
        value: 'false'
  - platform: template
    name: "Clock Seconds"
    icon: mdi:update
    lambda: !lambda |-
      return id(clock_seconds_enabled);
    turn_on_action:
      globals.set:
        id: clock_seconds_enabled
        value: 'true'
    turn_off_action: 
      globals.set:
        id: clock_seconds_enabled
        value: 'false'

light:
  - id: light_ring
    internal: False
    platform: fastled_clockless
    rgb_order: GRB
    chipset: WS2811
    pin: D5
    num_leds: "60"
    name: "LED Ring"
    color_correct: [90%, 90%, 90%]
    effects:
      - lambda:
          name: "Clock"
          update_interval: 32ms
          lambda: |-
            static boolean initialized;
            static ESPColor clock_ring_colors [60];
            if (initialized == false) {
              std::fill_n(clock_ring_colors, it.size(), ESPColor::BLACK);
              initialized = true;
            }
            auto time = id(sntp_time).now();
            if (!time.is_valid()) {
              return;
            }
            // calculate led indices
            int second_idx = (int) (time.second * (it.size() / 60));
            int minute_idx = (int) (time.minute * (it.size() / 60));
            int hour_idx = (int) ((time.hour % 12) * (it.size() / 12));
            int hour_inc_min_idx = hour_idx + (int) (((float) time.minute / 12) * (it.size() / 60));
            // fade out old colors
            for (int i = 0; i < it.size(); i++) {
              ESPColor old_color = clock_ring_colors[i];
              // fade out color
              int amount = 5;
              int red = old_color.red;
              int green = old_color.green;
              int blue = old_color.blue;
              int white = old_color.white;
              if (red < amount) { red = 0; } else { red -= amount; }
              if (green < amount) { green = 0; } else { green -= amount; }
              if (blue < amount) { blue = 0; } else { blue -= amount; }
              ESPColor new_color = ESPColor(red, green, blue, 0);
              clock_ring_colors[i] = new_color;
            }
            int indicator_brightness = id(clock_brightness) / 3;
            ESPColor indicator_color = ESPColor(indicator_brightness, indicator_brightness, indicator_brightness);
            // calculate colors
            ESPColor second_color = ESPColor(id(clock_brightness), 0, 0);
            ESPColor minute_color = ESPColor(0, id(clock_brightness), 0);
            if (minute_idx == second_idx) {
              minute_color += second_color;
            }
            ESPColor hour_color = ESPColor(0, 0, id(clock_brightness));
            if (hour_inc_min_idx == minute_idx) {
              // if seconds are also the same this will already contain the second color
              hour_color += minute_color;
            } else if (hour_inc_min_idx == second_idx) {
              hour_color += second_color;
            }
            if (id(clock_indicators_enabled)) {
              for (int i = 0; i < it.size(); i += (int) ((float) it.size() / 12)) {
                clock_ring_colors[i] = indicator_color;
              }
            }
            // set colors
            if (id(clock_seconds_enabled)) {
              clock_ring_colors[second_idx] = second_color;
            }
            clock_ring_colors[minute_idx] = minute_color;
            clock_ring_colors[hour_inc_min_idx] = hour_color;
            // apply colors to light
            for (int i = 0; i < it.size(); i++) {
              it[i] = clock_ring_colors[i];
            }
      - addressable_rainbow:
          name: "Rainbow Spinner"
          speed: 8
          width: 60
      - addressable_rainbow:
          name: "Rainbow Fader"
          speed: 3
          width: 60
      - random:
          name: "Random Slow"
          transition_length: 30s
          update_interval: 30s

Error generated when trying to compile:

Compiling /data/rgb_ring/.pioenvs/rgb_ring/src/main.cpp.o
src/main.cpp: In lambda function:
src/main.cpp:355:40: error: 'it' was not declared in this scope
         std::fill_n(clock_ring_colors, it.size(), ESPColor::BLACK);
                                        ^
src/main.cpp:363:46: error: 'it' was not declared in this scope
       int second_idx = (int) (time.second * (it.size() / 60));
                                              ^
*** [/data/rgb_ring/.pioenvs/rgb_ring/src/main.cpp.o] Error 1
========================== [FAILED] Took 3.46 seconds ==========================

Thanks for ideas, suggestions :wink:

Vincèn

Well the error says that you haven’t declared the variable ‘it’ from my guess. I’m only just about to start learning C++ so can’t really help any more than that

The error is suggesting that the object var ‘it’ does not exist for your light. I use same var for my oled display, you don’t need to declare, I assume the platform does that automatically. The var ‘it’ may be a default self reference, but only for if the platform code sets it.

Have a look at this for ‘Display’ which uses same var:

Yep thanks for help and figured out problem (code I was using was not correctly written unless indication of owner of code :frowning: so now my ring LED clock works fine :wink:

here this will help you to finger out the problem