Use ESPHome with e-ink Displays to blend in with your home decor!

Not a problem, the code might need some clean-up though, but it works. The only issue I have is that I cannot compile the yaml if I am using secrets. ESPHome returns error, just change whatever needs to be changed to suit your needs. Oh, you would need to edit “weatherman” config to swap entitity names with yours.

# WEATHERMAN DASHBOARD
# For Home Assistant and ESPHome
# Designed by Madelena Mak 2022 - https://mmak.es

# Cue "Blame it on the Weatherman" by B*Witched!
esphome:
  name: "weatherman"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

wifi:
  ssid: "CHANGEME"
  password: "CHANGEME"
  
  reboot_timeout: 300s
  
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-901078"
    password: "WHATEVER"
   

# Include time
time:
  - platform: homeassistant
    id: esptime

#Include sun
sun:
  latitude: CHANGEME
  longitude: CHANGEME

# Include custom fonts
font:
  - file: 'fonts/GothamRnd-Book.ttf'
    id: font_small_book
    size: 18
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_large_bold
    size: 108
    glyphs: [' ', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C',]
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_time
    size: 90
    glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':']
  - file: 'fonts/GothamRnd-Book.ttf'
    id: font_weekday
    size: 30
  - file: 'fonts/GothamRnd-Book.ttf'
    id: font_day
    size: 65
    glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_month
    size: 40
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_medium_bold
    size: 40
    #glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'M', 'I', 'N']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_small_bold
    size: 18
    # glyphs: ['°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', 'M', 'I', 'N']

  # Include Material Design Icons font
  # Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_large
    size: 96
    glyphs: &mdi-weather-glyphs
      - "\U000F0590" # mdi-weather-cloudy
      - "\U000F0F2F" # mdi-weather-cloudy-alert
      - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
      - "\U000F0591" # mdi-weather-fog
      - "\U000F0592" # mdi-weather-hail
      - "\U000F0F30" # mdi-weather-hazy
      - "\U000F0898" # mdi-weather-hurricane
      - "\U000F0593" # mdi-weather-lightning
      - "\U000F067E" # mdi-weather-lightning-rainy
      - "\U000F0594" # mdi-weather-night
      - "\U000F0F31" # mdi-weather-night-partly-cloudy
      - "\U000F0595" # mdi-weather-partly-cloudy
      - "\U000F0F32" # mdi-weather-partly-lightning
      - "\U000F0F33" # mdi-weather-partly-rainy
      - "\U000F0F34" # mdi-weather-partly-snowy
      - "\U000F0F35" # mdi-weather-partly-snowy-rainy
      - "\U000F0596" # mdi-weather-pouring
      - "\U000F0597" # mdi-weather-rainy
      - "\U000F0598" # mdi-weather-snowy
      - "\U000F0F36" # mdi-weather-snowy-heavy
      - "\U000F067F" # mdi-weather-snowy-rainy
      - "\U000F0599" # mdi-weather-sunny
      - "\U000F0F37" # mdi-weather-sunny-alert
      - "\U000F14E4" # mdi-weather-sunny-off
      - "\U000F059A" # mdi-weather-sunset
      - "\U000F059B" # mdi-weather-sunset-down
      - "\U000F059C" # mdi-weather-sunset-up
      - "\U000F0F38" # mdi-weather-tornado
      - "\U000F059D" # mdi-weather-windy
      - "\U000F059E" # mdi-weather-windy-variant
      - "\U000F058E" # mdi-water-percent
      - "\U000F04C5" # mdi-spedometer
      - "\U000F0F29" # mdi-snowflake-alert
      - "\U000F15FA" # mdi-windsock
      - "\U000F19B3" # mdi-arrow-down-thin
      - "\U000F19B2" # mdi-arrow-up-thin
      - "\U000F19B4" # mdi-arrow-top-right-thin
      - "\U000F19B7" # mdi-arrow-bottom-right-thin
      - "\U000F00A5" # mdi-binoculars
      - "\U000F018C" # mdi-compass-outline
      - "\U000F05A9" # mdi-wifi
      - "\U000F0928" # mdi-wifi-strength-4
      - "\U000F0925" # mdi-wifi-strength-3 
      - "\U000F0922" # mdi-wifi-strength-2
      - "\U000F091F" # mdi-wifi-strength-1
      - "\U000F092B" # mdi-wifi-strength-alert-outline
      - "\U000F0079" # mdi-battery
      - "\U000F0082" # mdi-battery-90
      - "\U000F0081" # mdi-battery-80
      - "\U000F0080" # mdi-battery-70
      - "\U000F007F" # mdi-battery-60
      - "\U000F007E" # mdi-battery-50
      - "\U000F007D" # mdi-battery-40
      - "\U000F007C" # mdi-battery-30
      - "\U000F007B" # mdi-battery-20
      - "\U000F007A" # mdi-battery-10
      - "\U000F10CD" # mdi-battery-alert-variant-outline
      - "\U000F0E03" # mdi-thermometer-chevron-up
      - "\U000F0E02" # mdi-thermometer-chevron-down
      - "\U000F1A09" # mdi-triangle-small-down
      - "\U000F1A0A" # mdi-triangle-small-up
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_medlarge
    size: 60
    glyphs:
      - "\U000F058E" # mdi-water-percent
      - "\U000F04C5" # mdi-spedometer
      - "\U000F0F29" # mdi-snowflake-alert
      - "\U000F15FA" # mdi-windsock
      - "\U000F0F61" # mdi-moon-first-quarter
      - "\U000F0F62" # mdi-moon-full
      - "\U000F0F63" # mdi-moon-last-quarter
      - "\U000F0F64" # mdi-moon-new
      - "\U000F0F65" # mdi-moon-waning-crescent
      - "\U000F0F66" # mdi-moon-waning-gibbous
      - "\U000F0F67" # mdi-moon-waxing-crescent
      - "\U000F0F68" # mdi-moon-waxing-gibbous
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_medium
    size: 36
    glyphs: *mdi-weather-glyphs


# Include Custom Titles
image:
  - file: "images/weatherman-title-weather.png"
    id: title_weather
    type: BINARY


# Call Weather sensors from HA
sensor:
  # Temperature - My Weather station
  - platform: homeassistant
    entity_id: weather.my_weather_station
    attribute: temperature
    id: weather_temperature
    
  # Humidity - My Weather station
  - platform: homeassistant
    entity_id: weather.my_weather_station
    attribute: humidity
    id: weather_humidity

  # Air pressure - My Weather station
  - platform: homeassistant
    entity_id: weather.my_weather_station
    attribute: pressure
    id: weather_pressure

  # Wind Bearing - from Yr.no (built-in HA weather privider)
  - platform: homeassistant
    entity_id: weather.home
    attribute: wind_bearing
    id: wind_bearing

  # Battery % for Aqara sensor
  - platform: homeassistant
    entity_id: sensor.zigbeeweather_battery
    id: battery_percent
  # Battery Voltage for Aqara sensor
  - platform: homeassistant
    entity_id: sensor.zigbeeweather_battery
    attribute: voltage
    id: battery_voltage

  # Weatherman entities
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_0
    id: weather_temperature_0
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_1
    id: weather_temperature_1
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_2
    id: weather_temperature_2
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_temperature_3
    id: weather_temperature_3

  # Strong Wind
  - platform: homeassistant
    entity_id: sensor.wind_warning
    id: wind_warning
  # Wind Speed 
  - platform: homeassistant
    entity_id: weather.my_weather_station
    attribute: wind_speed
    id: wind_speed
  # UV Index
  - platform: homeassistant
    entity_id: sensor.dundonald_uv_index_3_hourly
    id: uv_index
  # WiFi Signal     
  - platform: wifi_signal
    name: "WiFi Signal Sensor"
    id: wifisignal
    update_interval: 20s


text_sensor:
  # Pressure Trend
  - platform: homeassistant
    entity_id: binary_sensor.atmospheric_pressure
    id: pressure_trend
  # Temp Trend
  - platform: homeassistant
    entity_id: binary_sensor.outside_temperature
    id: temp_trend
  # Weather State
  - platform: homeassistant
    entity_id: weather.my_weather_station
    id: weather_state
  # Frost Risk
  - platform: homeassistant
    entity_id: sensor.weather_frostrisk
    id: frost_risk
  # # Weatherman entities
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_now
    id: weather_condition_now
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_0
    id: weather_condition_0
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_0
    id: weather_timestamp_0
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_1
    id: weather_condition_1
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_1
    id: weather_timestamp_1
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_2
    id: weather_condition_2
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_2
    id: weather_timestamp_2
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_condition_3
    id: weather_condition_3
  - platform: homeassistant
    entity_id: sensor.weatherman_data
    attribute: weather_timestamp_3
    id: weather_timestamp_3
  # Sunrise
  - platform: sun
    type: sunrise
    id: sun_sunrise
    format: "%H:%M"
  # Sunset
  - platform: sun
    type: sunset
    id: sun_sunset
    format: "%H:%M"
  # Visibility range from Met Office
  - platform: homeassistant
    entity_id: sensor.dundonald_visibility_distance_daily
    id: visibility_range
  # Moon phase
  - platform: homeassistant
    entity_id: sensor.moon
    id: moon_phase
  - platform: homeassistant
    entity_id: sensor.moon_rise
    id: moon_rise
  - platform: homeassistant
    entity_id: sensor.moon_set
    id: moon_set


# Define colors
# This design is white on black so this is necessary.
color:
  - id: color_black
    red: 0%
    green: 0%
    blue: 0%
    white: 50%
  - id: color_white
    red: 0%
    green: 0%
    blue: 0%
    white: 0%


# Pins for Waveshare ePaper ESP Board
spi:
  clk_pin: GPIO13
  mosi_pin: GPIO14


# Now render everything on the ePaper screen.
display:
  - platform: waveshare_epaper
    cs_pin: GPIO15
    dc_pin: GPIO27
    busy_pin: GPIO25
    reset_pin: GPIO26
    model: 7.50inV2
    update_interval: 60s
    rotation: 90°
    auto_clear_enabled: false
    lambda: |-
      // Map weather states to MDI characters.
      std::map<std::string, std::string> visibility_short
        {
          {"20-40", "30"},
          {"20-30", "25"},
          {"10-20", "15"},
        };
      std::map<std::string, std::string> moon_icon_map
        {
          {"first_quarter", "\U000F0F61"},
          {"full_moon", "\U000F0F62"},
          {"last_quarter", "\U000F0F63"},
          {"new_moon", "\U000F0F64"},
          {"waning_crescent", "\U000F0F65"},
          {"waning_gibbous", "\U000F0F66"},
          {"waning_crescent", "\U000F0F67"},
          {"waxing_gibbous", "\U000F0F68"},
          
        };
      std::map<std::string, std::string> weather_icon_map
        {
          {"cloudy", "\U000F0590"},
          {"cloudy-alert", "\U000F0F2F"},
          {"cloudy-arrow-right", "\U000F0E6E"},
          {"fog", "\U000F0591"},
          {"hail", "\U000F0592"},
          {"hazy", "\U000F0F30"},
          {"hurricane", "\U000F0898"},
          {"lightning", "\U000F0593"},
          {"lightning-rainy", "\U000F067E"},
          {"night", "\U000F0594"},
          {"night-partly-cloudy", "\U000F0F31"},
          {"partlycloudy", "\U000F0595"},
          {"partly-lightning", "\U000F0F32"},
          {"partly-rainy", "\U000F0F33"},
          {"partly-snowy", "\U000F0F34"},
          {"partly-snowy-rainy", "\U000F0F35"},
          {"pouring", "\U000F0596"},
          {"rainy", "\U000F0597"},
          {"snowy", "\U000F0598"},
          {"snowy-heavy", "\U000F0F36"},
          {"snowy-rainy", "\U000F067F"},
          {"sunny", "\U000F0599"},
          {"sunny-alert", "\U000F0F37"},
          {"sunny-off", "\U000F14E4"},
          {"sunset", "\U000F059A"},
          {"sunset-down", "\U000F059B"},
          {"sunset-up", "\U000F059C"},
          {"tornado", "\U000F0F38"},
          {"windy", "\U000F059D"},
          {"windy-variant", "\U000F059E"},
        };

      // Fill background in black.
      it.fill(color_white);

      // ----------------------------------------------------------------------------------- Print full weekday name
      it.strftime(340, 95, id(font_weekday), TextAlign::TOP_RIGHT, "%A", id(esptime).now());
      // ----------------------------------------------------------------------------------- Print time in HH:MM format 335
      it.strftime(340, 200, id(font_time), TextAlign::BASELINE_RIGHT, "%H:%M", id(esptime).now());
      // TEST it.printf(315, 200, id(font_time), TextAlign::BASELINE_RIGHT, "88:88");
      
      // ----------------------------------------------------------------------------------- Print day of the month
      it.strftime(440, 95, id(font_day), TextAlign::TOP_RIGHT, "%d", id(esptime).now());
      // ----------------------------------------------------------------------------------- Print abbreviated month name
      it.strftime(440, 200, id(font_month), TextAlign::BASELINE_RIGHT, "%b", id(esptime).now());
      // TEST it.printf(440, 200, id(font_month), TextAlign::BASELINE_RIGHT, "AAA");

      // ----------------------------------------------------------------------------------- WiFi
      if(id(wifisignal).has_state ()) {
        if (id(wifisignal).state >= -50) {
            // Excellent # mdi-wifi-strength-4 "\U000F0928" 255, 230
            it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0928");
        } else if (id(wifisignal).state  >= -60) {
            //Good # mdi-wifi-strength-3 "\U000F0925"
            it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0925");
        } else if (id(wifisignal).state  >= -67) {
            //Fair # mdi-wifi-strength-2 "\U000F0922"
            it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0922");
        } else if (id(wifisignal).state  >= -70) {
            //Weak # mdi-wifi-strength-1 "\U000F091F"
            it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F091F");
        } else {
            //Unlikely working signal # mdi-wifi-strength-alert-outline "\U000F092B"
            it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F092B");
        }
      }
      // ----------------------------------------------------------------------------------- LOW BATTERY
        if(id(battery_voltage).has_state ()) {
            if(id(battery_voltage).state <= 2700) {
                // Replace battery, less than 10% 420, 558 / 87
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F10CD");
            } else if (id(battery_percent).state == 100) {
                // "\U000F0079" # mdi-battery
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0079");
            } else if (id(battery_percent).state >= 90) {
                // "\U000F0082" # mdi-battery-90
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0082");
            } else if (id(battery_percent).state >= 80) {
                // "\U000F0081" # mdi-battery-80
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0081");
            } else if (id(battery_percent).state >= 70) {
                // "\U000F0080" # mdi-battery-70
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0080");
            } else if (id(battery_percent).state >= 60) {
                // "\U000F007F" # mdi-battery-60
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007F");
            } else if (id(battery_percent).state >= 50) {
                // "\U000F007E" # mdi-battery-50
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007E");
            } else if (id(battery_percent).state >= 40) {
                // "\U000F007D" # mdi-battery-40
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007D");
            } else if (id(battery_percent).state >= 30) {
                // "\U000F007C" # mdi-battery-30
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007C");
            } else if (id(battery_percent).state >= 20) {
                // "\U000F007B" # mdi-battery-20
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007B");
            } else if (id(battery_percent).state >= 10) {
                // "\U000F007A" # mdi-battery-10
                it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007A");
            }
        }
      // ----------------------------------------------------------------------------------- Print sunrise
        if(id(sun_sunrise).has_state ()) {
            it.printf(100, 235, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F059C");
            it.printf(105, 235, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(sun_sunrise).state.c_str());
        }      
      // ----------------------------------------------------------------------------------- Print sunset
        if(id(sun_sunset).has_state ()) {
            it.printf(455, 235, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F059B");
            it.printf(415, 235, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(sun_sunset).state.c_str());
        }
      // ----------------------------------------------------------------------------------- Print moonrise
        if(id(moon_rise).has_state ()) {
            it.printf(155, 260, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F1A0A");
            it.printf(155, 260, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(moon_rise).state.c_str());
        }      
      // ----------------------------------------------------------------------------------- Print moonset
        if(id(moon_set).has_state ()) {
            it.printf(400, 260, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F1A09");
            it.printf(365, 260, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(moon_set).state.c_str());
        }
      // Weather Section ------------------------------------------------------------------- PLACE NAME
        // TEST it.image(20, 338, id(title_weather));
        it.print(265, 280, id(font_weekday), color_black, TextAlign::TOP_CENTER, "DUNDONALD");

      // ----------------------------------------------------------------------------------- WEATHER STATE ICON --------------- (110, 358)
        it.printf(245, 335, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
      // TEST it.printf(245, 340, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "\U000F0F35");
      
      // ----------------------------------------------------------------------------------- MOON PHASE ICON ------------------
        if(id(moon_phase).has_state ()) {
            it.printf(265, 243, id(font_mdi_medlarge), color_black, TextAlign::CENTER, "%s", moon_icon_map[id(moon_phase).state.c_str()].c_str());
        }     
      // ----------------------------------------------------------------------------------- HUMIDITY
        if(id(weather_humidity).has_state ()) {
            it.printf(100, 352, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F058E");
            it.printf(145, 350, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "%s", "%");
            it.printf(140, 350, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(weather_humidity).state);
        }      
      // ----------------------------------------------------------------------------------- VISIBILITY
        if(id(visibility_range).has_state ()) {
            it.printf(100, 400, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F00A5");
            it.printf(140, 400, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%s", visibility_short[id(visibility_range).state.c_str()].c_str());
            it.printf(145, 400, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "km");
        }
      // ----------------------------------------------------------------------------------- UV INDEX
        if(id(uv_index).has_state ()) {
            it.printf(100, 454, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F0F37");
            it.printf(140, 450, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(uv_index).state);
            it.printf(145, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "UVI");
        }
      // ----------------------------------------------------------------------------------- PRESSURE
        if(id(weather_pressure).has_state ()) {
            // pressure trend
            if(id(pressure_trend).state == "on") {
                it.printf(325, 353, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F19B4");
            } else if(id(pressure_trend).state == "off") {
                it.printf(325, 352, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F19B7");
            }
            it.printf(410, 350, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(weather_pressure).state);
            it.printf(415, 350, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "hPa");
        }
        // TEST it.printf(410, 340, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "1888");
      // ----------------------------------------------------------------------------------- WIND
        if(id(wind_speed).has_state ()) {
            it.printf(330, 400, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F15FA");
            it.printf(410, 400, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(wind_speed).state);
            it.printf(415, 400, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "kmh");
            if(id(wind_warning).state > 20) {
                it.printf(415, 485, id(font_mdi_medium), color_black, TextAlign::TOP_LEFT, "\U000F15FA");
            }
        }
        // TEST it.printf(420, 390, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "188");
      // ----------------------------------------------------------------------------------- WIND DIRECTION & BEARING
        if(id(wind_bearing).has_state ()) {
            it.printf(330, 454, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F018C");
            it.printf(410, 450, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(wind_bearing).state);
            if (id(wind_bearing).state > 337.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "N");
            } else if(id(wind_bearing). state > 292.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "NW");
            } else if(id(wind_bearing). state > 247.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "W");
            } else if(id(wind_bearing). state > 202.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "SW");
            } else if(id(wind_bearing). state > 157.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "S");
            } else if(id(wind_bearing). state > 112.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "SE");
            } else if(id(wind_bearing). state > 67.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "E");
            } else if(id(wind_bearing). state > 22.5) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "NE");
            } else if(id(wind_bearing). state >= 0) {
                it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "N");
            }
        }
      // ----------------------------------------------------------------------------------- Frost Warning
        if(id(frost_risk).has_state ()) {
            if(id(frost_risk).state != "no_risk") {
                it.printf(415, 565, id(font_mdi_medium), color_black, TextAlign::BASELINE_LEFT, "\U000F0F29");
            }
        }
      // ----------------------------------------------------------------------------------- TEMPERATURE ---------------------- (310, 458)
        if(id(weather_temperature).has_state ()) {
            it.printf(410, 480, id(font_large_bold), color_black, TextAlign::TOP_RIGHT, "%2.0f°C", id(weather_temperature).state);
            // TEST it.printf(410, 480, id(font_large_bold), color_black, TextAlign::TOP_RIGHT, "%s", "88°C");
        }
        if(id(temp_trend).has_state ()) {
            if(id(temp_trend).state == "on") {
                it.printf(123, 527, id(font_mdi_medium), color_black, TextAlign::CENTER, "\U000F0E03");
            } else if(id(temp_trend).state == "off") {
                it.printf(123, 527, id(font_mdi_medium), color_black, TextAlign::CENTER, "\U000F0E02");
            }
        }
      
        if(id(weather_temperature_0).has_state ()) {
            it.printf(90, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
            it.printf(90, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
            it.printf(90, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
        }
        
        if(id(weather_temperature_1).has_state ()) {
            it.printf(200, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
            it.printf(200, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
            it.printf(200, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
        }
        
        if(id(weather_temperature_2).has_state ()) {
            it.printf(315, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
            it.printf(315, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
            it.printf(315, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
        }
        
        if(id(weather_temperature_3).has_state ()) {
            it.printf(425, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
            it.printf(425, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
            it.printf(425, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
        }
      
captive_portal:


Template entities:

  - sensor:
      - name: "Moon Rise"
        icon: "mdi:triangle-small-up"
        state: >-
          {% set x = states('sensor.astroweather_moon_next_rising') %}
          
          {{ x[11:16] }}
  - sensor:
      - name: "Moon Set"
        icon: "mdi:triangle-small-down"
        state: >-
          {% set x = states('sensor.astroweather_moon_next_setting') %}
          
          {{ x[11:16] }}

The above comes from Astroweater integration available to install in HACS:

Wind warning is based on my custom weather entity, by changing [1] to other number you can chose how soon you will see the warning.

  - sensor:
      - name: "Wind Warning"
        icon: "mdi:weather-windy"
        unit_of_measurement: "km/h"
        state: "{{state_attr('weather.my_weather_station', 'forecast')[1]['wind_speed']}}"

UV index sensor comes with MET Office integration. I also need to change source for the wind speed . I just noticed Met Office provides separate sensors in its integration, but if I remember correctly these are disabled by default. You can easily be change the identity name in the code once activated.

Temp trend:

  - platform: trend
    sensors:
      outside_temperature:
        entity_id: sensor.zigbeeweather_temperature
        friendly_name: "Temperature Trend"
        max_samples: 60
        sample_duration: 10800

Pressure trend:

  - platform: trend
    sensors:
      atmospheric_pressure:
        entity_id: sensor.zigbeeweather_pressure
        friendly_name: "Pressure Trend"
        max_samples: 60
        sample_duration: 21600

Lastly, frost risk is based on your current temperature, frost point and absolute humidit, quite reliable. Easily available through Thermal Comfort custom integration (HACS):

If I missed something, let me know. Hope it works without any issues.