ESPHome Mini Weather Display

Just a very quick post for a small weather display based on an ESP32 and an ili9341 2.2" TFT display.

The main reason for posting is that the code for calculating the location of the wind direction indicator on the compass rose may come in handy for someone.

This uses various sensors provided by my Home Assistant instance.

ESPHome YAML:

esphome:
  name: wind

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

ota:
  password: "8aebd6eb0427929de523046d6773d66e"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Wind Fallback Hotspot"
    password: "sh1mZkRvphaJ"

captive_portal:

text_sensor:
  - platform: homeassistant
    name: "Current Temp"
    entity_id: sensor.weather_station_temperature
    id: temp

  - platform: homeassistant
    name: "Current Wind Dir"
    entity_id: sensor.wind_direction
    id: wind_dir

  - platform: homeassistant
    name: "Current Wind Speed"
    entity_id: sensor.wind_speed
    id: wind_speed

  - platform: homeassistant
    name: "Named Wind Dir"
    entity_id: sensor.named_wind_direction
    id: named_dir
    
  - platform: homeassistant
    name: "Rain since 12am"
    entity_id: sensor.rain_accumulation
    id: total_rain

  - platform: homeassistant
    name: "Rain since 12am"
    entity_id: sensor.atmospheric_pressure_msl
    id: pressure
    
font:
  - file: "fonts/calibri.ttf"
    id: calibri_20
    size: 20

  - file: "fonts/calibri.ttf"
    id: calibri_25
    size: 25
    
  - file: "fonts/calibri.ttf"
    id: calibri_40
    size: 40
    
time:
  - platform: homeassistant
    id: my_time

display:
  - platform: ili9341
    rotation: 0
    model: TFT 2.4
    dc_pin: GPIO21
    cs_pin: GPIO22
    led_pin: GPIO12
    reset_pin: GPIO17
    
    lambda: |-
      // Colours - used for visiual indication of wind strength
      auto red = Color(255, 0, 0);
      auto green = Color(0, 255, 0);
      auto light_blue = Color(135, 237, 232);
      auto orange = Color(255, 170, 43);
      auto white = Color(255, 255, 255);
      auto purple = Color(97, 15, 219);
      // Convert wind direction to int
      int dir = atoi(id(wind_dir).state.c_str());
      // Convert wind speed to float
      float speed = atof(id(wind_speed).state.c_str());
      // Calculate xy position to plot wind indicator
      int x = 120 + (90 * (cos((dir-90)*PI/180)));
      int y = 160 + (90 * (sin((dir-90)*PI/180)));
      // Weather data
      it.strftime(5, 10, id(calibri_25), TextAlign::TOP_LEFT, "%H:%M", id(my_time).now());
      it.printf(235, 10, id(calibri_25), TextAlign::TOP_RIGHT, "%s °C", id(temp).state.c_str());
      it.printf(5, 310, id(calibri_20), TextAlign::BOTTOM_LEFT, "%s mm", id(total_rain).state.c_str());
      it.printf(235, 310, id(calibri_20), TextAlign::BOTTOM_RIGHT, "%s hPa", id(pressure).state.c_str());
      // Compass rose
      it.circle(120, 160, 90);
      it.print(120, 60, id(calibri_20), red, TextAlign::BOTTOM_CENTER, "N");
      it.print(120, 260, id(calibri_20), red, TextAlign::TOP_CENTER, "S");
      it.print(20, 160, id(calibri_20), red, TextAlign::CENTER_RIGHT, "W");
      it.print(220, 160, id(calibri_20), red, TextAlign::CENTER_LEFT, "E");
      // Wind pointer
      if (speed<=11) { it.filled_circle(x, y, 7, light_blue); }
        else {
      if (speed>11 && speed<=30) { it.filled_circle(x, y, 7, green); } 
        else {
      if (speed>30 && speed<=60) { it.filled_circle(x, y, 7, orange); } 
        else {
      if (speed>60) { it.filled_circle(x, y, 7, red); } 
        } } }
      // Wind details
      it.printf(120, 140, id(calibri_25), TextAlign::BOTTOM_CENTER, "%s", id(named_dir).state.c_str());
      if (speed<10) { it.printf(120, 185, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.1f", speed); }
        else { it.printf(120, 185, id(calibri_40), TextAlign::BOTTOM_CENTER, "%2.0f", round(speed));   
        }
      it.print(120, 185, id(calibri_20), TextAlign::TOP_CENTER, "km/h");     
5 Likes

Wow. Thank you.