From 2ba540cb172361b7e5b3cffcffc2de319ca2510b Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Mon, 11 Dec 2023 18:41:49 +0100 Subject: [PATCH 01/15] OSW weather emu + doc +The OSW weather app is now supported also when using the emulator. +Documentation update --- docs/firmware/apps/OswWeather.md | 15 ++- include/apps/_experiments/OswAppWeather.h | 3 +- src/apps/_experiments/OswAppWeather.cpp | 116 +++++++++++++----- .../_experiments/OswAppWeatherEncoder.cpp | 10 +- 4 files changed, 110 insertions(+), 34 deletions(-) diff --git a/docs/firmware/apps/OswWeather.md b/docs/firmware/apps/OswWeather.md index 874d358c4..319cb832f 100644 --- a/docs/firmware/apps/OswWeather.md +++ b/docs/firmware/apps/OswWeather.md @@ -1,5 +1,7 @@ -# OSW WEATHER +# OSW WEATHER +![](/assets/apps/OswWeather/h.png) +Author: [@LorenzoSciacca](https://github.com/Lorenzosciacca) ## How to install Add the flag `OSW_FEATURE_WEATHER` to the file `platformio.ini`: ```ini @@ -58,7 +60,8 @@ The / \ and \ / arrows are used to decrease/increase the current selection (da - Humidity: [relative humidity](https://en.wikipedia.org/wiki/Humidity#Relative_humidity) - Pressure: [hPa](https://en.wikipedia.org/wiki/Pascal_(unit)#Multiples_and_submultiples) -### Weather conditions +### Weather conditions + Visit [this link](https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2) for a more detailed description of each weather condition. @@ -164,4 +167,10 @@ Visit [this link](https://openweathermap.org/weather-conditions#Weather-Conditio -
Unknown
\ No newline at end of file + + +## Using the emulator +To use this app while using the OSW emulator, in order to retireve the data, it is necessary to perform the API request using the browser and to save the response in `file_weather.json` in the `/build` folder. + + + diff --git a/include/apps/_experiments/OswAppWeather.h b/include/apps/_experiments/OswAppWeather.h index 995884680..326885b82 100644 --- a/include/apps/_experiments/OswAppWeather.h +++ b/include/apps/_experiments/OswAppWeather.h @@ -60,5 +60,6 @@ class OswAppWeather : public OswApp { tm* tmInit; std::vector dayFirstUpdt{};// n-th entry is the index of first update of the n-th day bool _request(); + void drawPopUp(); }; -#endif \ No newline at end of file +#endif diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index b813a3f3e..e996484ed 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -3,16 +3,21 @@ #include "apps/_experiments/OswAppWeatherEncoder.h" #include "services/OswServiceTaskWiFi.h" #include -#include #include #include #include #include #include "fonts/DS_DIGI12pt7b.h" #include "ArduinoJson.h" - +#ifndef OSW_EMULATOR +#include +#endif #define OPENWEATHERMAP_URL "https://api.openweathermap.org/data/2.5/forecast?q=" #define URL_REQ OPENWEATHERMAP_URL OPENWEATHERMAP_CITY "," OPENWEATHERMAP_STATE_CODE "&appid=" OPENWEATHERMAP_APIKEY "&cnt=24" +#ifdef OSW_EMULATOR +#include +#include +#endif /* TODO: multiple location support measurement unit conversion (?) @@ -100,7 +105,6 @@ int WeatherDecoder::_str2wthr(const String& weather) { } - class WeatherParser { public: WeatherParser(); @@ -122,12 +126,12 @@ class WeatherParser { std::vectorrainMed{502, 501};//10 std::vectorrainHigh{503, 504, 511, 520, 521, 522, 531};//11 std::vectorthunderstorm{200, 201, 210, 211, 231, 230};//12 - std::vectorthunderstorHeavy{202, 212, 221, 232};//13 + std::vectorthunderstormHeavy{202, 212, 221, 232};//13 std::vectorsquallTornado{771, 781};//14 //15 ->unknown std::vector>weather_conditions{clearCode, cloudsMin, cloudsMed, cloudsHigh, mist, fog, snowMin, snowMed, snowHigh, rainMin, rainMed, rainHigh, thunderstorm, - thunderstorHeavy, squallTornado }; + thunderstormHeavy, squallTornado }; }; WeatherParser::WeatherParser() {} @@ -159,7 +163,10 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { update.weather = this->_getWCond(doc["list"][i]["weather"][0]["id"]); res = encoder.setUpdate(update); if (!res) { - return "ERROR_INPUT"; + OSW_LOG_I(i); + OSW_LOG_I("content"); + OSW_LOG_I(doc["list"][i]["main"]); + return "ERROR_INPUT" ; } } return encoder.getEncoded(); @@ -176,6 +183,17 @@ int WeatherParser::_getWCond(int weather_code) { return 15; // unknown weather def } +void OswAppWeather::drawPopUp() { + this->hal->gfx()->drawThickLine(50,120,190,120,15,rgb888(255,255,255),true); + this->hal->gfx()->drawThickLine(51,120,189,120,14,rgb888(0,0,0),true); + this->hal->gfx()->setTextCursor(120,120); + this->hal->gfx()->setTextColor(rgb888(255,255,255)); + this->hal->gfx()->setTextCenterAligned(); + this->hal->gfx()->setTextMiddleAligned(); + this->hal->gfx()->print("connecting..."); +} + + void OswAppWeather::drawWeather() { updtTime = initTimestamp + (this->updtSelector * 10800 ); this->printWIcon.drawIcon(this->forecast[this->updtSelector].weather,120,45,1); @@ -252,7 +270,7 @@ void OswAppWeather::printLastUpdate() { this->hal->gfx()->setTextCursor(120, 225); this->hal->gfx()->print(this->initTimeDMY); } - +#ifndef OSW_EMULATOR void OswAppWeather::weatherRequest() { if(!OswServiceAllTasks::wifi.isConnected()) { OswServiceAllTasks::wifi.enableWiFi(); @@ -263,9 +281,10 @@ void OswAppWeather::weatherRequest() { bool OswAppWeather::_request() { HTTPClient http; + int code = 0; + OSW_LOG_I("Request: "); OSW_LOG_I(this->url); http.begin(this->url, OPENWEATHERMAP_CA_CERT); - int code = 0; if (OswServiceAllTasks::wifi.isConnected()) { OswHal::getInstance()->disableDisplayBuffer(); this->forecast.clear(); @@ -277,9 +296,8 @@ bool OswAppWeather::_request() { } http.end(); OswServiceAllTasks::wifi.disconnectWiFi(); - OSW_LOG_I("code:", code); + OSW_LOG_I("Request returned code: ", code); if (code == 200) { - DynamicJsonDocument doc(16432); deserializeJson(doc,http.getStream()); WeatherParser pars; String encoded = pars.encodeWeather(doc); @@ -305,10 +323,22 @@ bool OswAppWeather::_request() { return true; } else { this->dataLoaded = false; - return false; + return false;6 } } +#else +void OswAppWeather::weatherRequest() { + this->requestMode = true; +} +bool OswAppWeather::_request() { + + this->requestMode=false; + this->dataLoaded=true; + return true; +} +#endif + void OswAppWeather::getDayList(int nUpdates) { time_t timestamp = this->initTimestamp; @@ -379,8 +409,32 @@ void OswAppWeather::printDate() { } bool OswAppWeather::loadData() { - String wstr = this->pref.getString("wtr"); - if (!wstr.equals("")) { +#ifdef OSW_EMULATOR + std::ifstream inFile; + inFile.open("file_weather.json"); //open the input file + if(!inFile.is_open()){ + OSW_LOG_I("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); + } + std::stringstream strStream; + strStream << inFile.rdbuf(); + std::string strW = strStream.str(); + OSW_LOG_I("ifstrm"); + DynamicJsonDocument doc(16432*2);// when in emulator more space is needed + OSW_LOG_I("json file:"); + OSW_LOG_I(strW); + deserializeJson(doc,strW); + WeatherParser pars; + String encoded = pars.encodeWeather(doc); + OSW_LOG_I("encoded"); + OSW_LOG_I(encoded); + int encoded_len = encoded.length(); + char encoded_arr[encoded_len + 1]; + strcpy(encoded_arr, encoded.c_str()); + String wstr = String(encoded_arr); +#else + String wstr = this->pref.getString("wtr"); +#endif + if (wstr!="") { OSW_LOG_I("size of wstr: ", wstr.length()); if( (wstr.length() % 8) != 0 ) { this->dataLoaded = false; @@ -430,19 +484,21 @@ int OswAppWeather::getPrevDay() { void OswAppWeather::setup() { +OSW_LOG_I("Setup "); this->location1 = OswConfigAllKeys::weatherLocation1.get(); this->state1 = OswConfigAllKeys::weatherState1.get(); this->api_key = OswConfigAllKeys::weatherApiKey.get(); this->url = String(OPENWEATHERMAP_URL); - this->url.concat(this->location1); - this->url.concat(","); - this->url.concat(this->state1); - this->url.concat("&appid="); - this->url.concat(this->api_key); - this->url.concat("&cnt=24"); - pref.begin("wheater-app"); + this->url = this->url + this->location1; + this->url = this->url + ","; + this->url = this->url + this->state1; + this->url = this->url + "&appid="; + this->url = this->url + this->api_key; + this->url = this->url + "&cnt=24"; + pref.begin("wheater-app", false); this->loadData(); this->printWIcon.getHal(this->hal); + OSW_LOG_I("Setup end"); } void OswAppWeather::loop() { @@ -453,19 +509,21 @@ void OswAppWeather::loop() { this->printDate(); this->printLastUpdate(); } + + #ifndef OSW_EMULATOR if(this->requestMode) { if (OswServiceAllTasks::wifi.isConnected()) { this->_request(); - } else {//pop-up - this->hal->gfx()->drawThickLine(50,120,190,120,15,rgb888(255,255,255),true); - this->hal->gfx()->drawThickLine(51,120,189,120,14,rgb888(0,0,0),true); - this->hal->gfx()->setTextCursor(120,120); - this->hal->gfx()->setTextColor(rgb888(255,255,255)); - this->hal->gfx()->setTextCenterAligned(); - this->hal->gfx()->setTextMiddleAligned(); - this->hal->gfx()->print("connecting..."); + } else { + this->drawPopUp(); } } + #else + if(this->requestMode) { + this->_request(); + this->drawPopUp(); + } + #endif if (hal->btnHasGoneDown(BUTTON_2)) { if(this->mainSelector==1) { // next update if(this->updtSelector<23) { @@ -511,4 +569,4 @@ void OswAppWeather::loop() { void OswAppWeather::stop() { } -#endif \ No newline at end of file +#endif diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index cb491393a..ffe886316 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -6,15 +6,23 @@ OswAppWeatherEncoder::OswAppWeatherEncoder() {} bool OswAppWeatherEncoder::setUpdate(OswAppWeather::weather_update_t update) { bool update_ok = true; if(update.temp > 99 || update.temp < -99 ) { - update_ok = false; + OSW_LOG_I("ERROR TEMP"); + OSW_LOG_I(update.temp); + update_ok = false; } if(update.humidity > 100 || update.humidity < 0) { + OSW_LOG_I("ERROR HUMIDITY"); + OSW_LOG_I(update.humidity); update_ok = false; } if(update.pressure < 0 || update.pressure > 2000 ) { + OSW_LOG_I("ERROR PRESSURE"); + OSW_LOG_I(update.pressure); update_ok = false; } if(update.weather < 0 || update.weather > 15) { + OSW_LOG_I(update.weather); + OSW_LOG_I("ERROR WEATHER"); update_ok = false; } if(!update_ok) { From d68d65dc5dbf20b9ef722459d3b8cbc2a35973c1 Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sat, 16 Dec 2023 16:29:20 +0100 Subject: [PATCH 02/15] bug fix --- src/apps/_experiments/OswAppWeather.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index e996484ed..09f1606b6 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -163,9 +163,7 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { update.weather = this->_getWCond(doc["list"][i]["weather"][0]["id"]); res = encoder.setUpdate(update); if (!res) { - OSW_LOG_I(i); - OSW_LOG_I("content"); - OSW_LOG_I(doc["list"][i]["main"]); + OSW_LOG_I("ERROR_INPUT" ); return "ERROR_INPUT" ; } } @@ -298,6 +296,7 @@ bool OswAppWeather::_request() { OswServiceAllTasks::wifi.disconnectWiFi(); OSW_LOG_I("Request returned code: ", code); if (code == 200) { + DynamicJsonDocument doc(16432); deserializeJson(doc,http.getStream()); WeatherParser pars; String encoded = pars.encodeWeather(doc); @@ -323,7 +322,7 @@ bool OswAppWeather::_request() { return true; } else { this->dataLoaded = false; - return false;6 + return false; } } From a03c4dc4c6922abe07e42599aeaf22c1ac956345 Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:39:12 +0100 Subject: [PATCH 03/15] Update OswAppWeather.cpp Cleanup debug print --- src/apps/_experiments/OswAppWeather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 09f1606b6..c0cc18a67 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -483,7 +483,7 @@ int OswAppWeather::getPrevDay() { void OswAppWeather::setup() { -OSW_LOG_I("Setup "); + OSW_LOG_D("OSW Weatheer Setup "); this->location1 = OswConfigAllKeys::weatherLocation1.get(); this->state1 = OswConfigAllKeys::weatherState1.get(); this->api_key = OswConfigAllKeys::weatherApiKey.get(); From 2ba14d914739b35456e7de32b6d5a9785283122c Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:40:24 +0100 Subject: [PATCH 04/15] Update OswAppWeatherEncoder.cpp Error print --- src/apps/_experiments/OswAppWeatherEncoder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index ffe886316..3bad82724 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -6,7 +6,7 @@ OswAppWeatherEncoder::OswAppWeatherEncoder() {} bool OswAppWeatherEncoder::setUpdate(OswAppWeather::weather_update_t update) { bool update_ok = true; if(update.temp > 99 || update.temp < -99 ) { - OSW_LOG_I("ERROR TEMP"); + OSW_LOG_E("ERROR TEMP"); OSW_LOG_I(update.temp); update_ok = false; } From 32c8f678162091c4f8cf0447809ffed97d7aa1ff Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sun, 17 Dec 2023 14:43:08 +0100 Subject: [PATCH 05/15] Update OswAppWeatherEncoder.cpp Warnings --- src/apps/_experiments/OswAppWeatherEncoder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index 3bad82724..149a1cb7e 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -6,23 +6,23 @@ OswAppWeatherEncoder::OswAppWeatherEncoder() {} bool OswAppWeatherEncoder::setUpdate(OswAppWeather::weather_update_t update) { bool update_ok = true; if(update.temp > 99 || update.temp < -99 ) { - OSW_LOG_E("ERROR TEMP"); + OSW_LOG_W("ERROR TEMP"); OSW_LOG_I(update.temp); update_ok = false; } if(update.humidity > 100 || update.humidity < 0) { - OSW_LOG_I("ERROR HUMIDITY"); + OSW_LOG_W("ERROR HUMIDITY"); OSW_LOG_I(update.humidity); update_ok = false; } if(update.pressure < 0 || update.pressure > 2000 ) { - OSW_LOG_I("ERROR PRESSURE"); + OSW_LOG_W("ERROR PRESSURE"); OSW_LOG_I(update.pressure); update_ok = false; } if(update.weather < 0 || update.weather > 15) { OSW_LOG_I(update.weather); - OSW_LOG_I("ERROR WEATHER"); + OSW_LOG_W("ERROR WEATHER"); update_ok = false; } if(!update_ok) { From b124ed0578f87923bcff52b1108e0ebc1d16caa5 Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sun, 17 Dec 2023 15:05:34 +0100 Subject: [PATCH 06/15] Update OswAppWeather.cpp Errors and warnings --- src/apps/_experiments/OswAppWeather.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index c0cc18a67..8165a6314 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -163,7 +163,7 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { update.weather = this->_getWCond(doc["list"][i]["weather"][0]["id"]); res = encoder.setUpdate(update); if (!res) { - OSW_LOG_I("ERROR_INPUT" ); + OSW_LOG_W("ERROR_INPUT" ); return "ERROR_INPUT" ; } } @@ -280,21 +280,21 @@ void OswAppWeather::weatherRequest() { bool OswAppWeather::_request() { HTTPClient http; int code = 0; - OSW_LOG_I("Request: "); - OSW_LOG_I(this->url); + OSW_LOG_D("Request: "); + OSW_LOG_D(this->url); http.begin(this->url, OPENWEATHERMAP_CA_CERT); if (OswServiceAllTasks::wifi.isConnected()) { OswHal::getInstance()->disableDisplayBuffer(); this->forecast.clear(); this->dataLoaded=false; - OSW_LOG_I("free heap ", ESP.getFreeHeap()); + OSW_LOG_D("free heap ", ESP.getFreeHeap()); code = http.GET(); } else { return false; } http.end(); OswServiceAllTasks::wifi.disconnectWiFi(); - OSW_LOG_I("Request returned code: ", code); + OSW_LOG_D("Request returned code: ", code); if (code == 200) { DynamicJsonDocument doc(16432); deserializeJson(doc,http.getStream()); @@ -317,7 +317,7 @@ bool OswAppWeather::_request() { this->requestMode=false; bool res = this->loadData(); if (res) { - OSW_LOG_I("weather updated correctly"); + OSW_LOG_D("weather updated correctly"); this->dataLoaded=true; return true; } else { @@ -412,12 +412,11 @@ bool OswAppWeather::loadData() { std::ifstream inFile; inFile.open("file_weather.json"); //open the input file if(!inFile.is_open()){ - OSW_LOG_I("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); + OSW_LOG_E("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); } std::stringstream strStream; strStream << inFile.rdbuf(); std::string strW = strStream.str(); - OSW_LOG_I("ifstrm"); DynamicJsonDocument doc(16432*2);// when in emulator more space is needed OSW_LOG_I("json file:"); OSW_LOG_I(strW); @@ -434,7 +433,7 @@ bool OswAppWeather::loadData() { String wstr = this->pref.getString("wtr"); #endif if (wstr!="") { - OSW_LOG_I("size of wstr: ", wstr.length()); + OSW_LOG_D("size of wstr: ", wstr.length()); if( (wstr.length() % 8) != 0 ) { this->dataLoaded = false; return false; @@ -483,7 +482,7 @@ int OswAppWeather::getPrevDay() { void OswAppWeather::setup() { - OSW_LOG_D("OSW Weatheer Setup "); + OSW_LOG_D("OSW Weather Setup "); this->location1 = OswConfigAllKeys::weatherLocation1.get(); this->state1 = OswConfigAllKeys::weatherState1.get(); this->api_key = OswConfigAllKeys::weatherApiKey.get(); @@ -497,7 +496,7 @@ void OswAppWeather::setup() { pref.begin("wheater-app", false); this->loadData(); this->printWIcon.getHal(this->hal); - OSW_LOG_I("Setup end"); + OSW_LOG_D("Setup end"); } void OswAppWeather::loop() { From 15ccebca98f03b3bc97ed3349028ea4355be23df Mon Sep 17 00:00:00 2001 From: Lorenzosciacca <60114811+Lorenzosciacca@users.noreply.github.com> Date: Sun, 17 Dec 2023 15:06:49 +0100 Subject: [PATCH 07/15] Update OswAppWeatherEncoder.cpp Warnings --- src/apps/_experiments/OswAppWeatherEncoder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index 149a1cb7e..7a58a9b85 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -7,21 +7,21 @@ bool OswAppWeatherEncoder::setUpdate(OswAppWeather::weather_update_t update) { bool update_ok = true; if(update.temp > 99 || update.temp < -99 ) { OSW_LOG_W("ERROR TEMP"); - OSW_LOG_I(update.temp); + OSW_LOG_W(update.temp); update_ok = false; } if(update.humidity > 100 || update.humidity < 0) { OSW_LOG_W("ERROR HUMIDITY"); - OSW_LOG_I(update.humidity); + OSW_LOG_W(update.humidity); update_ok = false; } if(update.pressure < 0 || update.pressure > 2000 ) { OSW_LOG_W("ERROR PRESSURE"); - OSW_LOG_I(update.pressure); + OSW_LOG_W(update.pressure); update_ok = false; } if(update.weather < 0 || update.weather > 15) { - OSW_LOG_I(update.weather); + OSW_LOG_W(update.weather); OSW_LOG_W("ERROR WEATHER"); update_ok = false; } From 74d9dbb713e0f808c6056c0f535c4dc0214ab1d5 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 09:42:09 +0200 Subject: [PATCH 08/15] Formatting Signed-off-by: simonmicro --- src/apps/_experiments/OswAppWeather.cpp | 84 ++++++++++++------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 8165a6314..4e6d05767 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -9,7 +9,7 @@ #include #include "fonts/DS_DIGI12pt7b.h" #include "ArduinoJson.h" -#ifndef OSW_EMULATOR +#ifndef OSW_EMULATOR #include #endif #define OPENWEATHERMAP_URL "https://api.openweathermap.org/data/2.5/forecast?q=" @@ -164,7 +164,7 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { res = encoder.setUpdate(update); if (!res) { OSW_LOG_W("ERROR_INPUT" ); - return "ERROR_INPUT" ; + return "ERROR_INPUT" ; } } return encoder.getEncoded(); @@ -182,13 +182,13 @@ int WeatherParser::_getWCond(int weather_code) { } void OswAppWeather::drawPopUp() { - this->hal->gfx()->drawThickLine(50,120,190,120,15,rgb888(255,255,255),true); - this->hal->gfx()->drawThickLine(51,120,189,120,14,rgb888(0,0,0),true); - this->hal->gfx()->setTextCursor(120,120); - this->hal->gfx()->setTextColor(rgb888(255,255,255)); - this->hal->gfx()->setTextCenterAligned(); - this->hal->gfx()->setTextMiddleAligned(); - this->hal->gfx()->print("connecting..."); + this->hal->gfx()->drawThickLine(50,120,190,120,15,rgb888(255,255,255),true); + this->hal->gfx()->drawThickLine(51,120,189,120,14,rgb888(0,0,0),true); + this->hal->gfx()->setTextCursor(120,120); + this->hal->gfx()->setTextColor(rgb888(255,255,255)); + this->hal->gfx()->setTextCenterAligned(); + this->hal->gfx()->setTextMiddleAligned(); + this->hal->gfx()->print("connecting..."); } @@ -326,15 +326,15 @@ bool OswAppWeather::_request() { } } -#else +#else void OswAppWeather::weatherRequest() { this->requestMode = true; } bool OswAppWeather::_request() { - - this->requestMode=false; - this->dataLoaded=true; - return true; + + this->requestMode=false; + this->dataLoaded=true; + return true; } #endif @@ -409,28 +409,28 @@ void OswAppWeather::printDate() { bool OswAppWeather::loadData() { #ifdef OSW_EMULATOR - std::ifstream inFile; - inFile.open("file_weather.json"); //open the input file - if(!inFile.is_open()){ - OSW_LOG_E("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); - } - std::stringstream strStream; - strStream << inFile.rdbuf(); - std::string strW = strStream.str(); - DynamicJsonDocument doc(16432*2);// when in emulator more space is needed - OSW_LOG_I("json file:"); - OSW_LOG_I(strW); - deserializeJson(doc,strW); - WeatherParser pars; - String encoded = pars.encodeWeather(doc); - OSW_LOG_I("encoded"); - OSW_LOG_I(encoded); - int encoded_len = encoded.length(); - char encoded_arr[encoded_len + 1]; - strcpy(encoded_arr, encoded.c_str()); - String wstr = String(encoded_arr); -#else - String wstr = this->pref.getString("wtr"); + std::ifstream inFile; + inFile.open("file_weather.json"); //open the input file + if(!inFile.is_open()) { + OSW_LOG_E("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); + } + std::stringstream strStream; + strStream << inFile.rdbuf(); + std::string strW = strStream.str(); + DynamicJsonDocument doc(16432*2);// when in emulator more space is needed + OSW_LOG_I("json file:"); + OSW_LOG_I(strW); + deserializeJson(doc,strW); + WeatherParser pars; + String encoded = pars.encodeWeather(doc); + OSW_LOG_I("encoded"); + OSW_LOG_I(encoded); + int encoded_len = encoded.length(); + char encoded_arr[encoded_len + 1]; + strcpy(encoded_arr, encoded.c_str()); + String wstr = String(encoded_arr); +#else + String wstr = this->pref.getString("wtr"); #endif if (wstr!="") { OSW_LOG_D("size of wstr: ", wstr.length()); @@ -507,8 +507,8 @@ void OswAppWeather::loop() { this->printDate(); this->printLastUpdate(); } - - #ifndef OSW_EMULATOR + +#ifndef OSW_EMULATOR if(this->requestMode) { if (OswServiceAllTasks::wifi.isConnected()) { this->_request(); @@ -516,12 +516,12 @@ void OswAppWeather::loop() { this->drawPopUp(); } } - #else +#else if(this->requestMode) { - this->_request(); - this->drawPopUp(); + this->_request(); + this->drawPopUp(); } - #endif +#endif if (hal->btnHasGoneDown(BUTTON_2)) { if(this->mainSelector==1) { // next update if(this->updtSelector<23) { From ce7d3fafe82bfa45807d0f4061f2d06f0edd8081 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 09:57:44 +0200 Subject: [PATCH 09/15] Cleanup error-logging Signed-off-by: simonmicro --- src/apps/_experiments/OswAppWeather.cpp | 35 +++++++++---------- .../_experiments/OswAppWeatherEncoder.cpp | 14 +++----- 2 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 4e6d05767..4f9cb9590 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -163,8 +163,8 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { update.weather = this->_getWCond(doc["list"][i]["weather"][0]["id"]); res = encoder.setUpdate(update); if (!res) { - OSW_LOG_W("ERROR_INPUT" ); - return "ERROR_INPUT" ; + OSW_LOG_E("Failed to pass update to encoder!"); + return "ERROR_INPUT"; } } return encoder.getEncoded(); @@ -305,12 +305,12 @@ bool OswAppWeather::_request() { strcpy(encoded_arr, encoded.c_str()); String encoded_S = String(encoded_arr); if (!this->pref.putString("wtr",encoded_S)) { - OSW_LOG_E("Error: unable to write to NVS"); + OSW_LOG_E("Unable to write to NVS?!"); this->dataLoaded = false; return false; } } else { - OSW_LOG_E("Error: API response: ", code); + OSW_LOG_E("Unexpected API response: ", code); this->dataLoaded = false; return false; } @@ -331,7 +331,7 @@ void OswAppWeather::weatherRequest() { this->requestMode = true; } bool OswAppWeather::_request() { - + // in emulator instantly "fullfill" the request this->requestMode=false; this->dataLoaded=true; return true; @@ -412,23 +412,22 @@ bool OswAppWeather::loadData() { std::ifstream inFile; inFile.open("file_weather.json"); //open the input file if(!inFile.is_open()) { - OSW_LOG_E("Emulator Error: Unable to open 'file_weather.json' in the './build' directory"); + OSW_LOG_E("Unable to open 'file_weather.json' in the current working directory"); + // error handling will be done below as the string is empty } std::stringstream strStream; strStream << inFile.rdbuf(); std::string strW = strStream.str(); + OSW_LOG_D("json file raw:"); + OSW_LOG_D(strW); DynamicJsonDocument doc(16432*2);// when in emulator more space is needed - OSW_LOG_I("json file:"); - OSW_LOG_I(strW); deserializeJson(doc,strW); WeatherParser pars; String encoded = pars.encodeWeather(doc); - OSW_LOG_I("encoded"); - OSW_LOG_I(encoded); - int encoded_len = encoded.length(); - char encoded_arr[encoded_len + 1]; - strcpy(encoded_arr, encoded.c_str()); - String wstr = String(encoded_arr); + OSW_LOG_D("as encoded:"); + OSW_LOG_D(encoded); + String wstr; + wstr += encoded; // this copies the value of "encoded" to "wstr" (just assignment does not take ownership of the value itself) #else String wstr = this->pref.getString("wtr"); #endif @@ -445,11 +444,11 @@ bool OswAppWeather::loadData() { WeatherDecoder decoder(wstr.c_str()); this->initTimestamp = decoder.getTime(); this->getDayList(); - if(strftime(this->initTimeDMY, sizeof(this->initTimeDMY), "%d/%m/%Y", localtime(&this->initTimestamp))) { - //OSW_LOG_I(this->inittimeDMY); + if(!strftime(this->initTimeDMY, sizeof(this->initTimeDMY), "%d/%m/%Y", localtime(&this->initTimestamp))) { + OSW_LOG_W("Failed to parse timestamp: ", this->initTimeDMY); } - if(strftime(this->initTimeMD, sizeof(this->initTimeMD), "%d/%m", localtime(&this->initTimestamp))) { - //OSW_LOG_I(this->initTimeMD); + if(!strftime(this->initTimeMD, sizeof(this->initTimeMD), "%d/%m", localtime(&this->initTimestamp))) { + OSW_LOG_W("Failed to parse timestamp: ", this->initTimeMD); } tmInit = localtime(&this->initTimestamp); forecast = decoder.getUpdates(); diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index 7a58a9b85..f918ce88c 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -6,23 +6,19 @@ OswAppWeatherEncoder::OswAppWeatherEncoder() {} bool OswAppWeatherEncoder::setUpdate(OswAppWeather::weather_update_t update) { bool update_ok = true; if(update.temp > 99 || update.temp < -99 ) { - OSW_LOG_W("ERROR TEMP"); - OSW_LOG_W(update.temp); - update_ok = false; + OSW_LOG_W("Invalid TEMPERATURE: ", update.temp); + update_ok = false; } if(update.humidity > 100 || update.humidity < 0) { - OSW_LOG_W("ERROR HUMIDITY"); - OSW_LOG_W(update.humidity); + OSW_LOG_W("Invalid HUMIDITY: ", update.humidity); update_ok = false; } if(update.pressure < 0 || update.pressure > 2000 ) { - OSW_LOG_W("ERROR PRESSURE"); - OSW_LOG_W(update.pressure); + OSW_LOG_W("Invalid PRESSURE: ", update.pressure); update_ok = false; } if(update.weather < 0 || update.weather > 15) { - OSW_LOG_W(update.weather); - OSW_LOG_W("ERROR WEATHER"); + OSW_LOG_W("Invalid WEATHER: ", update.weather); update_ok = false; } if(!update_ok) { From 6f5414174e8d13cd2b09f4c125c08bf21bf1268e Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:20:37 +0200 Subject: [PATCH 10/15] More strict error handling by replacement of "error-strings" Signed-off-by: simonmicro --- include/apps/_experiments/OswAppWeather.h | 47 +++++++ .../apps/_experiments/OswAppWeatherEncoder.h | 5 +- src/apps/_experiments/OswAppWeather.cpp | 123 ++++++------------ .../_experiments/OswAppWeatherEncoder.cpp | 4 +- 4 files changed, 93 insertions(+), 86 deletions(-) diff --git a/include/apps/_experiments/OswAppWeather.h b/include/apps/_experiments/OswAppWeather.h index 326885b82..1c8a17427 100644 --- a/include/apps/_experiments/OswAppWeather.h +++ b/include/apps/_experiments/OswAppWeather.h @@ -3,6 +3,7 @@ #include #include #include +#include "ArduinoJson.h" #include "OswAppWeatherIconPrinter.h" class OswAppWeather : public OswApp { @@ -20,6 +21,52 @@ class OswAppWeather : public OswApp { virtual void stop() override; ~OswAppWeather() {}; private: + class WeatherDecoder { + public: + WeatherDecoder(const String& input_String); + bool strIsValid(); + time_t getTime(); + std::vector getUpdates(); + private: + time_t _str2time(const String& t); + int _str2temp(const String& temp); + int _str2hum(const String& humidity); + int _str2pres(const String& pressure); + int _str2wthr(const String& weather); + bool in_ok = true; + int nUpdates = 0; + String in_String; + }; + + class WeatherParser { + public: + WeatherParser(); + std::optional encodeWeather(DynamicJsonDocument& doc); + private: + int _getWCond(int weather_code); + int cnt; + std::vector updates; + std::vectorclearCode{800};//0 + std::vectorcloudsMin{801};//1 + std::vectorcloudsMed{802};//2 + std::vectorcloudsHigh{803, 804};//3 + std::vectormist{701};//4 + std::vectorfog{741};//5 + std::vectorsnowMin{611, 612, 615, 616};//6 + std::vectorsnowMed{600, 613, 601, 620};//7 + std::vectorsnowHigh{602, 621, 622};//8 + std::vectorrainMin{500, 300, 301, 302, 310, 311, 312, 313, 314, 321};//9 + std::vectorrainMed{502, 501};//10 + std::vectorrainHigh{503, 504, 511, 520, 521, 522, 531};//11 + std::vectorthunderstorm{200, 201, 210, 211, 231, 230};//12 + std::vectorthunderstormHeavy{202, 212, 221, 232};//13 + std::vectorsquallTornado{771, 781};//14 + //15 ->unknown + std::vector>weather_conditions{clearCode, cloudsMin, cloudsMed, cloudsHigh, mist, fog, snowMin, snowMed, + snowHigh, rainMin, rainMed, rainHigh, thunderstorm, + thunderstormHeavy, squallTornado }; + }; + void getW(); void printW(); void drawLayout(); diff --git a/include/apps/_experiments/OswAppWeatherEncoder.h b/include/apps/_experiments/OswAppWeatherEncoder.h index 9512cf8f0..fd7344806 100644 --- a/include/apps/_experiments/OswAppWeatherEncoder.h +++ b/include/apps/_experiments/OswAppWeatherEncoder.h @@ -1,5 +1,8 @@ #pragma once #ifdef OSW_FEATURE_WEATHER + +#include + #include "apps/_experiments/OswAppWeather.h" class OswAppWeatherEncoder { @@ -7,7 +10,7 @@ class OswAppWeatherEncoder { OswAppWeatherEncoder(); bool setUpdate(OswAppWeather::weather_update_t update); bool setTimestamp(time_t t); - String getEncoded(); + std::optional getEncoded(); private: String _time2str(time_t time); diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 4f9cb9590..5d2065dde 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -8,7 +8,6 @@ #include #include #include "fonts/DS_DIGI12pt7b.h" -#include "ArduinoJson.h" #ifndef OSW_EMULATOR #include #endif @@ -25,24 +24,9 @@ -class WeatherDecoder { - public: - WeatherDecoder(const String& input_String); - bool strIsValid(); - time_t getTime(); - std::vector getUpdates(); - private: - time_t _str2time(const String& t); - int _str2temp(const String& temp); - int _str2hum(const String& humidity); - int _str2pres(const String& pressure); - int _str2wthr(const String& weather); - bool in_ok = true; - int nUpdates = 0; - String in_String; -}; - -WeatherDecoder::WeatherDecoder(const String& input_String) { + + +OswAppWeather::WeatherDecoder::WeatherDecoder(const String& input_String) { if(input_String.length() < 16 || (input_String.length()%8)!= 0 ) { this->in_ok = false; } @@ -50,17 +34,17 @@ WeatherDecoder::WeatherDecoder(const String& input_String) { this->nUpdates = (this->in_String.length()-8)/8; } -bool WeatherDecoder::strIsValid() { +bool OswAppWeather::WeatherDecoder::strIsValid() { return in_ok; } -time_t WeatherDecoder::getTime() { +time_t OswAppWeather::WeatherDecoder::getTime() { String time_str = this->in_String.substring(0,8); time_t t = this->_str2time(time_str); return t; } -std::vector WeatherDecoder::getUpdates() { +std::vector OswAppWeather::WeatherDecoder::getUpdates() { OswAppWeather::weather_update_t update; String update_str; std::vector updates; @@ -75,77 +59,47 @@ std::vector WeatherDecoder::getUpdates() { return updates; } -time_t WeatherDecoder::_str2time(const String& t) { +time_t OswAppWeather::WeatherDecoder::_str2time(const String& t) { int time = t.toInt(); time = time * 8; time = 2147483647 - time; return time; } -int WeatherDecoder::_str2temp(const String& temp) { +int OswAppWeather::WeatherDecoder::_str2temp(const String& temp) { int temp_int = temp.toInt(); return temp_int; } -int WeatherDecoder::_str2hum(const String& humidity) { +int OswAppWeather::WeatherDecoder::_str2hum(const String& humidity) { int hum = humidity.toInt(); hum = (hum*10)+ 5; return hum; } -int WeatherDecoder::_str2pres(const String& pressure) { +int OswAppWeather::WeatherDecoder::_str2pres(const String& pressure) { int pres = pressure.toInt(); pres = pres + 850; return pres; } -int WeatherDecoder::_str2wthr(const String& weather) { +int OswAppWeather::WeatherDecoder::_str2wthr(const String& weather) { char wthr = weather[0]; return wthr - 65; } +OswAppWeather::WeatherParser::WeatherParser() {} -class WeatherParser { - public: - WeatherParser(); - String encodeWeather(DynamicJsonDocument& doc); - private: - int _getWCond(int weather_code); - int cnt; - std::vector updates; - std::vectorclearCode{800};//0 - std::vectorcloudsMin{801};//1 - std::vectorcloudsMed{802};//2 - std::vectorcloudsHigh{803, 804};//3 - std::vectormist{701};//4 - std::vectorfog{741};//5 - std::vectorsnowMin{611, 612, 615, 616};//6 - std::vectorsnowMed{600, 613, 601, 620};//7 - std::vectorsnowHigh{602, 621, 622};//8 - std::vectorrainMin{500, 300, 301, 302, 310, 311, 312, 313, 314, 321};//9 - std::vectorrainMed{502, 501};//10 - std::vectorrainHigh{503, 504, 511, 520, 521, 522, 531};//11 - std::vectorthunderstorm{200, 201, 210, 211, 231, 230};//12 - std::vectorthunderstormHeavy{202, 212, 221, 232};//13 - std::vectorsquallTornado{771, 781};//14 - //15 ->unknown - std::vector>weather_conditions{clearCode, cloudsMin, cloudsMed, cloudsHigh, mist, fog, snowMin, snowMed, - snowHigh, rainMin, rainMed, rainHigh, thunderstorm, - thunderstormHeavy, squallTornado }; -}; - -WeatherParser::WeatherParser() {} - -String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { +std::optional OswAppWeather::WeatherParser::encodeWeather(DynamicJsonDocument& doc) { const char* code = nullptr; code = doc["cod"]; if(strcmp("200",code)) { if(code==nullptr) { OSW_LOG_E("Error, corrupted API response."); - return "ERROR_CORRUPTED_RESPONSE"; + return std::nullopt; // ERROR_CORRUPTED_RESPONSE } else { OSW_LOG_E("Error, response code: ", code); - return "ERROR_API_RESPONSE"; + return std::nullopt; // ERROR_API_RESPONSE } } cnt = doc["cnt"]; @@ -170,7 +124,7 @@ String WeatherParser::encodeWeather(DynamicJsonDocument& doc) { return encoder.getEncoded(); } -int WeatherParser::_getWCond(int weather_code) { +int OswAppWeather::WeatherParser::_getWCond(int weather_code) { for(int i=0; i<15; i++) { for(int j=0; j < weather_conditions[i].size(); j++) { if(weather_code == weather_conditions[i][j]) { @@ -278,6 +232,7 @@ void OswAppWeather::weatherRequest() { } bool OswAppWeather::_request() { + // TODO cleanup the error handling (especially the return false; statements) HTTPClient http; int code = 0; OSW_LOG_D("Request: "); @@ -295,36 +250,38 @@ bool OswAppWeather::_request() { http.end(); OswServiceAllTasks::wifi.disconnectWiFi(); OSW_LOG_D("Request returned code: ", code); - if (code == 200) { - DynamicJsonDocument doc(16432); - deserializeJson(doc,http.getStream()); - WeatherParser pars; - String encoded = pars.encodeWeather(doc); - int encoded_len = encoded.length(); - char encoded_arr[encoded_len + 1]; - strcpy(encoded_arr, encoded.c_str()); - String encoded_S = String(encoded_arr); - if (!this->pref.putString("wtr",encoded_S)) { - OSW_LOG_E("Unable to write to NVS?!"); - this->dataLoaded = false; - return false; - } - } else { + if (code != 200) { OSW_LOG_E("Unexpected API response: ", code); this->dataLoaded = false; return false; } + DynamicJsonDocument doc(16432); + deserializeJson(doc,http.getStream()); + WeatherParser pars; + std::optional encoded = pars.encodeWeather(doc); + if(!encoded.has_value()) { + OSW_LOG_E("Something went wrong with the encoding of the weather data?!"); + this->dataLoaded = false; + return false; + } + int encoded_len = encoded.value().length(); + char encoded_arr[encoded_len + 1]; + strcpy(encoded_arr, encoded.value().c_str()); + String encoded_S = String(encoded_arr); + if (!this->pref.putString("wtr",encoded_S)) { + OSW_LOG_E("Unable to write weather-update to NVS?!"); + this->dataLoaded = false; + return false; + } this->requestMode=false; bool res = this->loadData(); - if (res) { - OSW_LOG_D("weather updated correctly"); - this->dataLoaded=true; - return true; - } else { + if (!res) { this->dataLoaded = false; return false; } - + OSW_LOG_D("weather updated correctly"); + this->dataLoaded=true; + return true; } #else void OswAppWeather::weatherRequest() { diff --git a/src/apps/_experiments/OswAppWeatherEncoder.cpp b/src/apps/_experiments/OswAppWeatherEncoder.cpp index f918ce88c..ac6257dd0 100644 --- a/src/apps/_experiments/OswAppWeatherEncoder.cpp +++ b/src/apps/_experiments/OswAppWeatherEncoder.cpp @@ -43,14 +43,14 @@ bool OswAppWeatherEncoder::setTimestamp(time_t t) { return false; } -String OswAppWeatherEncoder::getEncoded() { +std::optional OswAppWeatherEncoder::getEncoded() { if(this->time_loaded) { String encoded; encoded += _time2str(this->timestamp); encoded += this->updates; return encoded; } else { - return "error_no_timestamp"; + return std::nullopt; // error_no_timestamp } } From f5d4291e94ff9fed93f4a2521abb33aaeb997ae2 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:22:48 +0200 Subject: [PATCH 11/15] Use OK-define Signed-off-by: simonmicro --- src/apps/_experiments/OswAppWeather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 5d2065dde..b9a7f5f9c 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -250,7 +250,7 @@ bool OswAppWeather::_request() { http.end(); OswServiceAllTasks::wifi.disconnectWiFi(); OSW_LOG_D("Request returned code: ", code); - if (code != 200) { + if (code != HTTP_CODE_OK) { OSW_LOG_E("Unexpected API response: ", code); this->dataLoaded = false; return false; From 579721a720013f08f0c395bec096555dbe29de21 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:24:53 +0200 Subject: [PATCH 12/15] Formatting ;) Signed-off-by: simonmicro --- src/apps/_experiments/OswAppWeather.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index b9a7f5f9c..45e826c64 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -241,7 +241,7 @@ bool OswAppWeather::_request() { if (OswServiceAllTasks::wifi.isConnected()) { OswHal::getInstance()->disableDisplayBuffer(); this->forecast.clear(); - this->dataLoaded=false; + this->dataLoaded = false; OSW_LOG_D("free heap ", ESP.getFreeHeap()); code = http.GET(); } else { From 6039cc90a68dc3c8bc5a8b29355e082255b2d849 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:27:33 +0200 Subject: [PATCH 13/15] Explain the user what is going on Signed-off-by: simonmicro --- src/apps/_experiments/OswAppWeather.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 45e826c64..db0e790b6 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -370,6 +370,7 @@ bool OswAppWeather::loadData() { inFile.open("file_weather.json"); //open the input file if(!inFile.is_open()) { OSW_LOG_E("Unable to open 'file_weather.json' in the current working directory"); + OSW_LOG_W("→ Because the emaulator has no HTTP-capabilities (yet), you need to provide this file manually for now."); // error handling will be done below as the string is empty } std::stringstream strStream; From 05806148de8b599ee8aedabecc65601c4f0d4445 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:35:18 +0200 Subject: [PATCH 14/15] Enable weather support in emulator + fixed error-handling there Signed-off-by: simonmicro --- CMakeLists.txt | 1 + src/apps/_experiments/OswAppWeather.cpp | 16 ++++++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ebb0b3b3..6bd1d0d85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -141,6 +141,7 @@ target_compile_definitions(emulator.run PUBLIC # LOCALE="locales/en-US.h" # Comment these as you wish... OSW_FEATURE_STATS_STEPS + OSW_FEATURE_WEATHER OSW_APPS_EXAMPLES=1 GAME_SNAKE=1 GAME_BRICK_BREAKER=1 diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index db0e790b6..53faac8e6 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -365,6 +365,7 @@ void OswAppWeather::printDate() { } bool OswAppWeather::loadData() { + String wstr; #ifdef OSW_EMULATOR std::ifstream inFile; inFile.open("file_weather.json"); //open the input file @@ -381,13 +382,16 @@ bool OswAppWeather::loadData() { DynamicJsonDocument doc(16432*2);// when in emulator more space is needed deserializeJson(doc,strW); WeatherParser pars; - String encoded = pars.encodeWeather(doc); - OSW_LOG_D("as encoded:"); - OSW_LOG_D(encoded); - String wstr; - wstr += encoded; // this copies the value of "encoded" to "wstr" (just assignment does not take ownership of the value itself) + std::optional encoded = pars.encodeWeather(doc); + if(encoded.has_value()) { + OSW_LOG_D("as encoded:"); + OSW_LOG_D(encoded.value()); + wstr += encoded.value(); // this copies the value of "encoded" to "wstr" (just assignment does not take ownership of the value itself) + } else { + OSW_LOG_E("Something went wrong with the encoding of the weather data from the local file?!"); + } #else - String wstr = this->pref.getString("wtr"); + wstr = this->pref.getString("wtr"); #endif if (wstr!="") { OSW_LOG_D("size of wstr: ", wstr.length()); From 7fdd2874a381130415351627d41debd0aec19518 Mon Sep 17 00:00:00 2001 From: simonmicro Date: Sat, 6 Apr 2024 10:59:15 +0200 Subject: [PATCH 15/15] Fixed multiple bugs: - out-of-memory reads - use of incorrectly cached HAL reference - underflow of size_t - wrong signedness comparison - botched load-from-file in emulator erro handling Signed-off-by: simonmicro --- include/apps/_experiments/OswAppWeather.h | 2 +- src/apps/_experiments/OswAppWeather.cpp | 46 +++++++++++++---------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/include/apps/_experiments/OswAppWeather.h b/include/apps/_experiments/OswAppWeather.h index 1c8a17427..7e89ecfd1 100644 --- a/include/apps/_experiments/OswAppWeather.h +++ b/include/apps/_experiments/OswAppWeather.h @@ -93,7 +93,7 @@ class OswAppWeather : public OswApp { uint8_t daySelector = 0; uint8_t placeSelector = 0; uint8_t updtSelector = 0; - OswHal* hal = OswHal::getInstance(); + OswHal* hal = nullptr; std::vector forecast;//one update each 3h time_t initTimestamp; char initTimeMD[6]; diff --git a/src/apps/_experiments/OswAppWeather.cpp b/src/apps/_experiments/OswAppWeather.cpp index 53faac8e6..639a30344 100644 --- a/src/apps/_experiments/OswAppWeather.cpp +++ b/src/apps/_experiments/OswAppWeather.cpp @@ -126,7 +126,7 @@ std::optional OswAppWeather::WeatherParser::encodeWeather(DynamicJsonDoc int OswAppWeather::WeatherParser::_getWCond(int weather_code) { for(int i=0; i<15; i++) { - for(int j=0; j < weather_conditions[i].size(); j++) { + for(size_t j=0; j < weather_conditions[i].size(); j++) { if(weather_code == weather_conditions[i][j]) { return i; } @@ -147,6 +147,10 @@ void OswAppWeather::drawPopUp() { void OswAppWeather::drawWeather() { + if(this->updtSelector >= this->forecast.size()) { + return; + } + updtTime = initTimestamp + (this->updtSelector * 10800 ); this->printWIcon.drawIcon(this->forecast[this->updtSelector].weather,120,45,1); //draw time of current weather updatea @@ -371,24 +375,24 @@ bool OswAppWeather::loadData() { inFile.open("file_weather.json"); //open the input file if(!inFile.is_open()) { OSW_LOG_E("Unable to open 'file_weather.json' in the current working directory"); - OSW_LOG_W("→ Because the emaulator has no HTTP-capabilities (yet), you need to provide this file manually for now."); - // error handling will be done below as the string is empty - } - std::stringstream strStream; - strStream << inFile.rdbuf(); - std::string strW = strStream.str(); - OSW_LOG_D("json file raw:"); - OSW_LOG_D(strW); - DynamicJsonDocument doc(16432*2);// when in emulator more space is needed - deserializeJson(doc,strW); - WeatherParser pars; - std::optional encoded = pars.encodeWeather(doc); - if(encoded.has_value()) { - OSW_LOG_D("as encoded:"); - OSW_LOG_D(encoded.value()); - wstr += encoded.value(); // this copies the value of "encoded" to "wstr" (just assignment does not take ownership of the value itself) + OSW_LOG_W("→ Because the emulator has no HTTP-capabilities (yet), you need to provide this file manually for now."); } else { - OSW_LOG_E("Something went wrong with the encoding of the weather data from the local file?!"); + std::stringstream strStream; + strStream << inFile.rdbuf(); + std::string strW = strStream.str(); + OSW_LOG_D("json file raw:"); + OSW_LOG_D(strW); + DynamicJsonDocument doc(16432*2);// when in emulator more space is needed + deserializeJson(doc,strW); + WeatherParser pars; + std::optional encoded = pars.encodeWeather(doc); + if(encoded.has_value()) { + OSW_LOG_D("as encoded:"); + OSW_LOG_D(encoded.value()); + wstr += encoded.value(); // this copies the value of "encoded" to "wstr" (just assignment does not take ownership of the value itself) + } else { + OSW_LOG_E("Something went wrong with the encoding of the weather data from the local file?!"); + } } #else wstr = this->pref.getString("wtr"); @@ -424,7 +428,7 @@ bool OswAppWeather::loadData() { } int OswAppWeather::getNextDay() { - for(int i=0; idayFirstUpdt.size(); i++) { + for(size_t i=0; idayFirstUpdt.size(); i++) { if(this->dayFirstUpdt[i] > this->updtSelector) { return this->dayFirstUpdt[i]; } @@ -456,6 +460,8 @@ void OswAppWeather::setup() { this->url = this->url + "&cnt=24"; pref.begin("wheater-app", false); this->loadData(); + this->hal = OswHal::getInstance(); // ALWAYS update cached hal reference, as it may change at any point (strictly speaking, it should be updated in every loop, but this is a good place to start with) + // ↑ this is fixed in OswAppV2 where you always have the up-to-date hal reference available this->printWIcon.getHal(this->hal); OSW_LOG_D("Setup end"); } @@ -490,7 +496,7 @@ void OswAppWeather::loop() { } } if(this->mainSelector==0) { //next day - if(this->updtSelector >= this->dayFirstUpdt[this->dayFirstUpdt.size()-1]) { + if(this->dayFirstUpdt.size() > 0 and this->updtSelector >= this->dayFirstUpdt[this->dayFirstUpdt.size()-1]) { this->updtSelector=this->updtSelector; } else { this->updtSelector = this->getNextDay();