Selected forecast items to ESP32 & ePaper display?

I have something similar (or exactly) what you want.

First I created a sensor in HA to get the forecast values in to one long string.
Values are separated with ; and days are separated with #.

sensor:
  - platform: template
    sensors:
      weather_fivedays:
        friendly_name: "Five day weather"
        value_template: >-
             # this creates an icon for each weather that can be displayed in ESPhome with the mdi font
             {% set weather = {
                "sunny": "",
                "clear-day": "", 
                "clear-night": "", 
                "cloudy": "", 
                "rainy": "", 
                "sleet": "", 
                "snow": "s", 
                "wind": "", 
                "fog": "", 
                "partlycloudy": "", 
              } %}
             # this is a translation table to get day names in local language
             {% set days = {'Mon':'Mån','Tue':'Tis','Wed':'Ons','Thu':'Tors','Fri':'Fre','Sat':'Lör','Sun':'Sön'} %}

                {% for state in states.weather.smhi_home.attributes.forecast[1:6] -%}
               
                {{ days[as_timestamp(state.datetime)| timestamp_custom("%a")] }};{{state.templow}}-{{ state.temperature }}°C;{{ state.precipitation | replace('.', ',') }}mm;{{ weather[state.condition] }}#
                
                {%- endfor %}

This sensor creates this:

Tors;7-13°C;0,0mm;#Fre;7-14°C;1,5mm;#Lör;8-14°C;2,4mm;#Sön;10-12°C;1,8mm;#Mån;9-11°C;7,8mm;#	

In ESP-Home you add a text sensor:

text_sensor:
  - platform: homeassistant
    id: w_fivedays
    entity_id: sensor.weather_fivedays

The font:

font:
  - file: 'materialdesignicons-webfont.ttf'
    id: weather_font
    size: 49
    glyphs: [
      # Weather
      "", # mdi-weather-sunny
      "", # mdi-weather-night
      "", # mdi-weather-cloudy
      "", # mdi-weather-pouring
      "", # mdi-weather-snowy-rainy
      "s", # mdi-weather-snowy-heavy
      "", # mdi-weather-windy-variant
      "", # mdi-weather-fog
      "n", # mdi-weather-night-partly-cloudy
      "", # mdi-weather-partly-cloudy
      ]

And the display lambda:

display:
  - platform: waveshare_epaper
    cs_pin: 5
    dc_pin: 19
    busy_pin: 4
    reset_pin: 12
    model: 2.90in
    full_update_every: 15
    update_interval: 1s
    lambda: |-
          fivedays = id(w_fivedays).state;
          
          //ESP_LOGD("%s", fivedays.c_str());
          five.clear();
          
          int count = 0;
          int wx = 0; // start positio x
          int wy = 0; // start position y
          token = strtok (&fivedays[0],"#");
          // this while splits the string (I believe, I "found" the code)
          while (token != NULL)
          {
            five.push_back(token);
            token = strtok (NULL, "#");
          }
          // here we loop the days
          for ( std::string fiv : five ) {
            it.rectangle(0, wy, 128, 59);  // adds a border around the "day"
            it.rectangle(1, wy+1, 126, 57);
            
            str = "";
            str = fiv;
            //ESP_LOGD("test: ", "String to Vector: %s", str.c_str());
            v.clear();
            token = strtok (&str[0],";");
            while (token != NULL)
            {
              v.push_back(token);
              token = strtok (NULL, ";");
            }

            // this is the loop for each value in the "day"
            for ( std::string s : v ) {

              if(count == 0){
                // Day (Mon/Tue...)
                it.printf(wx +7, wy, id(my_font_small), "%s", s.c_str());
              }else if(count == 1){
                // Temperature 
                it.printf(wx +7, wy+18, id(my_font_small), "%s", s.c_str());
              }else if(count == 2){
                // Precipitation 
                it.printf(wx +7, wy+35, id(my_font_small), "%s", s.c_str());
              }else if(count == 3){
                // weather icon
                it.printf(123, wy+5, id(weather_font), TextAlign::TOP_RIGHT, "%s", s.c_str());
              }
               
              //ESP_LOGD("test: ", "String to Vector: %s", s.c_str());
              count += 1;
            }
            count = 0;
            wy += 59; // move down 59 pixels and output next day
          }

The code is not good in anyways and has lots of room for improvement. But it works.

1 Like