From 327fed6f08c87f8ef2dea65815ad77184e4a2692 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 8 Jan 2022 10:13:02 +0100 Subject: [PATCH] Month plot fix and some other things --- src/AmsDataStorage.cpp | 105 ++++++++++++++++++++++++--------------- src/AmsToMqttBridge.h | 2 +- src/AmsToMqttBridge.ino | 37 ++++++++------ src/web/AmsWebServer.cpp | 3 +- web/application.js | 24 +++++++++ web/data.json | 3 +- web/debugging.html | 9 +++- web/foot.html | 5 +- web/head32.html | 4 +- web/head8266.html | 4 +- web/index.html | 17 ++++--- 11 files changed, 140 insertions(+), 73 deletions(-) diff --git a/src/AmsDataStorage.cpp b/src/AmsDataStorage.cpp index 3ed6dd8b..27f07dca 100644 --- a/src/AmsDataStorage.cpp +++ b/src/AmsDataStorage.cpp @@ -16,7 +16,7 @@ void AmsDataStorage::setTimezone(Timezone* tz) { bool AmsDataStorage::update(AmsData* data) { time_t now = time(nullptr); - if(debugger->isActive(RemoteDebug::DEBUG)) { + if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) Time is: %d\n", now); } if(now < EPOCH_2021_01_01) { @@ -32,8 +32,14 @@ bool AmsDataStorage::update(AmsData* data) { } } } + if(now < EPOCH_2021_01_01) { + if(debugger->isActive(RemoteDebug::VERBOSE)) { + debugger->printf("(AmsDataStorage) Invalid time: %d\n", now); + } + return false; + } if(now-day.lastMeterReadTime < 3595) { - if(debugger->isActive(RemoteDebug::DEBUG)) { + if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) It is only %d seconds since last update, ignoring\n", (now-day.lastMeterReadTime)); } return false; @@ -41,43 +47,49 @@ bool AmsDataStorage::update(AmsData* data) { tmElements_t tm, last; breakTime(now, tm); - if(now > EPOCH_2021_01_01) { - tmElements_t last; - if(day.lastMeterReadTime > EPOCH_2021_01_01) { - if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last day update: %d\n", day.lastMeterReadTime); - } - breakTime(day.lastMeterReadTime, last); - for(int i = last.Hour; i < tm.Hour; i++) { - if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Clearing hour: %d\n", i); - } - setHour(i, 0); + if(day.lastMeterReadTime > EPOCH_2021_01_01) { + if(debugger->isActive(RemoteDebug::DEBUG)) { + debugger->printf("(AmsDataStorage) Last day update: %d\n", day.lastMeterReadTime); + } + breakTime(day.lastMeterReadTime, last); + for(int i = last.Hour; i < tm.Hour; i++) { + if(debugger->isActive(RemoteDebug::VERBOSE)) { + debugger->printf("(AmsDataStorage) Clearing hour: %d\n", i); } + setHour(i, 0); + } + } + + if(month.lastMeterReadTime > EPOCH_2021_01_01) { + if(debugger->isActive(RemoteDebug::DEBUG)) { + debugger->printf("(AmsDataStorage) Last month update: %d\n", month.lastMeterReadTime); + } + if(tz != NULL) { + breakTime(tz->toLocal(now), tm); + breakTime(tz->toLocal(month.lastMeterReadTime), last); + } else { + breakTime(now, tm); + breakTime(month.lastMeterReadTime, last); } - if(month.lastMeterReadTime > EPOCH_2021_01_01) { - if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last month update: %d\n", month.lastMeterReadTime); - } - if(tz != NULL) { - breakTime(tz->toLocal(now), tm); - breakTime(tz->toLocal(month.lastMeterReadTime), last); - } else { - breakTime(now, tm); - breakTime(month.lastMeterReadTime, last); - } - - for(int i = last.Day; i < tm.Day; i++) { - if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Clearing day: %d\n", i); - } - setDay(i, 0); + for(int i = last.Day; i < tm.Day; i++) { + if(debugger->isActive(RemoteDebug::VERBOSE)) { + debugger->printf("(AmsDataStorage) Clearing day: %d\n", i); } + setDay(i, 0); } } + if(day.lastMeterReadTime > now) { + if(debugger->isActive(RemoteDebug::WARNING)) { + debugger->printf("(AmsDataStorage) Invalid future timestamp for day plot, resetting\n"); + } + day.activeImport = data->getActiveImportCounter() * 1000; + day.activeExport = data->getActiveExportCounter() * 1000; + day.lastMeterReadTime = now; + } + if(data->getListType() != 3) return false; else if(tm.Minute > 5) return false; @@ -144,8 +156,17 @@ bool AmsDataStorage::update(AmsData* data) { } else { breakTime(now, tm); } - if(tm.Hour == 0 && now-month.lastMeterReadTime > 86300) { - Serial.printf("\n%d %d %d %d\n", month.version, month.lastMeterReadTime, month.activeImport, month.activeExport); + + if(month.lastMeterReadTime > now) { + if(debugger->isActive(RemoteDebug::WARNING)) { + debugger->printf("(AmsDataStorage) Invalid future timestamp for month plot, resetting\n"); + } + month.activeImport = data->getActiveImportCounter() * 1000; + month.activeExport = data->getActiveExportCounter() * 1000; + month.lastMeterReadTime = now; + } + + if(tm.Hour == 0 && now - month.lastMeterReadTime > 86300) { if(month.activeImport == 0 || now - month.lastMeterReadTime > 2678400) { month.activeImport = data->getActiveImportCounter() * 1000; month.activeExport = data->getActiveExportCounter() * 1000; @@ -153,7 +174,7 @@ bool AmsDataStorage::update(AmsData* data) { if(debugger->isActive(RemoteDebug::WARNING)) { debugger->printf("(AmsDataStorage) Too long since last month update, clearing data\n"); } - for(int i = 0; i<31; i++) { + for(int i = 1; i<=31; i++) { setDay(i, 0); } } else if(now - month.lastMeterReadTime < 87000) { @@ -181,12 +202,16 @@ bool AmsDataStorage::update(AmsData* data) { debugger->printf("(AmsDataStorage) Since last month update, hours: %.1f, import: %d (%.2f/hr), export: %d (%.2f/hr)\n", hrs, im, iph, ex, eph); } + // Make sure last month read is at midnight if(tz != NULL) { breakTime(tz->toLocal(month.lastMeterReadTime), tm); } else { breakTime(month.lastMeterReadTime, tm); } month.lastMeterReadTime = month.lastMeterReadTime - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second; + if(debugger->isActive(RemoteDebug::DEBUG)) { + debugger->printf("(AmsDataStorage) Last month read after resetting to midnight: %lu", month.lastMeterReadTime); + } if(tz != NULL) { breakTime(tz->toLocal(now), tm); @@ -213,7 +238,7 @@ bool AmsDataStorage::update(AmsData* data) { month.activeImport += iph * hours; month.activeExport += eph * hours; - month.lastMeterReadTime += cur; + month.lastMeterReadTime = cur; } } } @@ -221,22 +246,22 @@ bool AmsDataStorage::update(AmsData* data) { } void AmsDataStorage::setHour(uint8_t hour, int32_t val) { - if(hour < 0) return; + if(hour < 0 || hour > 24) return; day.points[hour] = val / 10; } int16_t AmsDataStorage::getHour(uint8_t hour) { - if(hour < 0) return 0; + if(hour < 0 || hour > 24) return 0; return day.points[hour] * 10; } void AmsDataStorage::setDay(uint8_t day, int32_t val) { - if(day < 1) return; + if(day < 1 || day > 31) return; month.points[day-1] = val / 10; } int32_t AmsDataStorage::getDay(uint8_t day) { - if(day < 1) return 0; + if(day < 1 || day > 31) return 0; return (month.points[day-1] * 10); } @@ -273,7 +298,7 @@ bool AmsDataStorage::load() { if(month->version == 4) { memcpy(&this->month, month, sizeof(this->month)); - ret = true; + ret = ret && true; } else { ret = false; } diff --git a/src/AmsToMqttBridge.h b/src/AmsToMqttBridge.h index 2f1a0075..fa05c3d8 100644 --- a/src/AmsToMqttBridge.h +++ b/src/AmsToMqttBridge.h @@ -1,7 +1,7 @@ #ifndef _AMSTOMQTTBRIDGE_H #define _AMSTOMQTTBRIDGE_H -#define WIFI_CONNECTION_TIMEOUT 25000; +#define WIFI_CONNECTION_TIMEOUT 60000; #define INVALID_BUTTON_PIN 0xFFFFFFFF diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 70a7a236..0bf9076a 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -13,6 +13,9 @@ */ #if defined(ESP8266) ADC_MODE(ADC_VCC); +#else if defined(ESP32) +#include +#define WDT_TIMEOUT 10 #endif #include "AmsToMqttBridge.h" @@ -305,6 +308,11 @@ void setup() { } ws.setup(&config, &gpioConfig, &meterConfig, &meterState, &ds); + + #if defined(ESP32) + esp_task_wdt_init(WDT_TIMEOUT, true); + esp_task_wdt_add(NULL); + #endif } int buttonTimer = 0; @@ -349,7 +357,7 @@ void loop() { if (WiFi.status() != WL_CONNECTED) { wifiConnected = false; Debug.stop(); - //WiFi_connect(); Should not be necessary, handled by WiFi stack + WiFi_connect(); } else { wifiReconnectCount = 0; if(!wifiConnected) { @@ -485,6 +493,7 @@ void loop() { } } delay(1); // Needed for auto modem sleep + esp_task_wdt_reset(); } void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) { @@ -700,7 +709,7 @@ bool readHanPort() { } if(ma->append((uint8_t *) buf, len) < 0) pos = -77; - if(Debug.isActive(RemoteDebug::DEBUG)) { + if(Debug.isActive(RemoteDebug::VERBOSE)) { debugD("Frame dump (%db):", len); debugPrint(buf, 0, len); } @@ -708,7 +717,7 @@ bool readHanPort() { return false; } else if(pos == MBUS_FRAME_LAST_SEGMENT) { debugI("Final segment"); - if(Debug.isActive(RemoteDebug::DEBUG)) { + if(Debug.isActive(RemoteDebug::VERBOSE)) { debugD("Frame dump (%db):", len); debugPrint(buf, 0, len); } @@ -730,19 +739,19 @@ bool readHanPort() { memcpy(hc->encryption_key, meterConfig.encryptionKey, 16); memcpy(hc->authentication_key, meterConfig.authenticationKey, 16); } - if(Debug.isActive(RemoteDebug::DEBUG)) { + if(Debug.isActive(RemoteDebug::VERBOSE)) { debugD("Frame dump (%db):", len); debugPrint(buf, 0, len); - if(hc != NULL) { - debugD("System title:"); - debugPrint(hc->system_title, 0, 8); - debugD("Initialization vector:"); - debugPrint(hc->initialization_vector, 0, 12); - debugD("Additional authenticated data:"); - debugPrint(hc->additional_authenticated_data, 0, 17); - debugD("Authentication tag:"); - debugPrint(hc->authentication_tag, 0, 12); - } + } + if(hc != NULL && Debug.isActive(RemoteDebug::DEBUG)) { + debugD("System title:"); + debugPrint(hc->system_title, 0, 8); + debugD("Initialization vector:"); + debugPrint(hc->initialization_vector, 0, 12); + debugD("Additional authenticated data:"); + debugPrint(hc->additional_authenticated_data, 0, 17); + debugD("Authentication tag:"); + debugPrint(hc->authentication_tag, 0, 12); } len = 0; while(hanSerial->available()) hanSerial->read(); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 905dea31..dfebe566 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -781,7 +781,8 @@ void AmsWebServer::dataJson() { mqttStatus, mqtt == NULL ? 0 : (int) mqtt->lastError(), price == ENTSOE_NO_VALUE ? "null" : String(price, 2).c_str(), - time(nullptr) + time(nullptr), + meterState->getMeterType() ); server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); diff --git a/web/application.js b/web/application.js index d7dc3766..b8ab69b6 100644 --- a/web/application.js +++ b/web/application.js @@ -754,6 +754,30 @@ var fetch = function() { $('.jc').addClass('text-danger'); } + var mt = parseInt(json.mt); + switch(mt) { + case 1: + $('.jmt').html("Aidon"); + break; + case 2: + $('.jmt').html("Kaifa"); + break; + case 3: + $('.jmt').html("Kamstrup"); + break; + case 8: + $('.jmt').html("Iskra"); + break; + case 9: + $('.jmt').html("Landis"); + break; + case 10: + $('.jmt').html("Sagecom"); + break; + default: + $('.jmt').html(""); + } + setTimeout(fetch, interval); var price = parseFloat(json.p); diff --git a/web/data.json b/web/data.json index 5cb20cf1..2b200341 100644 --- a/web/data.json +++ b/web/data.json @@ -31,5 +31,6 @@ "mm" : %d, "me" : %d, "p" : %s, - "c" : %lu + "c" : %lu, + "mt" : %d } \ No newline at end of file diff --git a/web/debugging.html b/web/debugging.html index b0f84f6d..ac858968 100644 --- a/web/debugging.html +++ b/web/debugging.html @@ -1,4 +1,10 @@ -
!!NOTE!!
Telnet debugging is not considered safe and should be switched off when not in use
+
+ !!WARNING!!
+ Telnet debugging is not considered safe and should be switched off when not in use.
+
+ !!WARNING!!
+ Enabling debugging can cause sudden reboots. Do not leave this on unless you are debugging! +
@@ -15,6 +21,7 @@