weather forecast enhancements

This commit is contained in:
Nic Limper
2025-03-20 13:43:21 +01:00
parent 107764c6be
commit 047230de25
4 changed files with 87 additions and 79 deletions

View File

@@ -877,6 +877,53 @@ const String getWeatherIcon(const uint8_t id, const bool isNight = false) {
return weatherIcons[id];
}
void drawWeatherContent(JsonDocument &doc, JsonDocument &loc, TFT_eSprite &spr, JsonObject &cfgobj, imgParam &imageParams, bool isForecast = false) {
const auto &currentWeather = doc["current_weather"];
const double temperature = currentWeather["temperature"].as<double>();
float windspeed = currentWeather["windspeed"].as<float>();
int windval = 0;
const int winddirection = currentWeather["winddirection"].as<int>();
const bool isNight = currentWeather["is_day"].as<int>() == 0;
uint8_t weathercode = currentWeather["weathercode"].as<int>();
if (weathercode > 40) weathercode -= 40;
const uint8_t beaufort = windSpeedToBeaufort(windspeed);
if (cfgobj["units"] != "1") {
windval = beaufort;
} else {
windval = int(windspeed);
}
if (!isForecast) {
const auto &location = loc["location"];
drawString(spr, cfgobj["location"], location[0], location[1], location[2]);
}
const auto &wind = isForecast ? loc["currentwind"] : loc["wind"];
drawString(spr, String(windval), wind[0], wind[1], wind[2], TR_DATUM, (beaufort > 4 ? imageParams.highlightColor : TFT_BLACK));
char tmpOutput[5];
dtostrf(temperature, 2, 1, tmpOutput);
const auto &temp = loc["temp"];
String temperatureStr = String(tmpOutput);
if (temp[3] && temp[3] == 1) {
temperatureStr += (cfgobj["units"] == "1") ? "°" : "°";
}
drawString(spr, temperatureStr, temp[0], temp[1], temp[2], TL_DATUM, (temperature < 0 ? imageParams.highlightColor : TFT_BLACK));
const int iconcolor = (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 96 || weathercode == 99)
? imageParams.highlightColor
: TFT_BLACK;
const auto &icon = isForecast ? loc["currenticon"] : loc["icon"];
drawString(spr, getWeatherIcon(weathercode, isNight), icon[0], icon[1], "/fonts/weathericons.ttf", icon[3], iconcolor, icon[2]);
const auto &dir = loc["dir"];
drawString(spr, windDirectionIcon(winddirection), dir[0], dir[1], "/fonts/weathericons.ttf", TC_DATUM, TFT_BLACK, dir[2]);
if (weathercode > 10) {
const auto &umbrella = loc["umbrella"];
drawString(spr, "\uf084", umbrella[0], umbrella[1], "/fonts/weathericons.ttf", TC_DATUM, imageParams.highlightColor, umbrella[2]);
}
}
void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo, imgParam &imageParams) {
wsLog("get weather");
@@ -895,69 +942,14 @@ void drawWeather(String &filename, JsonObject &cfgobj, const tagRecord *taginfo,
if (!success) {
return;
}
const auto &currentWeather = doc["current_weather"];
const double temperature = currentWeather["temperature"].as<double>();
float windspeed = currentWeather["windspeed"].as<float>();
int windval = 0;
const int winddirection = currentWeather["winddirection"].as<int>();
const bool isNight = currentWeather["is_day"].as<int>() == 0;
uint8_t weathercode = currentWeather["weathercode"].as<int>();
if (weathercode > 40) weathercode -= 40;
const uint8_t beaufort = windSpeedToBeaufort(windspeed);
if (cfgobj["units"] != "1") {
windval = beaufort;
} else {
windval = int(windspeed);
}
doc.clear();
if (taginfo->hwType == SOLUM_SEG_UK) {
const String weatherText[] = {"sun", "sun", "sun", "CLDY", "CLDY", "FOG", "", "", "FOG", "", "",
"DRZL", "", "DRZL", "", "DRZL", "ice", "ice", "", "", "",
"rain", "", "rain", "", "rain", "ice", "ice", "", "", "",
"SNOW", "", "SNOW", "", "SNOW", "", "SNOW", "", "", "rain",
"rain", "rain", "", "", "SNOW", "SNOW", "", "", "", "",
"", "", "", "", "STRM", "HAIL", "", "", "HAIL"};
if (temperature < -9.9) {
sprintf(imageParams.segments, "%3d^%2d%-4.4s", static_cast<int>(temperature), windval, weatherText[weathercode].c_str());
imageParams.symbols = 0x00;
} else {
sprintf(imageParams.segments, "%3d^%2d%-4.4s", static_cast<int>(temperature * 10), windval, weatherText[weathercode].c_str());
imageParams.symbols = 0x04;
}
return;
}
getTemplate(doc, 4, taginfo->hwType);
JsonDocument loc;
getTemplate(loc, 4, taginfo->hwType);
TFT_eSprite spr = TFT_eSprite(&tft);
tft.setTextWrap(false, false);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
const auto &location = doc["location"];
drawString(spr, cfgobj["location"], location[0], location[1], location[2]);
const auto &wind = doc["wind"];
drawString(spr, String(windval), wind[0], wind[1], wind[2], TR_DATUM, (beaufort > 4 ? imageParams.highlightColor : TFT_BLACK));
char tmpOutput[5];
dtostrf(temperature, 2, 1, tmpOutput);
const auto &temp = doc["temp"];
drawString(spr, String(tmpOutput), temp[0], temp[1], temp[2], TL_DATUM, (temperature < 0 ? imageParams.highlightColor : TFT_BLACK));
const int iconcolor = (weathercode == 55 || weathercode == 65 || weathercode == 75 || weathercode == 82 || weathercode == 86 || weathercode == 95 || weathercode == 96 || weathercode == 99)
? imageParams.highlightColor
: TFT_BLACK;
const auto &icon = doc["icon"];
drawString(spr, getWeatherIcon(weathercode, isNight), icon[0], icon[1], "/fonts/weathericons.ttf", icon[3], iconcolor, icon[2]);
const auto &dir = doc["dir"];
drawString(spr, windDirectionIcon(winddirection), dir[0], dir[1], "/fonts/weathericons.ttf", TC_DATUM, TFT_BLACK, dir[2]);
if (weathercode > 10) {
const auto &umbrella = doc["umbrella"];
drawString(spr, "\uf084", umbrella[0], umbrella[1], "/fonts/weathericons.ttf", TC_DATUM, imageParams.highlightColor, umbrella[2]);
}
drawWeatherContent(doc, loc, spr, cfgobj, imageParams);
spr2buffer(spr, filename, imageParams);
spr.deleteSprite();
@@ -976,7 +968,7 @@ void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo
}
JsonDocument doc;
const bool success = util::httpGetJson("https://api.open-meteo.com/v1/forecast?latitude=" + lat + "&longitude=" + lon + "&daily=weathercode,temperature_2m_max,temperature_2m_min,precipitation_sum,windspeed_10m_max,winddirection_10m_dominant&windspeed_unit=ms&timeformat=unixtime&timezone=" + tz + units, doc, 5000);
const bool success = util::httpGetJson("https://api.open-meteo.com/v1/forecast?latitude=" + lat + "&longitude=" + lon + "&daily=weathercode,temperature_2m_max,temperature_2m_min,precipitation_sum,windspeed_10m_max,winddirection_10m_dominant&current_weather=true&windspeed_unit=ms&timeformat=unixtime&timezone=" + tz + units, doc, 5000);
if (!success) {
return;
}
@@ -988,6 +980,8 @@ void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo
getTemplate(loc, 8, taginfo->hwType);
initSprite(spr, imageParams.width, imageParams.height, imageParams);
if (loc["temp"]) drawWeatherContent(doc, loc, spr, cfgobj, imageParams, true);
const auto &location = loc["location"];
drawString(spr, cfgobj["location"], location[0], location[1], location[2], TL_DATUM, TFT_BLACK);
const auto &daily = doc["daily"];
@@ -1039,7 +1033,7 @@ void drawForecast(String &filename, JsonObject &cfgobj, const tagRecord *taginfo
drawString(spr, String(tmin) + " ", dag * column1 + day[0].as<int>(), day[4], day[2], TR_DATUM, (tmin < 0 ? imageParams.highlightColor : TFT_BLACK));
drawString(spr, String(" ") + String(tmax), dag * column1 + day[0].as<int>(), day[4], day[2], TL_DATUM, (tmax < 0 ? imageParams.highlightColor : TFT_BLACK));
drawString(spr, String(wind), dag * column1 + column1 - 10, day[3], day[2], TR_DATUM, (beaufort > 5 ? imageParams.highlightColor : TFT_BLACK));
drawString(spr, " " + String(wind), dag * column1 + column1 / 2, day[3], day[2], TL_DATUM, (beaufort > 5 ? imageParams.highlightColor : TFT_BLACK));
if (dag > 0) {
for (int i = loc["line"][0]; i < loc["line"][1]; i += 3) {
spr.drawPixel(dag * column1, i, TFT_BLACK);

View File

@@ -1,5 +1,5 @@
{
"version": 3,
"version": 4,
"name": "M3 4.3\"",
"width": 522,
"height": 152,
@@ -31,7 +31,7 @@
"day": [ 37, 20, "fonts/twcondensed20", 41, 105 ],
"rain": [ 34, 130 ],
"icon": [ 30, 55, 30 ],
"wind": [ 18, 26 ],
"wind": [ 27, 26 ],
"line": [ 20, 150 ]
},
"9": {

View File

@@ -1,5 +1,5 @@
{
"version": 2,
"version": 3,
"name": "M3 2.9\"",
"width": 384,
"height": 168,
@@ -30,14 +30,22 @@
"cols": [ 1, 157, 16, "glasstown_nbp_tf" ],
"bars": [ 5, 141, 14 ]
},
"8": {
"location": [ 5, 12, "t0_14b_tf" ],
"column": [ 5, 76 ],
"day": [ 39, 23, "bahnschrift20.vlw", 48, 140 ],
"icon": [ 39, 65, 45 ],
"wind": [ 23, 26 ],
"line": [ 20, 168 ]
},
"4": {
"location": [ 10, 0, "fonts/calibrib36" ],
"wind": [ 80, 45, "fonts/calibrib40" ],
"temp": [ 10, 63, "fonts/calibrib100" ],
"icon": [ 375, 0, 100, 2 ],
"dir": [ 30, 20, 70 ],
"umbrella": [ 325, 100, 78 ]
},
"8": {
"location": [ 5, -3, "fonts/calibrib24" ],
"column": [ 5, 76 ],
"day": [ 39, 30, "bahnschrift20.vlw", 56, 147 ],
"icon": [ 39, 72, 45 ],
"wind": [ 23, 34 ],
"line": [ 20, 168 ]
},
"9": {
"title": [ 5, 4, "bahnschrift20.vlw", 25 ],
"items": 8,

View File

@@ -1,5 +1,5 @@
{
"version": 3,
"version": 4,
"name": "M3 7.5\"",
"width": 800,
"height": 480,
@@ -29,13 +29,19 @@
"umbrella": [ 325, 155, 78 ]
},
"8": {
"location": [ 10, 10, "fonts/calibrib30" ],
"column": [ 6, 66 ],
"day": [ 33, 60, "fonts/bahnschrift20", 104, 230 ],
"rain": [ 34, 260 ],
"icon": [ 32, 145, 30 ],
"wind": [ 17, 90 ],
"line": [ 50, 300 ]
"location": [ 10, 0, "fonts/calibrib50" ],
"column": [ 7, 114 ],
"day": [ 55, 210, "fonts/calibrib30", 250, 385 ],
"rain": [ 58, 440 ],
"icon": [ 55, 280, 60 ],
"wind": [ 37, 220 ],
"line": [ 195, 470 ],
"currentwind": [ 460, 130, "fonts/calibrib40" ],
"temp": [ 10, 50, "fonts/calibrib120", 1 ],
"currenticon": [ 770, 0, 140, 2 ],
"dir": [ 410, 100, 80 ],
"umbrella": [ 390, 50, 60 ]
},
"9": {
"title": [ 6, 0, "Signika-SB.ttf", 32 ],