Some error handling

This commit is contained in:
Gunnar Skjold 2022-12-09 19:10:24 +01:00
parent b2de6472cf
commit bc4d61098c
8 changed files with 82 additions and 24 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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 @@
<Badge title="MQTT" text="MQTT" color={sysinfo.booting ? 'gray' : data.mm === 1 ? 'green' : data.mm === 2 ? 'yellow' : data.mm === 3 ? 'red' : 'gray'}/>
</div>
{#if data.he < 0}
<div class="bd-red">{ 'HAN error: ' + hanError(data.he) }</div>
<div class="bd-red">{ 'HAN: ' + hanError(data.he) }</div>
{/if}
{#if data.me < 0}
<div class="bd-red">{ 'MQTT error: ' + mqttError(data.me) }</div>
<div class="bd-red">{ 'MQTT: ' + mqttError(data.me) }</div>
{/if}
{#if data.ee != 0}
<div class="bd-red">{ 'PriceAPI: ' + priceError(data.ee) }</div>
{/if}
<div class="flex-auto p-2 flex flex-row-reverse flex-wrap">
<div class="flex-none">

View File

@ -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 "";
}

View File

@ -29,7 +29,7 @@
s.booting = res.reboot;
return s;
});
navigate("/setup");
navigate(sysinfo.usrcfg ? "/" : "/setup");
}
</script>
@ -52,6 +52,9 @@
</select>
</div>
{/if}
<div class="my-3">
<label><input type="checkbox" name="vr" value="true" class="rounded mb-1" checked /> Clear all other configuration</label>
</div>
<div class="my-3">
<button type="submit" class="btn-pri">Save</button>
</div>

View File

@ -58,5 +58,6 @@
},
"pr" : "%s",
"he" : %d,
"ee" : %d,
"c" : %lu
}

View File

@ -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) {

View File

@ -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();