From bc4d61098c8f9ca1b68c53fb48ea92a9afcb0e40 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 9 Dec 2022 19:10:24 +0100 Subject: [PATCH] Some error handling --- lib/EntsoePriceApi/include/EntsoeApi.h | 4 +++ lib/EntsoePriceApi/src/EntsoeApi.cpp | 30 +++++++++++++++---- lib/SvelteUi/app/src/lib/Header.svelte | 9 ++++-- lib/SvelteUi/app/src/lib/Helpers.js | 20 +++++++++++++ lib/SvelteUi/app/src/lib/VendorPanel.svelte | 5 +++- lib/SvelteUi/json/data.json | 1 + lib/SvelteUi/src/AmsWebServer.cpp | 5 +++- src/AmsToMqttBridge.ino | 32 ++++++++++++--------- 8 files changed, 82 insertions(+), 24 deletions(-) diff --git a/lib/EntsoePriceApi/include/EntsoeApi.h b/lib/EntsoePriceApi/include/EntsoeApi.h index 43f3811c..7ff12fba 100644 --- a/lib/EntsoePriceApi/include/EntsoeApi.h +++ b/lib/EntsoePriceApi/include/EntsoeApi.h @@ -29,6 +29,8 @@ public: float getValueForHour(int8_t); float getValueForHour(time_t, int8_t); + int16_t getLastError(); + private: RemoteDebug* debugger; EntsoeConfig* config = NULL; @@ -54,6 +56,8 @@ private: float currencyMultiplier = 0; + int16_t lastError = 0; + PricesContainer* fetchPrices(time_t); bool retrieve(const char* url, Stream* doc); float getCurrencyMultiplier(const char* from, const char* to); diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 32af0385..3efe4d5f 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -164,8 +164,13 @@ bool EntsoeApi::loop() { return true; } else { if(today == NULL && (lastTodayFetch == 0 || now - lastTodayFetch > 60000)) { - lastTodayFetch = now; - today = fetchPrices(t); + try { + lastTodayFetch = now; + today = fetchPrices(t); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + today = NULL; + } return today != NULL; } @@ -175,9 +180,14 @@ bool EntsoeApi::loop() { && midnightMillis - now < tomorrowFetchMillis && (lastTomorrowFetch == 0 || now - lastTomorrowFetch > 900000) ) { - breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight - lastTomorrowFetch = now; - tomorrow = fetchPrices(t+SECS_PER_DAY); + try { + breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight + lastTomorrowFetch = now; + tomorrow = fetchPrices(t+SECS_PER_DAY); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + tomorrow = NULL; + } return tomorrow != NULL; } } @@ -207,8 +217,10 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { printD("Receiving data"); http.writeToStream(doc); http.end(); + lastError = 0; return true; } else { + lastError = status; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); printE(http.errorToString(status)); printD(http.getString()); @@ -326,7 +338,9 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { printD("Receiving data"); data = http.getString(); http.end(); + lastError = 0; } else { + lastError = status; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); printE(http.errorToString(status)); printD(http.getString()); @@ -355,8 +369,10 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { for(uint8_t i = 0; i < 24; i++) { ret->points[i] = ntohl(ret->points[i]); } + lastError = 0; return ret; } else { + lastError = gcmRet; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Error code while decrypting prices: %d\n", gcmRet); } } @@ -392,3 +408,7 @@ void EntsoeApi::debugPrint(byte *buffer, int start, int length) { } debugger->println(""); } + +int16_t EntsoeApi::getLastError() { + return lastError; +} \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index bb41bf27..024b4498 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -2,7 +2,7 @@ import { Link } from "svelte-navigator"; import { sysinfoStore, getGitHubReleases, gitHubReleaseStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; - import { boardtype, hanError, mqttError } from './Helpers.js'; + import { boardtype, hanError, mqttError, priceError } from './Helpers.js'; import GitHubLogo from './../assets/github.svg'; import Uptime from "./Uptime.svelte"; import Badge from './Badge.svelte'; @@ -59,10 +59,13 @@ {#if data.he < 0} -
{ 'HAN error: ' + hanError(data.he) }
+
{ 'HAN: ' + hanError(data.he) }
{/if} {#if data.me < 0} -
{ 'MQTT error: ' + mqttError(data.me) }
+
{ 'MQTT: ' + mqttError(data.me) }
+ {/if} + {#if data.ee != 0} +
{ 'PriceAPI: ' + priceError(data.ee) }
{/if}
diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index 2cb3ea50..6712ceae 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -118,6 +118,26 @@ export function mqttError(err) { case -13: return "Connection lost"; } + if(err < 0) return "Unspecified error "+err; + return ""; +} + +export function priceError(err) { + switch(err) { + case 401: + case 403: + return "Unauthorized, check API key"; + case 404: + return "Price unavailable, not found"; + case 500: + return "Internal server error"; + case -2: return "Incomplete data received"; + case -3: return "Invalid data, tag missing"; + case -51: return "Authentication failed"; + case -52: return "Decryption failed"; + case -53: return "Encryption key invalid"; + } + if(err < 0) return "Unspecified error "+err; return ""; } \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index dac12b65..8740f27c 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -29,7 +29,7 @@ s.booting = res.reboot; return s; }); - navigate("/setup"); + navigate(sysinfo.usrcfg ? "/" : "/setup"); } @@ -52,6 +52,9 @@
{/if} +
+ +
diff --git a/lib/SvelteUi/json/data.json b/lib/SvelteUi/json/data.json index 173c115f..6b840e41 100644 --- a/lib/SvelteUi/json/data.json +++ b/lib/SvelteUi/json/data.json @@ -58,5 +58,6 @@ }, "pr" : "%s", "he" : %d, + "ee" : %d, "c" : %lu } \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index a17573cb..a2385992 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -403,6 +403,7 @@ void AmsWebServer::dataJson() { ea->getIncomeThisMonth(), priceRegion.c_str(), meterState->getLastError(), + eapi == NULL ? 0 : eapi->getLastError(), (uint32_t) time(nullptr) ); @@ -859,7 +860,9 @@ void AmsWebServer::handleSave() { if(server.hasArg(F("v")) && server.arg(F("v")) == F("true")) { int boardType = server.arg(F("vb")).toInt(); int hanPin = server.arg(F("vh")).toInt(); - config->clear(); + if(server.hasArg(F("vr")) && server.arg(F("vr")) == F("true")) { + config->clear(); + } #if defined(CONFIG_IDF_TARGET_ESP32S2) switch(boardType) { diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 8b180345..a2d11865 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -572,25 +572,29 @@ void loop() { ea.setup(&ds, eac); config.ackEnergyAccountingChange(); } + try { + if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { + if(now - lastTemperatureRead > 15000) { + unsigned long start = millis(); + hw.updateTemperatures(); + lastTemperatureRead = now; - if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { - if(now - lastTemperatureRead > 15000) { - unsigned long start = millis(); - hw.updateTemperatures(); - lastTemperatureRead = now; - - if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { - mqttHandler->publishTemperatures(&config, &hw); + if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { + mqttHandler->publishTemperatures(&config, &hw); + } + debugD("Used %ld ms to update temperature", millis()-start); } - debugD("Used %ld ms to update temperature", millis()-start); - } - if(now - lastSysupdate > 10000) { - if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { - mqttHandler->publishSystem(&hw, eapi, &ea); + if(now - lastSysupdate > 10000) { + if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { + mqttHandler->publishSystem(&hw, eapi, &ea); + } + lastSysupdate = now; } - lastSysupdate = now; } + } catch(const std::exception& e) { + debugE("Exception in readHanPort (%s)", e.what()); } + delay(1); // Needed for auto modem sleep #if defined(ESP32) esp_task_wdt_reset();