But this is the display part:
display:
- platform: waveshare_epaper
model: 7.50in-bv2-rb
id: eink_display
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin:
number: GPIO25
inverted: True
reset_pin: GPIO26
reset_duration: 2ms
update_interval: never
rotation: 0°
lambda: |-
std::map<std::string, std::string> weather_icon_map
{
{"clear-night", "\U000F0594"},
{"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"}
};
std::map<std::string, std::string> car_icon_map
{
{ "power-plug", "\U000F06A5" },
{ "power-plug-outline", "\U000F1425" },
{ "power-plug-off-outline", "\U000F1424" },
{ "connection", "\U000F1616" },
{ "car-off", "\U000F0E1C" },
{ "battery", "\U000F0079" },
{ "battery-high", "\U000F12A3" },
{ "battery-medium", "\U000F12A2" },
{ "battery-low", "\U000F12A1" },
{ "battery-outline", "\U000F008E" },
{ "battery-charging-100", "\U000F0085" },
{ "battery-charging-high", "\U000F12A6" },
{ "battery-charging-medium", "\U000F12A5" },
{ "battery-charging-low", "\U000F12A4" },
{ "battery-charging-outline", "\U000F089F" },
{ "car-outline", "\U000F14ED" },
{ "lock-open-outline", "\U000F0340" },
{ "car-wash", "\U000F010E" },
{ "solar-power", "\U000F1A73" },
{ "car-clock", "\U000F1974" },
{ "bus-clock", "\U000F08CA" },
{ "train", "\U000F052C" }
};
std::map<std::string, int> d_w_s {
{ "Pui", 0 },
{ "Voord", 1 },
{ "Schuur", 2 },
{ "KeukenRm", 3 },
{ "L SKRm", 4 },
{ "R SKRm", 5 },
{ "JasRm", 6 },
{ "RiaRm", 7 },
{ "ZDRm", 8 },
{ "L DKRm", 9 },
{ "R DKRm", 10 },
{ "L SKRm W", 11 },
{ "R SKRm W", 12 },
{ "L DKRm W", 13 },
{ "R DKRm W", 14 },
{ "ZDSch L", 15 },
{ "ZDSch R", 16 },
{ "SKSch L", 17 },
{ "SKSch M", 18 },
{ "SKSch R", 19 },
{ "KeukenSch", 20 },
{ "Pui O", 21 },
{ "KeukenRm O", 22 },
{ "SKRm L O", 23 },
{ "SKRm R O", 24 },
{ "RiaRm O", 25 },
{ "JasRm O", 26 },
{ "ZDRm O", 27 },
{ "DKRm L O", 28 },
{ "DKRm R O", 29 },
{ "Pui S", 30 },
{ "KeukenRm S", 31 },
{ "SKRm L S", 32 },
{ "SKRm R S", 33 },
{ "RiaRm S", 34 },
{ "JasRm S", 35 },
{ "ZDRm S", 36 },
{ "DKRm L S", 37 },
{ "DKRm R S", 38 },
{ "Rm OA L SKSch", 39 },
{ "Rm OA R SKSch", 40 },
{ "Rm OA ZDSch", 41 },
{ "RolSch WGrens", 42 },
{ "KnikSch WGrens", 43 },
{ "L DkSch", 44 },
{ "R DkSch", 45 },
{ "Car D", 46 },
{ "Car W", 47 },
{ "FLock", 48 }
};
it.line(0, 468, 799, 468); // bottom line
if (id(initial_data_received) == false) {
id(refreshes_skipped) = 100;
it.printf(390, 234, id(font_small_bold), C_RED, TextAlign::TOP_CENTER, "WACHT OP GEGEVENS...");
} else {
std::string stats = (id(statussen).state + "???????????????????????????????????????????????????????").c_str(); // make sure at least as many ? as needed
// windows and shutters, house outline
int hx = 400, hy = 20, w=22, h=22, g=6, s=4;
it.line(hx + 1 * w + 1 * g, hy + 7 * h + 4 * g, hx + 5 * w + 6 * g, hy + 7 * h + 4 * g); // vloer
it.line(hx + 1 * w + 1 * g, hy + 1 * h + 1 * g, hx + 1 * w + 1 * g, hy + 7 * h + 4 * g); // achtergevel
it.line(hx + 5 * w + 6 * g, hy + 0 * h + 0 * g, hx + 5 * w + 6 * g, hy + 7 * h + 4 * g); // voorgevel
it.line(hx + 1 * w + 1 * g, hy + 1 * h + 1 * g, hx + 5 * w + 6 * g, hy + 0 * h + 0 * g); // dak
it.line(hx + 1 * w + 1 * g - 1, hy + 7 * h + 4 * g - 1, hx + 5 * w + 6 * g + 1, hy + 7 * h + 4 * g - 1); // vloer
it.line(hx + 1 * w + 1 * g - 1, hy + 1 * h + 1 * g - 1, hx + 1 * w + 1 * g - 1, hy + 7 * h + 4 * g + 1); // achtergevel
it.line(hx + 5 * w + 6 * g + 1, hy + 0 * h + 0 * g - 1, hx + 5 * w + 6 * g + 1, hy + 7 * h + 4 * g + 1); // voorgevel
it.line(hx + 1 * w + 1 * g - 1, hy + 1 * h + 1 * g - 1, hx + 5 * w + 6 * g + 1, hy + 0 * h + 0 * g - 1); // dak
it.rectangle(hx + 1 * w + 2 * g + 0, hy + 1 * h + 2 * g, w, 1.5 * h, stats[d_w_s["DKRm L O"]] == 'O' ? C_RED : COLOR_ON); // linker dakkapel
it.rectangle(hx + 2 * w + 3 * g + 0, hy + 1 * h + 2 * g, w, 1.5 * h, stats[d_w_s["DKRm R O"]] == 'O' ? C_RED : COLOR_ON); // rechter dakkapel
it.rectangle(hx + 4 * w + 5 * g + 0, hy + 1 * h + 2 * g, w, 1.5 * h, stats[d_w_s["ZDRm O"]] == 'O' ? C_RED : COLOR_ON); // studeerkamer
it.rectangle(hx + 1 * w + 2 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["JasRm O"]] == 'O' ? C_RED : COLOR_ON); // jasper
it.rectangle(hx + 2 * w + 3 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["RiaRm O"]] == 'O' ? C_RED : COLOR_ON); // rianne
it.rectangle(hx + 3 * w + 4 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["SKRm L O"]] == 'O' ? C_RED : COLOR_ON); // slaapkamer links
it.rectangle(hx + 4 * w + 5 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["SKRm R O"]] == 'O' ? C_RED : COLOR_ON); // slaapkamer rechts
it.rectangle(hx + 1 * w + 2 * g + 0, hy + 5 * h + 4 * g, w, 2.0 * h, stats[d_w_s["Pui O"]] == 'O' ? C_RED : COLOR_ON); // schuifpui
it.rectangle(hx + 3 * w + 4 * g + 0, hy + 5 * h + 4 * g, w, 1.0 * h, stats[d_w_s["KeukenRm O"]] == 'O' ? C_RED : COLOR_ON); // keukenraam
it.rectangle(hx + 4 * w + 5 * g + 0, hy + 5 * h + 4 * g, w, 2.0 * h); // voordeur
it.rectangle(hx + 0 * w + 0 * g - 1, hy + 5 * h + 4 * g, w, 2.0 * h); // schuurdeur
it.circle(hx + 0.5 * w - 0 * g - 0.5 * s, hy + 1 * h + 2 * g, s); // linker dakscherm
it.circle(hx + 1.0 * w - 0 * g - 1.0 * s, hy + 1 * h + 2 * g, s); // rechter dakscherm
it.circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 1 * h + 2 * g, s); // studeerkamerscherm links
it.circle(hx + 5.5 * w + 7 * g + 0.5 * s, hy + 1 * h + 2 * g, s); // studeerkamerscherm rechts
it.circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 3 * h + 3 * g, s); // slaapkamerscherm links
it.circle(hx + 5.5 * w + 7 * g + 0.5 * s, hy + 3 * h + 3 * g, s); // slaapkamerscherm midden
it.circle(hx + 6.0 * w + 7 * g + 0.0 * s, hy + 3 * h + 3 * g, s); // slaapkamerscherm rechts
it.circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 5 * h + 4 * g, s); // keukenscherm
if (stats[d_w_s["RolSch WGrens"]] == 'W') {
it.filled_circle(hx + 0.5 * w - 0 * g - 0.5 * s, hy + 1 * h + 2 * g, s, C_RED); // linker dakscherm
it.filled_circle(hx + 1.0 * w - 0 * g - 1.0 * s, hy + 1 * h + 2 * g, s, C_RED); // rechter dakscherm
it.filled_circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 1 * h + 2 * g, s, C_RED); // studeerkamerscherm links
it.filled_circle(hx + 5.5 * w + 7 * g + 0.5 * s, hy + 1 * h + 2 * g, s, C_RED); // studeerkamerscherm rechts
it.filled_circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 3 * h + 3 * g, s, C_RED); // slaapkamerscherm links
it.filled_circle(hx + 5.5 * w + 7 * g + 0.5 * s, hy + 3 * h + 3 * g, s, C_RED); // slaapkamerscherm midden
it.filled_circle(hx + 6.0 * w + 7 * g + 0.0 * s, hy + 3 * h + 3 * g, s, C_RED); // slaapkamerscherm rechts
}
if (stats[d_w_s["KnikSch WGrens"]] == 'W')
it.filled_circle(hx + 5.0 * w + 7 * g + 1.0 * s, hy + 5 * h + 4 * g, s, C_RED); // keukenscherm
if (stats[d_w_s["L DKRm W"]] == 'O' || stats[d_w_s["L DKRm"]] == 'O') // linker dakkapel
it.filled_rectangle(hx + 1 * w + 2 * g + 0, hy + 1 * h + 2 * g, w, (stats[d_w_s["L DKRm W"]] == 'O' ? 1.5 : 0.5) * h, stats[d_w_s["DKRm L S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["DKRm L O"]] == 'O')
it.filled_circle(hx + 1.5 * w + 2 * g + 0, hy + 1.75 * h + 2 * g, w / 2 - s, C_RED);
if (stats[d_w_s["R DKRm W"]] == 'O' || stats[d_w_s["R DKRm"]] == 'O') // rechter dakkapel
it.filled_rectangle(hx + 2 * w + 3 * g + 0, hy + 1 * h + 2 * g, w, (stats[d_w_s["R DKRm W"]] == 'O' ? 1.5 : 0.5) * h, stats[d_w_s["DKRm R S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["DKRm R O"]] == 'O')
it.filled_circle(hx + 2.5 * w + 3 * g + 0, hy + 1.75 * h + 2 * g, w / 2 - s, C_RED);
if (stats[d_w_s["ZDRm"]] == 'O') // studeerkamer
it.filled_rectangle(hx + 4 * w + 5 * g + 0, hy + 1 * h + 2 * g, w, 1.5 * h, stats[d_w_s["ZDRm S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["ZDRm O"]] == 'O')
it.filled_circle(hx + 4.5 * w + 5 * g + 0, hy + 1.75 * h + 2 * g, w / 2 - s, C_RED);
if (stats[d_w_s["JasRm"]] == 'O') // jasper
it.filled_rectangle(hx + 1 * w + 2 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["JasRm S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["JasRm O"]] == 'O')
it.filled_circle(hx + 1.5 * w + 2 * g + 0, hy + 3.75 * h + 3 * g, w / 2 - s, C_RED);
if (stats[d_w_s["RiaRm"]] == 'O') // rianne
it.filled_rectangle(hx + 2 * w + 3 * g + 0, hy + 3 * h + 3 * g, w, 1.5 * h, stats[d_w_s["RiaRm S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["RiaRm O"]] == 'O')
it.filled_circle(hx + 2.5 * w + 3 * g + 0, hy + 3.75 * h + 3 * g, w / 2 - s, C_RED);
if (stats[d_w_s["L SKRm W"]] == 'O' || stats[d_w_s["L SKRm"]] == 'O') // slaapkamer links
it.filled_rectangle(hx + 3 * w + 4 * g + 0, hy + 3 * h + 3 * g, w, (stats[d_w_s["L SKRm W"]] == 'O' ? 1.5 : 0.5) * h, stats[d_w_s["SKRm L S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["SKRm L O"]] == 'O')
it.filled_circle(hx + 3.5 * w + 4 * g + 0, hy + 3.75 * h + 3 * g, w / 2 - s, C_RED);
if (stats[d_w_s["R SKRm W"]] == 'O' || stats[d_w_s["R SKRm"]] == 'O') // slaapkamer rechts
it.filled_rectangle(hx + 4 * w + 5 * g + 0, hy + 3 * h + 3 * g, w, (stats[d_w_s["R SKRm W"]] == 'O' ? 1.5 : 0.5) * h, stats[d_w_s["SKRm R S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["SKRm R O"]] == 'O')
it.filled_circle(hx + 4.5 * w + 5 * g + 0, hy + 3.75 * h + 3 * g, w / 2 - s, C_RED);
if (stats[d_w_s["Pui"]] == 'O') // schuifpui
it.filled_rectangle(hx + 1 * w + 2 * g + 0, hy + 5 * h + 4 * g, w, 2.0 * h, stats[d_w_s["Pui S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["Pui O"]] == 'O')
it.filled_circle(hx + 1.5 * w + 2 * g + 0, hy + 5.75 * h + 4 * g, w / 2 - s, C_RED);
if (stats[d_w_s["KeukenRm"]] == 'O') // keukenraam
it.filled_rectangle(hx + 3 * w + 4 * g + 0, hy + 5 * h + 4 * g, w, 1.0 * h, stats[d_w_s["KeukenRm S"]] == 'S' ? C_RED : COLOR_ON);
if (stats[d_w_s["KeukenRm O"]] == 'O')
it.filled_circle(hx + 3.5 * w + 4 * g + 0, hy + 5.5 * h + 4 * g, w / 2 - s, C_RED);
if (stats[d_w_s["Voord"]] == 'O') // voordeur
it.filled_rectangle(hx + 4 * w + 5 * g + 0, hy + 5 * h + 4 * g, w, 2.0 * h);
if (stats[d_w_s["FLock"]] != '-') { // voordeur
it.filled_circle(hx + 4.5 * w + 5 * g + 0, hy + 6 * h + 4 * g, w / 2 - s, stats[d_w_s["FLock"]] == 'L' ? (stats[d_w_s["Voord"]] == 'O' ? C_WHT : COLOR_ON) : C_RED);
it.filled_circle(hx + 4.5 * w + 5 * g + 0, hy + 6 * h + 4 * g, w / 2 - s * 2, stats[d_w_s["Voord"]] == 'O' ? C_RED : C_WHT);
}
if (stats[d_w_s["Schuur"]] == 'O') // schuurdeur
it.filled_rectangle(hx + 0 * w + 0 * g - 1, hy + 5 * h + 4 * g, w, 2.0 * h);
if (stats[d_w_s["L DkSch"]] != '-') // linker dakscherm
it.filled_rectangle(hx + 0.5 * w - 0 * g - 0.5 * s - 1, hy + 1 * h + 2 * g, s, 1.5 * h, stats[d_w_s["L DkSch"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["R DkSch"]] != '-') // rechter dakscherm
it.filled_rectangle(hx + 1.0 * w - 0 * g - 1.0 * s - 1, hy + 1 * h + 2 * g, s, 1.5 * h, stats[d_w_s["R DkSch"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["ZDSch L"]] != '-') // studeerkamerscherm links
it.filled_rectangle(hx + 5.0 * w + 7 * g + 0.0 * s + 1, hy + 1 * h + 2 * g, s, 1.5 * h, stats[d_w_s["ZDSch L"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["ZDSch R"]] != '-') // studeerkamerscherm rechts
it.filled_rectangle(hx + 5.5 * w + 7 * g - 0.0 * s + 1, hy + 1 * h + 2 * g, s, 1.5 * h, stats[d_w_s["ZDSch R"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["SKSch L"]] != '-') // slaapkamerscherm links
it.filled_rectangle(hx + 5.0 * w + 7 * g + 0.0 * s + 1, hy + 3 * h + 3 * g, s, 1.5 * h, stats[d_w_s["SKSch L"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["SKSch M"]] != '-') // slaapkamerscherm midden
it.filled_rectangle(hx + 5.5 * w + 7 * g - 0.5 * s + 1, hy + 3 * h + 3 * g, s, 1.5 * h, stats[d_w_s["SKSch M"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["SKSch R"]] != '-') // slaapkamerscherm rechts
it.filled_rectangle(hx + 6.0 * w + 7 * g - 1.0 * s + 1, hy + 3 * h + 3 * g, s, 1.5 * h, stats[d_w_s["SKSch R"]] == 'C' ? COLOR_ON : C_RED);
if (stats[d_w_s["KeukenSch"]] != '-') { // keukenscherm
it.filled_rectangle(hx + 5.0 * w + 7 * g + 0.5 * s + 0.0 * h + 1, hy + 5 * h + 4 * g + 0 + 1, 0.5 * h, s, stats[d_w_s["KeukenSch"]] == 'C' ? COLOR_ON : C_RED);
it.filled_rectangle(hx + 5.0 * w + 7 * g + 0.5 * s + 0.5 * h + 1, hy + 5 * h + 4 * g + 1 + 1, 0.5 * h, s, stats[d_w_s["KeukenSch"]] == 'C' ? COLOR_ON : C_RED);
it.filled_rectangle(hx + 5.0 * w + 7 * g + 0.5 * s + 1.0 * h + 1, hy + 5 * h + 4 * g + 2 + 1, 0.5 * h, s, stats[d_w_s["KeukenSch"]] == 'C' ? COLOR_ON : C_RED);
}
// Weather Section
int wo_x = 50, wo_y = 50, ho_x = 790, hsp = 100, vsp1 = 60, vsp2 = 97, vsp3 = 140;
it.printf(wo_x + hsp * 0.50, wo_y, id(font_mdi_large), C_RED, TextAlign::CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
it.printf(wo_x + hsp * 2.85, wo_y, id(font_large_bold), id(weather_temperature).state < 0 ? C_RED : COLOR_ON, TextAlign::CENTER_RIGHT, "%1.1f", id(weather_temperature).state);
it.printf(wo_x + hsp * 3.30, wo_y + 8, id(font_medium_bold), id(weather_temperature).state < 0 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "°C");
it.printf(wo_x, wo_y + vsp1, id(font_smaller_bold), TextAlign::CENTER, "%s", id(weather_timestamp_0).state.c_str());
it.printf(wo_x, wo_y + vsp2, id(font_mdi_medium), C_RED, TextAlign::CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
it.printf(wo_x, wo_y + vsp3, id(font_small_bold), TextAlign::CENTER, "%1.0f°C", id(weather_temperature_0).state);
it.printf(wo_x + hsp, wo_y + vsp1, id(font_smaller_bold), TextAlign::CENTER, "%s", id(weather_timestamp_1).state.c_str());
it.printf(wo_x + hsp, wo_y + vsp2, id(font_mdi_medium), C_RED, TextAlign::CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
it.printf(wo_x + hsp, wo_y + vsp3, id(font_small_bold), TextAlign::CENTER, "%1.0f°C", id(weather_temperature_1).state);
it.printf(wo_x + hsp * 2, wo_y + vsp1, id(font_smaller_bold), TextAlign::CENTER, "%s", id(weather_timestamp_2).state.c_str());
it.printf(wo_x + hsp * 2, wo_y + vsp2, id(font_mdi_medium), C_RED, TextAlign::CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
it.printf(wo_x + hsp * 2, wo_y + vsp3, id(font_small_bold), TextAlign::CENTER, "%1.0f°C", id(weather_temperature_2).state);
it.printf(wo_x + hsp * 3, wo_y + vsp1, id(font_smaller_bold), TextAlign::CENTER, "%s", id(weather_timestamp_3).state.c_str());
it.printf(wo_x + hsp * 3, wo_y + vsp2, id(font_mdi_medium), C_RED, TextAlign::CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
it.printf(wo_x + hsp * 3, wo_y + vsp3, id(font_small_bold), TextAlign::CENTER, "%1.0f°C", id(weather_temperature_3).state);
// rain graph
std::string gdata = id(rain_graph).state;
char *token = strtok (&gdata[0],";");
std::string t1 = str_until(token == NULL ? "??:??" : token,';'); token = strtok(NULL, ";");
std::string t2 = str_until(token == NULL ? "??:??" : token,';'); token = strtok(NULL, ";");
std::string t3 = str_until(token == NULL ? "??:??" : token,';'); token = strtok(NULL, ";");
std::string t4 = str_until(token == NULL ? "??:??" : token,';'); token = strtok(NULL, ";");
std::string t5 = str_until(token == NULL ? "??:??" : token,';'); token = strtok(NULL, ";");
auto g_low = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f); token = strtok(NULL, ";");
auto g_med = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f); token = strtok(NULL, ";");
auto g_hgh = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f); token = strtok(NULL, ";");
auto g_max = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f) * 1.1f; token = strtok(NULL, ";");
int g_x = 11, g_y = 250, g_w = 5, g_h = 80, g_c = 0, g_t = 5;
it.filled_rectangle(g_x, g_y + g_h - 1, 73 * g_w, 2, COLOR_ON); // x-axis
it.filled_rectangle(g_x - 1, g_y, 2, g_h, COLOR_ON); // y-axis
float prev = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f) * g_h / g_max; token = strtok(NULL, ";");
if (prev != 0) it.filled_rectangle(g_x + g_c, g_y + g_h - prev, g_w, prev, C_RED);
g_c += g_w;
while (token != NULL) {
auto g_r = parse_number<float>(str_until(token == NULL ? "0.1" : token,';')).value_or(0.0f) * g_h / g_max; token = strtok(NULL, ";");
float itv = (2 * prev + g_r) / 3;
if (itv != 0) it.filled_rectangle(g_x + g_c, g_y + g_h - itv, g_w, itv, C_RED);
g_c += g_w;
itv = (prev + 2 * g_r) / 3;
if (itv != 0) it.filled_rectangle(g_x + g_c, g_y + g_h - itv, g_w, itv, C_RED);
g_c += g_w;
if (g_r != 0) it.filled_rectangle(g_x + g_c, g_y + g_h - g_r, g_w, g_r, C_RED);
g_c += g_w;
prev = g_r;
}
it.rectangle(g_x - 1, g_y + g_h - g_hgh * g_h / g_max, g_c, 1); // high
it.rectangle(g_x - 1, g_y + g_h - g_med * g_h / g_max, g_c, 1); // medium
it.rectangle(g_x - 1, g_y + g_h - g_low * g_h / g_max, g_c, 1); // low
it.rectangle(g_x - 1, g_y + g_h, g_c, 1); // bottom
it.printf(g_x + 0.00 * g_c + 0, g_y + g_h + g_t, id(font_tiny_book), COLOR_ON, TextAlign::TOP_LEFT, "%s", t1.c_str());
it.printf(g_x + 0.25 * g_c + 7, g_y + g_h + g_t, id(font_tiny_book), COLOR_ON, TextAlign::TOP_CENTER, "%s", t2.c_str()); // smuggle bit more right because first time differs
it.printf(g_x + 0.50 * g_c + 0, g_y + g_h + g_t, id(font_tiny_book), COLOR_ON, TextAlign::TOP_CENTER, "%s", t3.c_str());
it.printf(g_x + 0.75 * g_c - 7, g_y + g_h + g_t, id(font_tiny_book), COLOR_ON, TextAlign::TOP_CENTER, "%s", t4.c_str());
it.printf(g_x + 1.00 * g_c + 0, g_y + g_h + g_t, id(font_tiny_book), COLOR_ON, TextAlign::TOP_RIGHT, "%s", t5.c_str()); // smuggle bit more left because last time differs
// Car Section
it.printf(ho_x - hsp * 0.45, wo_y, id(font_large_bold), id(room_temperature).state < 0 ? C_RED : COLOR_ON, TextAlign::CENTER_RIGHT, "%1.1f", id(room_temperature).state);
it.printf(ho_x - hsp * 0.00, wo_y + 8, id(font_medium_bold), id(room_temperature).state < 0 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "°C");
it.printf(ho_x - hsp * 0.45, wo_y + vsp2 + 0, id(font_large_book), id(car_battery_perc).state <= 45 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "%1.0f", id(car_battery_perc).state);
it.printf(ho_x - hsp * 0.00, wo_y + vsp2 - 5, id(font_medium_bold), id(car_battery_perc).state <= 45 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "%%");
it.printf(ho_x - hsp * 0.45, wo_y + vsp3 + 19, id(font_large_book), id(car_km_range).state < 100 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "%1.0f", id(car_km_range).state);
it.printf(ho_x - hsp * 0.00, wo_y + vsp3 + 14, id(font_small_bold), id(car_km_range).state < 100 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "km");
int b_y = 225, b_x = 10, b_h = 8, l_h = 2, b_l = 800 - 2 * b_x, t_h = 12,
b_f = b_l * id(car_battery_perc).state / 100, b_t = b_l * id(car_target_perc).state / 100;
it.rectangle(b_x, b_y + (b_h - l_h) / 2, b_l, l_h, id(car_battery_perc).state <= 45 ? COLOR_ON : C_RED); // thin line
it.filled_rectangle(b_x + (b_l - b_f) / 2, b_y, b_f, b_h, id(car_battery_perc).state <= 45 ? C_RED : COLOR_ON); // battery percentage bar
it.filled_rectangle(b_x + (b_l - b_t) / 2, b_y + (b_h - t_h) / 2, l_h, t_h, id(car_battery_perc).state <= 45 ? COLOR_ON : C_RED); // target perc markers
it.filled_rectangle(b_x + (b_l + b_t) / 2, b_y + (b_h - t_h) / 2, l_h, t_h, id(car_battery_perc).state <= 45 ? COLOR_ON : C_RED);
std::string cstate = id(car_charge_status).state.c_str(), bat = "", car = "";
Color c_col = COLOR_ON, b_col = COLOR_ON;
if (cstate == "?") { bat = "connection"; b_col = C_RED; }
else if (cstate == "Laden") {
if (id(car_battery_perc).state <= 35) { bat = "battery-charging-outline"; b_col = C_RED; }
else if (id(car_battery_perc).state <= 45) { bat = "battery-charging-low"; b_col = C_RED; }
else if (id(car_battery_perc).state <= 55) { bat = "battery-charging-low"; }
else if (id(car_battery_perc).state <= 75) { bat = "battery-charging-medium"; }
else if (id(car_battery_perc).state <= 95) { bat = "battery-charging-high"; }
else bat = "battery-charging-100";
} else if (cstate == "Opgeladen") {
bat = "power-plug";
// if (id(car_battery_perc).state <= 35) { bat = "battery-outline"; b_col = C_RED; }
// else if (id(car_battery_perc).state <= 45) { bat = "battery-low"; b_col = C_RED; }
// else if (id(car_battery_perc).state <= 55) { bat = "battery-low"; }
// else if (id(car_battery_perc).state <= 75) { bat = "battery-medium"; }
// else if (id(car_battery_perc).state <= 95) { bat = "battery-high"; }
// else bat = "battery";
} else if (cstate == "Verbroken") { bat = "connection"; b_col = C_RED; }
else if (cstate == "Aangesloten") { bat = "power-plug-outline"; }
if (stats[d_w_s["Car D"]] == 'O') { car = "lock-open-outline"; c_col = C_RED; }
else if (stats[d_w_s["Car D"]] == 'O') { car = "car-wash"; c_col = C_RED; }
if (bat != "")
it.printf(ho_x - hsp * 1.5, wo_y + vsp2 - 5, id(font_mdi_title), b_col, TextAlign::BOTTOM_RIGHT, "%s", car_icon_map[bat].c_str());
if (car != "")
it.printf(ho_x - hsp * 1.5, wo_y + vsp3 + 14, id(font_mdi_title), c_col, TextAlign::BOTTOM_RIGHT, "%s", car_icon_map[car].c_str());
// calendar
int cal_x = 405, cal_y = 255, cal_dx = 30, cl = 0;
if (id(apt_gezin).state != "")
it.printf(cal_x, cal_y + cl++ * cal_dx, id(font_smaller_bold), TextAlign::TOP_LEFT, "%s", id(apt_gezin).state.c_str());
if (id(apt_edwin).state != "")
it.printf(cal_x, cal_y + cl++ * cal_dx, id(font_smaller_bold), TextAlign::TOP_LEFT, "%s", id(apt_edwin).state.c_str());
if (id(apt_fleur).state != "")
it.printf(cal_x, cal_y + cl++ * cal_dx, id(font_smaller_bold), TextAlign::TOP_LEFT, "%s", id(apt_fleur).state.c_str());
if (id(apt_rianne).state != "")
it.printf(cal_x, cal_y + cl++ * cal_dx, id(font_smaller_bold), TextAlign::TOP_LEFT, "%s", id(apt_rianne).state.c_str());
if (id(apt_jasper).state != "")
it.printf(cal_x, cal_y + cl++ * cal_dx, id(font_smaller_bold), TextAlign::TOP_LEFT, "%s", id(apt_jasper).state.c_str());
it.filled_rectangle(790, cal_y, 10, 5 * cal_dx, C_WHT); // replace by clipping
// Solar Section
int sol_y = (cal_y + cl * cal_dx) > 350 ? 430 : 420;
float prod = id(solar_production_today).state, fcast = id(solar_forecast_today).state;
it.printf(prod >= 20 ? 385 : 390, sol_y - 2, id(font_mdi_title), C_RED, TextAlign::BOTTOM_LEFT, "%s", car_icon_map["solar-power"].c_str());
it.printf(520, sol_y + 10, id(font_large_bold), COLOR_ON, TextAlign::BOTTOM_CENTER, prod > 0.005 && prod < 0.1 ? "%1.2f" : "%1.1f", prod);
it.printf(598, sol_y + 5, id(font_large_book), COLOR_ON, TextAlign::BOTTOM_LEFT, "/");
it.printf(ho_x - hsp * 0.60, sol_y + 5, id(font_large_book), COLOR_ON, TextAlign::BOTTOM_RIGHT, "%1.1f", fcast);
it.printf(ho_x + hsp * 0.05, sol_y, id(font_small_bold), COLOR_ON, TextAlign::BOTTOM_RIGHT, "kWh");
// travel section
it.printf(10, sol_y - 2, id(font_mdi_title), C_RED, TextAlign::BOTTOM_LEFT, "%s", car_icon_map["car-clock"].c_str());
it.printf(145, sol_y + 5, id(font_large_book), id(reistijd_leo_kanner).state >= 40 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "%1.0f", id(reistijd_leo_kanner).state);
it.printf(150, sol_y, id(font_small_bold), COLOR_ON, TextAlign::BOTTOM_LEFT, "min");
it.printf(10, 458, id(font_small_bold), TextAlign::BOTTOM_LEFT, "%s", id(next_meal).state.c_str());
char str[17];
time_t currTime = id(homeassistant_time).now().timestamp;
strftime(str, sizeof(str), "%H:%M", localtime(&currTime));
it.printf(798, 463, id(font_tiny_book), id(refreshes_skipped) >= 15 ? C_RED : COLOR_ON, TextAlign::BOTTOM_RIGHT, "Laatste update: %s", str);
}