Skip to content

Fix: Waveshare ESP32-S3 LCD7 Display Rotation#147

Open
bonaminGR wants to merge 1 commit intokoosoli:mainfrom
bonaminGR:fix-waveshare-esp32s3-lcd7
Open

Fix: Waveshare ESP32-S3 LCD7 Display Rotation#147
bonaminGR wants to merge 1 commit intokoosoli:mainfrom
bonaminGR:fix-waveshare-esp32s3-lcd7

Conversation

@bonaminGR
Copy link
Copy Markdown

Tested on a Waveshare ESP32-S3-Touch-LCD-7, and while it does generally work, the image is rotated.
Changing the rotation: 90 to 0 fixes the issue.

I am not exactly a programmer, and this is my first ever pull request, so if I did anything wrong, please feel free to ignore the issue. I just wanted to add my 2 cents on the project. ;)

@koosoli
Copy link
Copy Markdown
Owner

koosoli commented Jan 10, 2026

Hi, thanks for the commit, I will need to get the 0.9 pre released bug fixed first, but after that, I will take a close look at your commit.
Someone also gave me an example yaml that should work; maybe you could compare it with your commit?

# ============================================================================
# ESPHome YAML - Generated by ESPHome Designer
# ============================================================================
# TARGET DEVICE: Waveshare Touch LCD 7 7.0" 800x480
#         - Display Platform: mipi_rgb (RGB LCD)
#         - PSRAM: Yes (Octal, 80MHz)
#         - Touchscreen: GT911 (I2C via CH422G)
#         - Framework: ESP-IDF with execute_from_psram
# ============================================================================
#
# BASED ON: https://github.com/agillis/esphome-modular-lvgl-buttons
# Hardware configuration adapted for ESPHome Designer.
#
# ============================================================================
#
# 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-S3
#         - 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)
#
# ============================================================================

esphome:
  min_version: 2024.11.0
  project:
    name: "Waveshare.ESP32-S3-touch-lcd-7"
    version: "1.0"
  platformio_options:
    board_upload.maximum_ram_size: 524288

esp32:
  variant: esp32s3
  flash_size: 16MB
  framework:
    type: esp-idf
    advanced:
       execute_from_psram: true

psram:
  mode: octal
  speed: 80Mhz

preferences:
  flash_write_interval: 5min

ch422g:
  - id: ch422g_hub

switch:
  - platform: gpio
    id: lcdbacklight
    name: lcdbacklight
    pin:
      ch422g: ch422g_hub
      number: 2
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_ON

light:
  - platform: monochromatic
    name: "Display Backlight"
    output: fake_backlight_output
    id: display_backlight
    default_transition_length: 1s
    gamma_correct: 2.8

output:
  - platform: template
    id: fake_backlight_output
    type: float
    write_action:
      - lambda: |-
          ESP_LOGD("fake_light", "Fake brightness level: %.2f", state);

i2c:
  - id: bus_a
    sda: GPIO8
    scl: GPIO9
    scan: true

touchscreen:
  platform: gt911
  id: my_touchscreen
  i2c_id: bus_a
  interrupt_pin: GPIO4
  reset_pin:
    ch422g: ch422g_hub
    number: 1
    mode: OUTPUT

display:
  - platform: mipi_rgb
    model: ESP32-S3-TOUCH-LCD-7-800X480
    id: my_display
    rotation: 90
    update_interval: never
    auto_clear_enabled: false
    color_order: RGB
    pclk_frequency: 16MHZ
    dimensions:
      width: 800
      height: 480
    reset_pin:
      ch422g: ch422g_hub
      number: 3
    de_pin:
      number: GPIO5
    hsync_pin:
      number: GPIO46
      ignore_strapping_warning: true
    vsync_pin:
      number: GPIO3
      ignore_strapping_warning: true
    pclk_pin: GPIO7
    pclk_inverted: true
    hsync_back_porch: 8
    hsync_front_porch: 8
    hsync_pulse_width: 4
    vsync_back_porch: 8
    vsync_front_porch: 8
    vsync_pulse_width: 4
    data_pins:
      red: [1, 2, 42, 41, 40]
      blue: [14, 38, 18, 17, 10]
      green: [39, 0, 45, 48, 47, 21]
    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;

      auto apply_grey_dither_mask = [&](int x, int y, int w, int h) {
          // Dithering only for E-paper devices
          // LCDs use standard RGB/Gray rendering
          // No-op for LCD
      };

      auto extract_time = [](const char* iso_str) -> std::string {
          // Expected format: YYYY-MM-DDTHH:MM:SS or similar
          std::string s(iso_str);
          if (s.length() >= 16) return s.substr(11, 5);
          return "";
      };

      int currentPage = id(display_page);
      if (currentPage == 0) {
        // page:name "Page 1"
        // page:dark_mode "dark"
        // page:refresh_type "interval"
        // page:refresh_time ""
        // Clear screen for this page
        it.fill(COLOR_BLACK);
        color_off = COLOR_BLACK;
        color_on = COLOR_WHITE;
        // widget:datetime id:w_mjim13abl8mwl type:datetime x:12 y:16 w:200 h:60 format:time_only time_size:71 date_size:16 color:white text_align:CENTER italic:false font_family:"Roboto" 
        {
          auto now = id(ha_time).now();
          it.strftime(12 + 200/2, 16, id(font_roboto_700_71), COLOR_WHITE, TextAlign::TOP_CENTER, "%H:%M", now);
        }
        // widget:sensor_text id:w_mjim15kap7xju type:sensor_text x:88 y:221 w:138 h:59 ent:sensor.living_room_th_temp entity_2: title:"Living Room" format:value_only_no_unit label_font:14 value_font:40 color:white label_align:TOP_LEFT value_align:TOP_LEFT precision:1 unit:"" hide_unit:false prefix:"" postfix:"°C" separator:"~" local:false text_sensor:false font_family:"Roboto" font_weight:500 italic:false
        {
          char buf1[32];
          snprintf(buf1, sizeof(buf1), "%.1f", id(sensor_living_room_th_temp).state);
          std::string val1 = buf1;
          std::string sensorValue = val1;
          std::string fullValue = "" + sensorValue + "" + "°C";
          it.printf(88, 221, id(font_roboto_500_40), COLOR_WHITE, TextAlign::TOP_LEFT, "%s", fullValue.c_str());
        }
        // widget:weather_forecast id:w_mjimihcis712k type:weather_forecast x:0 y:141 w:400 h:80 weather_entity:"weather.forecast_home" layout:horizontal show_high_low:true day_font_size:12 temp_font_size:14 icon_size:32 font_family:"Roboto" color:white 
        {
          static std::map<std::string, const char*> weather_icons = {
            {"clear-night", "\U000F0594"}, {"cloudy", "\U000F0590"},
            {"exceptional", "\U000F0026"}, {"fog", "\U000F0591"},
            {"hail", "\U000F0592"}, {"lightning", "\U000F0593"},
            {"lightning-rainy", "\U000F067E"}, {"partlycloudy", "\U000F0595"},
            {"pouring", "\U000F0596"}, {"rainy", "\U000F0597"},
            {"snowy", "\U000F0598"}, {"snowy-rainy", "\U000F067F"},
            {"sunny", "\U000F0599"}, {"windy", "\U000F059D"},
            {"windy-variant", "\U000F059E"}
          };
          auto get_icon = [&](const std::string& cond) -> const char* {
            return weather_icons.count(cond) ? weather_icons[cond] : "\U000F0590";
          };
          auto get_day_name = [](int offset) -> std::string {
            if (offset == 0) return "Today";
            auto t = id(ha_time).now();
            if (!t.is_valid()) return "---";
            ESPTime future = ESPTime::from_epoch_local(t.timestamp + (offset * 86400));
            char buf[8]; future.strftime(buf, sizeof(buf), "%a");
            return std::string(buf);
          };
          {
            int dx = 0; int dy = 141;
            it.printf(dx + 40, dy, id(font_roboto_700_12), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_day_name(0).c_str());
            std::string cond = id(weather_cond_day0).state;
            it.printf(dx + 40, dy + 16, id(font_material_design_icons_400_32), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_icon(cond));
            float high = id(weather_high_day0).state; float low = id(weather_low_day0).state;
            if (!std::isnan(high) && !std::isnan(low)) {
              it.printf(dx + 40, dy + 52, id(font_roboto_400_14), COLOR_WHITE, TextAlign::TOP_CENTER, "%.0f/%.0f", high, low);
            }
          }
          {
            int dx = 80; int dy = 141;
            it.printf(dx + 40, dy, id(font_roboto_700_12), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_day_name(1).c_str());
            std::string cond = id(weather_cond_day1).state;
            it.printf(dx + 40, dy + 16, id(font_material_design_icons_400_32), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_icon(cond));
            float high = id(weather_high_day1).state; float low = id(weather_low_day1).state;
            if (!std::isnan(high) && !std::isnan(low)) {
              it.printf(dx + 40, dy + 52, id(font_roboto_400_14), COLOR_WHITE, TextAlign::TOP_CENTER, "%.0f/%.0f", high, low);
            }
          }
          {
            int dx = 160; int dy = 141;
            it.printf(dx + 40, dy, id(font_roboto_700_12), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_day_name(2).c_str());
            std::string cond = id(weather_cond_day2).state;
            it.printf(dx + 40, dy + 16, id(font_material_design_icons_400_32), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_icon(cond));
            float high = id(weather_high_day2).state; float low = id(weather_low_day2).state;
            if (!std::isnan(high) && !std::isnan(low)) {
              it.printf(dx + 40, dy + 52, id(font_roboto_400_14), COLOR_WHITE, TextAlign::TOP_CENTER, "%.0f/%.0f", high, low);
            }
          }
          {
            int dx = 240; int dy = 141;
            it.printf(dx + 40, dy, id(font_roboto_700_12), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_day_name(3).c_str());
            std::string cond = id(weather_cond_day3).state;
            it.printf(dx + 40, dy + 16, id(font_material_design_icons_400_32), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_icon(cond));
            float high = id(weather_high_day3).state; float low = id(weather_low_day3).state;
            if (!std::isnan(high) && !std::isnan(low)) {
              it.printf(dx + 40, dy + 52, id(font_roboto_400_14), COLOR_WHITE, TextAlign::TOP_CENTER, "%.0f/%.0f", high, low);
            }
          }
          {
            int dx = 320; int dy = 141;
            it.printf(dx + 40, dy, id(font_roboto_700_12), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_day_name(4).c_str());
            std::string cond = id(weather_cond_day4).state;
            it.printf(dx + 40, dy + 16, id(font_material_design_icons_400_32), COLOR_WHITE, TextAlign::TOP_CENTER, "%s", get_icon(cond));
            float high = id(weather_high_day4).state; float low = id(weather_low_day4).state;
            if (!std::isnan(high) && !std::isnan(low)) {
              it.printf(dx + 40, dy + 52, id(font_roboto_400_14), COLOR_WHITE, TextAlign::TOP_CENTER, "%.0f/%.0f", high, low);
            }
          }
        }
        // widget:sensor_text id:w_1766497361397_463 type:sensor_text x:94 y:279 w:132 h:53 ent:sensor.outside_th_temperature entity_2: title:"Outside" format:value_only_no_unit label_font:14 value_font:40 color:white label_align:TOP_LEFT value_align:TOP_LEFT precision:1 unit:"" hide_unit:false prefix:"" postfix:"°C" separator:"~" local:false text_sensor:false font_family:"Roboto" font_weight:500 italic:false
        {
          char buf1[32];
          snprintf(buf1, sizeof(buf1), "%.1f", id(sensor_outside_th_temperature).state);
          std::string val1 = buf1;
          std::string sensorValue = val1;
          std::string fullValue = "" + sensorValue + "" + "°C";
          it.printf(94, 279, id(font_roboto_500_40), COLOR_WHITE, TextAlign::TOP_LEFT, "%s", fullValue.c_str());
        }
        // widget:sensor_text id:w_1766497469586_12 type:sensor_text x:94 y:332 w:132 h:53 ent:sensor.closed_terrace_low_atc_tempc_7 entity_2: title:"Outside" format:value_only_no_unit label_font:14 value_font:40 color:white label_align:TOP_LEFT value_align:TOP_LEFT precision:1 unit:"" hide_unit:false prefix:"" postfix:"°C" separator:"~" local:false text_sensor:false font_family:"Roboto" font_weight:500 italic:false
        {
          char buf1[32];
          snprintf(buf1, sizeof(buf1), "%.1f", id(sensor_closed_terrace_low_atc_tempc_7).state);
          std::string val1 = buf1;
          std::string sensorValue = val1;
          std::string fullValue = "" + sensorValue + "" + "°C";
          it.printf(94, 332, id(font_roboto_500_40), COLOR_WHITE, TextAlign::TOP_LEFT, "%s", fullValue.c_str());
        }
        // widget:text id:w_mjin1k2ieht7n type:text x:0 y:250 w:83 h:22 text:"Living Room:" font_family:"Roboto" font_size:13 font_weight:400 italic:false color:white text_align:TOP_RIGHT 
        it.printf(0 + 83, 250, id(font_roboto_400_13), COLOR_WHITE, TextAlign::TOP_RIGHT, "Living Room:");
        // widget:text id:w_1766497642125_322 type:text x:0 y:306 w:83 h:22 text:"Outside:" font_family:"Roboto" font_size:13 font_weight:400 italic:false color:white text_align:TOP_RIGHT 
        it.printf(0 + 83, 306, id(font_roboto_400_13), COLOR_WHITE, TextAlign::TOP_RIGHT, "Outside:");
        // widget:text id:w_1766497683674_688 type:text x:0 y:359 w:83 h:22 text:"C. Terrace:" font_family:"Roboto" font_size:13 font_weight:400 italic:false color:white text_align:TOP_RIGHT 
        it.printf(0 + 83, 359, id(font_roboto_400_13), COLOR_WHITE, TextAlign::TOP_RIGHT, "C. Terrace:");
        // widget:datetime id:w_mjin6555dxm46 type:datetime x:12 y:53 w:200 h:60 format:date_only time_size:28 date_size:16 color:white text_align:CENTER italic:false font_family:"Roboto" 
        {
          auto now = id(ha_time).now();
          it.strftime(12 + 200/2, 53, id(font_roboto_400_16), COLOR_WHITE, TextAlign::TOP_CENTER, "%d.%m.%Y", now);
        }
        // widget:shape_rect id:w_mjin9q91baqrn type:shape_rect x:5 y:224 w:382 h:186 fill:false border:1 color:gray border_color:gray 
        for (int i = 0; i < 1; i++) {
          it.rectangle(5 + i, 224 + i, 382 - 2 * i, 186 - 2 * i, COLOR_BLACK);
        }
        apply_grey_dither_mask(5, 224, 382, 186);
      }


# ------------------------------------
# Hardware Recipe / Package Content
# ------------------------------------
# Note: System-level configuration (WiFi, API, etc.) has been
# automatically commented out to prevent conflicts.
# ------------------------------------
# ============================================================================
# ESPHome YAML - Generated by ESPHome Designer
# ============================================================================
# TARGET DEVICE: Waveshare Touch LCD 7 7.0" 800x480
#         - Display Platform: mipi_rgb (RGB LCD)
#         - PSRAM: Yes (Octal, 80MHz)
#         - Touchscreen: GT911 (I2C via CH422G)
#         - Framework: ESP-IDF with execute_from_psram
# ============================================================================
#
# BASED ON: https://github.com/agillis/esphome-modular-lvgl-buttons
# Hardware configuration adapted for ESPHome Designer.
#
# ============================================================================
#
# 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-S3
#         - 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)
#
# ============================================================================

# esphome: # (Auto-commented by Designer)
#   min_version: 2024.11.0
#   project:
#     name: "Waveshare.ESP32-S3-touch-lcd-7"
#     version: "1.0"
#   platformio_options:
#     board_upload.maximum_ram_size: 524288

# esp32: # (Auto-commented by Designer)
#   variant: esp32s3
#   flash_size: 16MB
#   framework:
#     type: esp-idf
#     advanced:
#        execute_from_psram: true

psram:
  mode: octal
  speed: 80Mhz

# preferences: # (Auto-commented by Designer)
#   flash_write_interval: 5min

ch422g:
  - id: ch422g_hub

switch:
  - platform: gpio
    id: lcdbacklight
    name: lcdbacklight
    pin:
      ch422g: ch422g_hub
      number: 2
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_ON

light:
  - platform: monochromatic
    name: "Display Backlight"
    output: fake_backlight_output
    id: display_backlight
    default_transition_length: 1s
    gamma_correct: 2.8

output:
  - platform: template
    id: fake_backlight_output
    type: float
    write_action:
      - lambda: |-
          ESP_LOGD("fake_light", "Fake brightness level: %.2f", state);

i2c:
  - id: bus_a
    sda: GPIO8
    scl: GPIO9
    scan: true

touchscreen:
  platform: gt911
  id: my_touchscreen
  i2c_id: bus_a
  interrupt_pin: GPIO4
  reset_pin:
    ch422g: ch422g_hub
    number: 1
    mode: OUTPUT

display:
  - platform: mipi_rgb
    model: ESP32-S3-TOUCH-LCD-7-800X480
    id: my_display
    rotation: 90
    update_interval: never
    auto_clear_enabled: false
    color_order: RGB
    pclk_frequency: 16MHZ
    dimensions:
      width: 800
      height: 480
    reset_pin:
      ch422g: ch422g_hub
      number: 3
    de_pin:
      number: GPIO5
    hsync_pin:
      number: GPIO46
      ignore_strapping_warning: true
    vsync_pin:
      number: GPIO3
      ignore_strapping_warning: true
    pclk_pin: GPIO7
    pclk_inverted: true
    hsync_back_porch: 8
    hsync_front_porch: 8
    hsync_pulse_width: 4
    vsync_back_porch: 8
    vsync_front_porch: 8
    vsync_pulse_width: 4
    data_pins:
      red: [1, 2, 42, 41, 40]
      blue: [14, 38, 18, 17, 10]
      green: [39, 0, 45, 48, 47, 21]
    # __LAMBDA_PLACEHOLDER__


# ====================================
# Device Settings
# ====================================
# Orientation: landscape
# Dark Mode: enabled
# Power Strategy: Full Power (Always On)
# ====================================

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'

http_request:
  verify_ssl: false
  timeout: 20s

time:
  - platform: homeassistant
    id: ha_time

sensor:
  - platform: homeassistant
    id: sensor_living_room_th_temp
    entity_id: sensor.living_room_th_temp
    internal: true
  - platform: homeassistant
    id: sensor_outside_th_temperature
    entity_id: sensor.outside_th_temperature
    internal: true
  - platform: homeassistant
    id: sensor_closed_terrace_low_atc_tempc_7
    entity_id: sensor.closed_terrace_low_atc_tempc_7
    internal: true
  - platform: homeassistant
    id: weather_high_day0
    entity_id: sensor.weather_forecast_day_0_high
    internal: true
  - platform: homeassistant
    id: weather_low_day0
    entity_id: sensor.weather_forecast_day_0_low
    internal: true
  - platform: homeassistant
    id: weather_high_day1
    entity_id: sensor.weather_forecast_day_1_high
    internal: true
  - platform: homeassistant
    id: weather_low_day1
    entity_id: sensor.weather_forecast_day_1_low
    internal: true
  - platform: homeassistant
    id: weather_high_day2
    entity_id: sensor.weather_forecast_day_2_high
    internal: true
  - platform: homeassistant
    id: weather_low_day2
    entity_id: sensor.weather_forecast_day_2_low
    internal: true
  - platform: homeassistant
    id: weather_high_day3
    entity_id: sensor.weather_forecast_day_3_high
    internal: true
  - platform: homeassistant
    id: weather_low_day3
    entity_id: sensor.weather_forecast_day_3_low
    internal: true
  - platform: homeassistant
    id: weather_high_day4
    entity_id: sensor.weather_forecast_day_4_high
    internal: true
  - platform: homeassistant
    id: weather_low_day4
    entity_id: sensor.weather_forecast_day_4_low
    internal: true

button:
  - platform: template
    name: "Next Page"
    on_press:
      then:
        - lambda: |-
            if (id(display_page) < 0) {
              id(display_page) += 1;
            } else {
              id(display_page) = 0;
            }
        - component.update: my_display
  - platform: template
    name: "Previous Page"
    on_press:
      then:
        - lambda: |-
            if (id(display_page) > 0) {
              id(display_page) -= 1;
            } else {
              id(display_page) = 0;
            }
        - component.update: my_display
  - platform: template
    name: "Refresh Display"
    on_press:
      then:
        - component.update: my_display
  - platform: template
    name: "Go to Page 1"
    on_press:
      then:
        - lambda: 'id(display_page) = 0;'
        - component.update: my_display

text_sensor:
  # Weather Forecast Condition Sensors
  - platform: homeassistant
    id: weather_cond_day0
    entity_id: sensor.weather_forecast_day_0_condition
    internal: true
  - platform: homeassistant
    id: weather_cond_day1
    entity_id: sensor.weather_forecast_day_1_condition
    internal: true
  - platform: homeassistant
    id: weather_cond_day2
    entity_id: sensor.weather_forecast_day_2_condition
    internal: true
  - platform: homeassistant
    id: weather_cond_day3
    entity_id: sensor.weather_forecast_day_3_condition
    internal: true
  - platform: homeassistant
    id: weather_cond_day4
    entity_id: sensor.weather_forecast_day_4_condition
    internal: true

# ============================================================================
# HOME ASSISTANT TEMPLATE SENSORS
# Add these template sensors to your Home Assistant configuration.yaml:
# ============================================================================
#
# template:
#   - trigger:
#       - trigger: state
#         entity_id: weather.forecast_home  # Replace with your weather entity
#       - trigger: time_pattern
#         hours: "/1"
#     action:
#       - action: weather.get_forecasts
#         target:
#           entity_id: weather.forecast_home  # Replace with your weather entity
#         data:
#           type: daily
#         response_variable: forecast_data
#     sensor:
#       - name: "Weather Forecast Day 0 High"
#         unique_id: weather_forecast_day_0_high
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[0].temperature | default('N/A') }}"
#       - name: "Weather Forecast Day 0 Low"
#         unique_id: weather_forecast_day_0_low
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[0].templow | default('N/A') }}"
#       - name: "Weather Forecast Day 0 Condition"
#         unique_id: weather_forecast_day_0_condition
#         state: "{{ forecast_data['weather.forecast_home'].forecast[0].condition | default('cloudy') }}"
#       - name: "Weather Forecast Day 1 High"
#         unique_id: weather_forecast_day_1_high
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[1].temperature | default('N/A') }}"
#       - name: "Weather Forecast Day 1 Low"
#         unique_id: weather_forecast_day_1_low
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[1].templow | default('N/A') }}"
#       - name: "Weather Forecast Day 1 Condition"
#         unique_id: weather_forecast_day_1_condition
#         state: "{{ forecast_data['weather.forecast_home'].forecast[1].condition | default('cloudy') }}"
#       - name: "Weather Forecast Day 2 High"
#         unique_id: weather_forecast_day_2_high
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[2].temperature | default('N/A') }}"
#       - name: "Weather Forecast Day 2 Low"
#         unique_id: weather_forecast_day_2_low
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[2].templow | default('N/A') }}"
#       - name: "Weather Forecast Day 2 Condition"
#         unique_id: weather_forecast_day_2_condition
#         state: "{{ forecast_data['weather.forecast_home'].forecast[2].condition | default('cloudy') }}"
#       - name: "Weather Forecast Day 3 High"
#         unique_id: weather_forecast_day_3_high
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[3].temperature | default('N/A') }}"
#       - name: "Weather Forecast Day 3 Low"
#         unique_id: weather_forecast_day_3_low
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[3].templow | default('N/A') }}"
#       - name: "Weather Forecast Day 3 Condition"
#         unique_id: weather_forecast_day_3_condition
#         state: "{{ forecast_data['weather.forecast_home'].forecast[3].condition | default('cloudy') }}"
#       - name: "Weather Forecast Day 4 High"
#         unique_id: weather_forecast_day_4_high
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[4].temperature | default('N/A') }}"
#       - name: "Weather Forecast Day 4 Low"
#         unique_id: weather_forecast_day_4_low
#         unit_of_measurement: "°C"
#         state: "{{ forecast_data['weather.forecast_home'].forecast[4].templow | default('N/A') }}"
#       - name: "Weather Forecast Day 4 Condition"
#         unique_id: weather_forecast_day_4_condition
#         state: "{{ forecast_data['weather.forecast_home'].forecast[4].condition | default('cloudy') }}"
#
# ============================================================================

font:
  - file:
      type: gfonts
      family: Roboto
      weight: 400
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 700
    id: font_roboto_700_71
    size: 71
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 400
    id: font_roboto_400_16
    size: 16
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 500
    id: font_roboto_500_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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 500
    id: font_roboto_500_40
    size: 40
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 700
    id: font_roboto_700_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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 400
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file: "fonts/materialdesignicons-webfont.ttf"
    id: font_material_design_icons_400_32
    size: 32
    glyphs: ["\U000F0026", "\U000F0590", "\U000F0591", "\U000F0592", "\U000F0593", "\U000F0594", "\U000F0595", "\U000F0596", "\U000F0597", "\U000F0598", "\U000F0599", "\U000F059D", "\U000F059E", "\U000F067E", "\U000F067F"]
  - file:
      type: gfonts
      family: Roboto
      weight: 400
    id: font_roboto_400_13
    size: 13
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
  - file:
      type: gfonts
      family: Roboto
      weight: 700
    id: font_roboto_700_28
    size: 28
    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", "\U000000B0", "\U000000B1", "\U000000B2", "\U000000B3", "\U000000B5", "\U000000A3", "\U000000A5", "\U000000A9", "\U000000AE", "\U000000D7", "\U000000F7", "\U000003BC", "\U000003A9", "\U000020AC", "\U00002122"]
script:
  - id: manage_run_and_sleep
    mode: restart
    then:
      - logger.log: "Waiting for sync (Generic/E1001)..."
      - wait_until:
          condition:
            lambda: 'return id(ha_time).now().is_valid() && api_is_connected();'
          timeout: 60s
      - delay: 5s # Grace period for data propagation
      - lambda: |-
          if (!id(ha_time).now().is_valid()) {
            ESP_LOGW("script", "Time sync failed/invalid! Sleeping for 1 hour to retry.");
            return;
          }

      # Regular Run
      - if:
          condition:
            lambda: 'return !id(ha_time).now().is_valid();'
          then:
            - delay: 2000ms
            - script.execute: manage_run_and_sleep
          else:
            - lambda: |-
                int page = id(display_page);
                int interval = id(page_refresh_default_s);
                switch (page) {
                  default:
                    break;
                }
                if (interval < 60) {
                  interval = 60;
                }
                id(page_refresh_current_s) = interval;
                ESP_LOGI("refresh", "Next refresh in %d seconds for page %d", interval, page);
            

            - component.update: my_display
      
            - delay: !lambda 'return id(page_refresh_current_s) * 1000;'
            - script.execute: manage_run_and_sleep

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants