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.