Skip to content

If recipe includes sensor and sketch adds one or more the generated code will include two sensor sections and thus not compile - pre_0.9b296 #218

Description

@karl-petter

I have just finished another hardware receipt, this time for the Cheap Yellow Display

While doing that I discovered a small bug. This display has a LDR sensor on the front to measure incoming light and thus be able to adjust backlighting. I added that as a sensor in the hardware receipt

I used this receipt and created a sketch presenting a text sensor as well as the wifi sensor. If I do that the generated code will include include two sensor: sections. See this example:

# ============================================================================
# ESPHome YAML - Generated by ESPHome Designer
# ============================================================================
# TARGET DEVICE: Guition ESP32-2.8-inch resistor touch
#         - https://randomnerdtutorials.com/esp32-cheap-yellow-display-cyd-pinout-esp32-2432s028r/
#         - ESP32: Sparkleiot XH-32S
#         - Display Platform: 2.8-inch color TFT display screen with ILI9341 driver chip
#         - PSRAM: None
#         - Touchscreen: XPT2046
#         - Framework: ESP-IDF
# Name: Guition ESP32-2.8-inch resistor touch 240x320
# Resolution: 240x320
# Shape: rectangle
# ============================================================================
#
# SETUP INSTRUCTIONS:
#
# STEP 1: Copy the Material Design Icons font file
#         - From this repo: resources/fonts/materialdesignicons-webfont.ttf
#         - To ESPHome: /config/esphome/fonts/materialdesignicons-webfont.ttf
#         (Create the fonts folder if it doesn't exist)
#
# STEP 2: Create a new device in ESPHome
#         - Click "New Device"
#         - Name: your-device-name
#         - Select: ESP32
#         - Framework: ESP-IDF (Required for this device)
#
# STEP 3: REPLACE your entire YAML with this generated output
#         (This profile includes full esphome: and esp32: sections)
#
# ============================================================================

# substitutions: # (Auto-commented)
#   name: "guiton_esp32_2432s028r"
#   friendly_name: 'Guition ESP32-2.8-inch" 2432S028 R'
#   device_description: "Guition ESP32-2.8-inch resistor touch 240x320"
#   project_name: "ESPHomeDesigner_Waveshare_Touch_Round_LCD_1.28"
#   project_version: "1.0.0"
#   #GPIO pins for the LCD screen
#   misopin: GPIO12
#   mosipin: GPIO13
#   sclkpin: GPIO14
#   cspin: GPIO15
#   dcpin: GPIO2
#   blpin: GPIO21
#   # GPIO pins for Touchpanel
#   tp_irqpin: GPIO36
#   tp_mosipin: GPIO32
#   tp_misopin: GPIO39
#   tp_clkpin: GPIO25
#   tp_cspin: GPIO33
#   # GPIO pins for RGB LED
#   led_rpin: GPIO4
#   led_gpin: GPIO16
#   led_bpin: GPIO17
#   # GPIO LDR
#   ldr_pin: GPIO34
#   # GPIO pins for i2c
#   sdapin: GPIO27
#   sclpin: GPIO22
#   # SD Card
#   sd_cs_pin: GPIO4

# esphome: # (Auto-commented)
#   friendly_name: $friendly_name
#   name: $name
#   project:
#     name: "${project_name}"
#     version: "${project_version}"

# esp32: # (Auto-commented)
#   board: esp32dev
#   framework:
#     type: esp-idf

spi:
  - id: tft
    clk_pin: $sclkpin
    mosi_pin: $mosipin
    miso_pin:
      number: $misopin
      ignore_strapping_warning: true
  - id: touch
    clk_pin: $tp_clkpin
    mosi_pin: $tp_mosipin
    miso_pin: $tp_misopin

i2c:
  sda: $sdapin
  scl: $sclpin

output:
  - platform: ledc
    pin: $blpin
    frequency: 1000hz
    id: gpio_backlight_pwm
  - id: output_red
    platform: ledc
    pin: $led_rpin
    inverted: true
  - id: output_green
    platform: ledc
    pin: $led_gpin
    inverted: true
  - id: output_blue
    platform: ledc
    pin: $led_bpin
    inverted: true

light:
  - platform: monochromatic # Define a monochromatic, dimmable light for the backlight
    output: gpio_backlight_pwm
    name: Display Backlight
    icon: mdi:lightbulb-on
    id: display_backlight
    restore_mode: ALWAYS_ON
  - platform: rgb # RGB Led on backside
    id: rgb_led
    name: RGB LED
    red: output_red
    green: output_green
    blue: output_blue
    restore_mode: ALWAYS_OFF

sensor:
  # Board LDR
  - platform: adc
    pin: $ldr_pin
    name: "board_ldr"
    update_interval: 1500ms

touchscreen:
  - id: my_touchscreen
    platform: xpt2046
    spi_id: touch
    cs_pin: $tp_cspin
    interrupt_pin: $tp_irqpin
    threshold: 400
    calibration:
      x_min: 280
      x_max: 3860
      y_min: 340
      y_max: 3860
    transform:
      mirror_x: true
    on_touch:
      - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
            touch.x,
            touch.y,
            touch.x_raw,
            touch.y_raw
          );

display:
  - id: my_display
    platform: ili9xxx
    model: ILI9342
    spi_id: tft
    cs_pin:
      number: $cspin
      ignore_strapping_warning: true
    dc_pin:
      number: $dcpin
      ignore_strapping_warning: true
    invert_colors: false
    update_interval: never
    auto_clear_enabled: false
    color_order: RGB
    dimensions:
      width: 240
      height: 320
    lambda: |-
      const auto COLOR_WHITE = Color(255, 255, 255);
      const auto COLOR_BLACK = Color(0, 0, 0);
      const auto COLOR_RED = Color(255, 0, 0);
      const auto COLOR_GREEN = Color(0, 255, 0);
      const auto COLOR_BLUE = Color(0, 0, 255);
      const auto COLOR_YELLOW = Color(255, 255, 0);
      const auto COLOR_ORANGE = Color(255, 165, 0);
      auto color_off = COLOR_WHITE;
      auto color_on = COLOR_BLACK;
      
      // Helper to apply a simple grey dither mask for e-paper (checkerboard)
      auto apply_grey_dither_mask = [&](int x_start, int y_start, int w, int h, int r = 0) {
        for (int y = y_start; y < y_start + h; y++) {
          for (int x = x_start; x < x_start + w; x++) {
            if (r > 0) {
              int dx = 0, dy = 0;
              if (x < x_start + r && y < y_start + r) { dx = x_start + r - x; dy = y_start + r - y; }
              else if (x >= x_start + w - r && y < y_start + r) { dx = x - (x_start + w - r - 1); dy = y_start + r - y; }
              else if (x < x_start + r && y >= y_start + h - r) { dx = x_start + r - x; dy = y - (y_start + h - r - 1); }
              else if (x >= x_start + w - r && y >= y_start + h - r) { dx = x - (x_start + w - r - 1); dy = y - (y_start + h - r - 1); }
              if (dx*dx + dy*dy > r*r) continue;
            }
            if ((x + y) % 2 == 0) it.draw_pixel_at(x, y, COLOR_WHITE);
            else it.draw_pixel_at(x, y, COLOR_BLACK);
          }
        }
      };
      
      // Helper to apply grey dither to text (subtractive - erases every other black pixel)
      auto apply_grey_dither_to_text = [&](int x_start, int y_start, int w, int h) {
        for (int y = y_start; y < y_start + h; y++) {
          for (int x = x_start; x < x_start + w; x++) {
            if ((x + y) % 2 == 0) it.draw_pixel_at(x, y, COLOR_WHITE);
          }
        }
      };
      int currentPage = id(display_page);
      if (currentPage == 0) {
        // page:name "Page 1"
        // page:dark_mode "inherit"
        // page:refresh_type "interval"
        // page:refresh_time ""
        // Clear screen for this page
        it.fill(COLOR_WHITE);
        color_off = COLOR_WHITE;
        color_on = COLOR_BLACK;
        // widget:text id:w_mkzz2oupe6tj1 type:text x:60 y:74 w:120 h:40 text:"Welcome!" 
        it.printf(120, 94, id(font_roboto_400_20), COLOR_BLACK, TextAlign::CENTER, "Welcome!");
        // widget:icon id:w_mkzz2sr1a20u2 type:icon x:71 y:114 w:98 h:93 code:F07D0 size:85 color:#00BCF7 
        it.printf(71, 114, id(font_material_design_icons_400_85), Color(0, 188, 247), "%s", "\U000F07D0");
        // widget:wifi_signal id:w_mkzz3ql00s8t3 type:wifi_signal x:60 y:11 w:120 h:40 entity:wifi_signal_dbm size:24 font_size:12 color:#00B700 show_dbm:true local:true 
        {
          const char* wifi_icon = "\U000F092B"; // Default: wifi-strength-alert-outline
          if (id(wifi_signal_dbm).has_state()) {
            float signal = id(wifi_signal_dbm).state;
            if (std::isnan(signal)) signal = -100;
            if (signal >= -50) wifi_icon = "\U000F0928";      // wifi-strength-4 (Excellent)
            else if (signal >= -60) wifi_icon = "\U000F0925"; // wifi-strength-3 (Good)
            else if (signal >= -75) wifi_icon = "\U000F0922"; // wifi-strength-2 (Fair)
            else if (signal >= -100) wifi_icon = "\U000F091F"; // wifi-strength-1 (Weak)
            else wifi_icon = "\U000F092B";                    // wifi-strength-alert-outline
          }
          it.printf(60 + 120 / 2, 11 + (40 - 38) / 2, id(font_material_design_icons_400_24), Color(0, 183, 0), TextAlign::TOP_CENTER, "%s", wifi_icon);
          if (id(wifi_signal_dbm).has_state()) {
            it.printf(60 + 120 / 2, 11 + (40 - 38) / 2 + 24 + 2, id(font_roboto_400_12), Color(0, 183, 0), TextAlign::TOP_CENTER, "%.0fdB", id(wifi_signal_dbm).state);
          }
        }
        // widget:sensor_text id:w_mkzz3yp9i02sx type:sensor_text x:60 y:237 w:120 h:40 entity:"sensor.medeltemperatur_pa_oppna_delar_av_entreplan" format:"label_newline_value" 
        it.printf(120, 237, id(font_roboto_400_14), COLOR_BLACK, TextAlign::TOP_CENTER, "Temperatur");
        it.printf(120, 237 + 18, id(font_roboto_400_20), COLOR_BLACK, TextAlign::TOP_CENTER, "%.1f °C", id(sensor_medeltemperatur_pa_oppna_delar_av_entreplan).state);
      }


globals:
  - id: display_page
    type: int
    restore_value: true
    initial_value: '0'
  - id: page_refresh_default_s
    type: int
    restore_value: true
    initial_value: '600'
  - id: page_refresh_current_s
    type: int
    restore_value: false
    initial_value: '60'
  - id: last_page_switch_time
    type: uint32_t
    restore_value: false
    initial_value: '0'
psram:

time:
  - platform: homeassistant
    id: ha_time
sensor:
  - platform: homeassistant
    id: sensor_medeltemperatur_pa_oppna_delar_av_entreplan
    entity_id: sensor.medeltemperatur_pa_oppna_delar_av_entreplan
    internal: true
  - platform: wifi_signal
    name: "WiFi Signal"
    id: wifi_signal_dbm
    update_interval: 60s
font:
  - file:
      type: gfonts
      family: "Roboto"
      weight: 400
      italic: false
    id: font_roboto_400_12
    size: 12
    glyphs: ["\U00000020", "\U00000021", "\U00000022", "\U00000023", "\U00000024", "\U00000025", "\U00000026", "\U00000027", "\U00000028", "\U00000029", "\U0000002A", "\U0000002B", "\U0000002C", "\U0000002D", "\U0000002E", "\U0000002F", "\U00000030", "\U00000031", "\U00000032", "\U00000033", "\U00000034", "\U00000035", "\U00000036", "\U00000037", "\U00000038", "\U00000039", "\U0000003A", "\U0000003B", "\U0000003C", "\U0000003D", "\U0000003E", "\U0000003F", "\U00000040", "\U00000041", "\U00000042", "\U00000043", "\U00000044", "\U00000045", "\U00000046", "\U00000047", "\U00000048", "\U00000049", "\U0000004A", "\U0000004B", "\U0000004C", "\U0000004D", "\U0000004E", "\U0000004F", "\U00000050", "\U00000051", "\U00000052", "\U00000053", "\U00000054", "\U00000055", "\U00000056", "\U00000057", "\U00000058", "\U00000059", "\U0000005A", "\U0000005B", "\U0000005C", "\U0000005D", "\U0000005E", "\U0000005F", "\U00000060", "\U00000061", "\U00000062", "\U00000063", "\U00000064", "\U00000065", "\U00000066", "\U00000067", "\U00000068", "\U00000069", "\U0000006A", "\U0000006B", "\U0000006C", "\U0000006D", "\U0000006E", "\U0000006F", "\U00000070", "\U00000071", "\U00000072", "\U00000073", "\U00000074", "\U00000075", "\U00000076", "\U00000077", "\U00000078", "\U00000079", "\U0000007A", "\U0000007B", "\U0000007C", "\U0000007D", "\U0000007E", "\U000000A0", "\U000000A1", "\U000000A2", "\U000000A3", "\U000000A4", "\U000000A5", "\U000000A6", "\U000000A7", "\U000000A8", "\U000000A9", "\U000000AA", "\U000000AB", "\U000000AC", "\U000000AD", "\U000000AE", "\U000000AF", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B4", "\U000000B5", "\U000000B6", "\U000000B7", "\U000000B8", "\U000000B9", "\U000000BA", "\U000000BB", "\U000000BC", "\U000000BD", "\U000000BE", "\U000000BF", "\U000000C0", "\U000000C1", "\U000000C2", "\U000000C3", "\U000000C4", "\U000000C5", "\U000000C6", "\U000000C7", "\U000000C8", "\U000000C9", "\U000000CA", "\U000000CB", "\U000000CC", "\U000000CD", "\U000000CE", "\U000000CF", "\U000000D0", "\U000000D1", "\U000000D2", "\U000000D3", "\U000000D4", "\U000000D5", "\U000000D6", "\U000000D7", "\U000000D8", "\U000000D9", "\U000000DA", "\U000000DB", "\U000000DC", "\U000000DD", "\U000000DE", "\U000000DF", "\U000000E0", "\U000000E1", "\U000000E2", "\U000000E3", "\U000000E4", "\U000000E5", "\U000000E6", "\U000000E7", "\U000000E8", "\U000000E9", "\U000000EA", "\U000000EB", "\U000000EC", "\U000000ED", "\U000000EE", "\U000000EF", "\U000000F0", "\U000000F1", "\U000000F2", "\U000000F3", "\U000000F4", "\U000000F5", "\U000000F6", "\U000000F7", "\U000000F8", "\U000000F9", "\U000000FA", "\U000000FB", "\U000000FC", "\U000000FD", "\U000000FE", "\U000000FF", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: "Roboto"
      weight: 400
      italic: false
    id: font_roboto_400_14
    size: 14
    glyphs: ["\U00000020", "\U00000021", "\U00000022", "\U00000023", "\U00000024", "\U00000025", "\U00000026", "\U00000027", "\U00000028", "\U00000029", "\U0000002A", "\U0000002B", "\U0000002C", "\U0000002D", "\U0000002E", "\U0000002F", "\U00000030", "\U00000031", "\U00000032", "\U00000033", "\U00000034", "\U00000035", "\U00000036", "\U00000037", "\U00000038", "\U00000039", "\U0000003A", "\U0000003B", "\U0000003C", "\U0000003D", "\U0000003E", "\U0000003F", "\U00000040", "\U00000041", "\U00000042", "\U00000043", "\U00000044", "\U00000045", "\U00000046", "\U00000047", "\U00000048", "\U00000049", "\U0000004A", "\U0000004B", "\U0000004C", "\U0000004D", "\U0000004E", "\U0000004F", "\U00000050", "\U00000051", "\U00000052", "\U00000053", "\U00000054", "\U00000055", "\U00000056", "\U00000057", "\U00000058", "\U00000059", "\U0000005A", "\U0000005B", "\U0000005C", "\U0000005D", "\U0000005E", "\U0000005F", "\U00000060", "\U00000061", "\U00000062", "\U00000063", "\U00000064", "\U00000065", "\U00000066", "\U00000067", "\U00000068", "\U00000069", "\U0000006A", "\U0000006B", "\U0000006C", "\U0000006D", "\U0000006E", "\U0000006F", "\U00000070", "\U00000071", "\U00000072", "\U00000073", "\U00000074", "\U00000075", "\U00000076", "\U00000077", "\U00000078", "\U00000079", "\U0000007A", "\U0000007B", "\U0000007C", "\U0000007D", "\U0000007E", "\U000000A0", "\U000000A1", "\U000000A2", "\U000000A3", "\U000000A4", "\U000000A5", "\U000000A6", "\U000000A7", "\U000000A8", "\U000000A9", "\U000000AA", "\U000000AB", "\U000000AC", "\U000000AD", "\U000000AE", "\U000000AF", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B4", "\U000000B5", "\U000000B6", "\U000000B7", "\U000000B8", "\U000000B9", "\U000000BA", "\U000000BB", "\U000000BC", "\U000000BD", "\U000000BE", "\U000000BF", "\U000000C0", "\U000000C1", "\U000000C2", "\U000000C3", "\U000000C4", "\U000000C5", "\U000000C6", "\U000000C7", "\U000000C8", "\U000000C9", "\U000000CA", "\U000000CB", "\U000000CC", "\U000000CD", "\U000000CE", "\U000000CF", "\U000000D0", "\U000000D1", "\U000000D2", "\U000000D3", "\U000000D4", "\U000000D5", "\U000000D6", "\U000000D7", "\U000000D8", "\U000000D9", "\U000000DA", "\U000000DB", "\U000000DC", "\U000000DD", "\U000000DE", "\U000000DF", "\U000000E0", "\U000000E1", "\U000000E2", "\U000000E3", "\U000000E4", "\U000000E5", "\U000000E6", "\U000000E7", "\U000000E8", "\U000000E9", "\U000000EA", "\U000000EB", "\U000000EC", "\U000000ED", "\U000000EE", "\U000000EF", "\U000000F0", "\U000000F1", "\U000000F2", "\U000000F3", "\U000000F4", "\U000000F5", "\U000000F6", "\U000000F7", "\U000000F8", "\U000000F9", "\U000000FA", "\U000000FB", "\U000000FC", "\U000000FD", "\U000000FE", "\U000000FF", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: "Roboto"
      weight: 400
      italic: false
    id: font_roboto_400_20
    size: 20
    glyphs: ["\U00000020", "\U00000021", "\U00000022", "\U00000023", "\U00000024", "\U00000025", "\U00000026", "\U00000027", "\U00000028", "\U00000029", "\U0000002A", "\U0000002B", "\U0000002C", "\U0000002D", "\U0000002E", "\U0000002F", "\U00000030", "\U00000031", "\U00000032", "\U00000033", "\U00000034", "\U00000035", "\U00000036", "\U00000037", "\U00000038", "\U00000039", "\U0000003A", "\U0000003B", "\U0000003C", "\U0000003D", "\U0000003E", "\U0000003F", "\U00000040", "\U00000041", "\U00000042", "\U00000043", "\U00000044", "\U00000045", "\U00000046", "\U00000047", "\U00000048", "\U00000049", "\U0000004A", "\U0000004B", "\U0000004C", "\U0000004D", "\U0000004E", "\U0000004F", "\U00000050", "\U00000051", "\U00000052", "\U00000053", "\U00000054", "\U00000055", "\U00000056", "\U00000057", "\U00000058", "\U00000059", "\U0000005A", "\U0000005B", "\U0000005C", "\U0000005D", "\U0000005E", "\U0000005F", "\U00000060", "\U00000061", "\U00000062", "\U00000063", "\U00000064", "\U00000065", "\U00000066", "\U00000067", "\U00000068", "\U00000069", "\U0000006A", "\U0000006B", "\U0000006C", "\U0000006D", "\U0000006E", "\U0000006F", "\U00000070", "\U00000071", "\U00000072", "\U00000073", "\U00000074", "\U00000075", "\U00000076", "\U00000077", "\U00000078", "\U00000079", "\U0000007A", "\U0000007B", "\U0000007C", "\U0000007D", "\U0000007E", "\U000000A0", "\U000000A1", "\U000000A2", "\U000000A3", "\U000000A4", "\U000000A5", "\U000000A6", "\U000000A7", "\U000000A8", "\U000000A9", "\U000000AA", "\U000000AB", "\U000000AC", "\U000000AD", "\U000000AE", "\U000000AF", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B4", "\U000000B5", "\U000000B6", "\U000000B7", "\U000000B8", "\U000000B9", "\U000000BA", "\U000000BB", "\U000000BC", "\U000000BD", "\U000000BE", "\U000000BF", "\U000000C0", "\U000000C1", "\U000000C2", "\U000000C3", "\U000000C4", "\U000000C5", "\U000000C6", "\U000000C7", "\U000000C8", "\U000000C9", "\U000000CA", "\U000000CB", "\U000000CC", "\U000000CD", "\U000000CE", "\U000000CF", "\U000000D0", "\U000000D1", "\U000000D2", "\U000000D3", "\U000000D4", "\U000000D5", "\U000000D6", "\U000000D7", "\U000000D8", "\U000000D9", "\U000000DA", "\U000000DB", "\U000000DC", "\U000000DD", "\U000000DE", "\U000000DF", "\U000000E0", "\U000000E1", "\U000000E2", "\U000000E3", "\U000000E4", "\U000000E5", "\U000000E6", "\U000000E7", "\U000000E8", "\U000000E9", "\U000000EA", "\U000000EB", "\U000000EC", "\U000000ED", "\U000000EE", "\U000000EF", "\U000000F0", "\U000000F1", "\U000000F2", "\U000000F3", "\U000000F4", "\U000000F5", "\U000000F6", "\U000000F7", "\U000000F8", "\U000000F9", "\U000000FA", "\U000000FB", "\U000000FC", "\U000000FD", "\U000000FE", "\U000000FF", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: font_material_design_icons_400_85
    size: 85
    glyphs: ["\U000F07D0"]
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: font_material_design_icons_400_24
    size: 24
    glyphs: ["\U000F091F", "\U000F0922", "\U000F0925", "\U000F0928", "\U000F092B"]
script:
  - id: change_page_to
    parameters:
      target_page: int
    then:
      - lambda: |-
          int pages_count = 1;
          int target = target_page;
          while (target < 0) target += pages_count;
          target %= pages_count;

          // Debounce: Ignore page changes within 500ms of last change
          // (adjusted for LCD display update time)
          uint32_t now = millis();
          if (now - id(last_page_switch_time) < 500) {
            ESP_LOGD("display", "Page change ignored (debounce), last switch was %d ms ago", now - id(last_page_switch_time));
            return;
          }

          if (id(display_page) != target) {
            // Set debounce time BEFORE display update (update takes ~1.6s)
            id(last_page_switch_time) = now;
            id(display_page) = target;
            id(my_display).update();
            ESP_LOGI("display", "Switched to page %d", target);
            // Restart refresh logic
            if (id(manage_run_and_sleep).is_running()) id(manage_run_and_sleep).stop();
            id(manage_run_and_sleep).execute();
          }
  - id: manage_run_and_sleep
    mode: restart
    then:
      - logger.log: "Waiting for sync..."
      - wait_until:
          condition:
            lambda: 'return id(ha_time).now().is_valid() && api_is_connected();'
          timeout: 60s
      - delay: 5s
      - lambda: 'id(page_refresh_current_s) = id(page_refresh_default_s);'
      - component.update: my_display
      - delay: !lambda 'return id(page_refresh_current_s) * 1000;'
      - script.execute: manage_run_and_sleep

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions