Month plot fix and some other things

This commit is contained in:
Gunnar Skjold 2022-01-08 10:13:02 +01:00
parent 8fe1a1edf2
commit 327fed6f08
11 changed files with 140 additions and 73 deletions

View File

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

View File

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

View File

@ -13,6 +13,9 @@
*/
#if defined(ESP8266)
ADC_MODE(ADC_VCC);
#else if defined(ESP32)
#include <esp_task_wdt.h>
#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();

View File

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

View File

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

View File

@ -31,5 +31,6 @@
"mm" : %d,
"me" : %d,
"p" : %s,
"c" : %lu
"c" : %lu,
"mt" : %d
}

View File

@ -1,4 +1,10 @@
<div class="alert alert-warning">!!NOTE!!<br/>Telnet debugging is not considered safe and should be switched off when not in use</div>
<div class="alert alert-danger">
!!WARNING!!<br/>
Telnet debugging is not considered safe and should be switched off when not in use.<br/>
<br/>
!!WARNING!!<br/>
Enabling debugging can cause sudden reboots. Do not leave this on unless you are debugging!
</div>
<form method="post" action="/save">
<input type="hidden" name="debugConfig" value="true"/>
<div class="my-3 p-3 bg-white rounded shadow">
@ -15,6 +21,7 @@
<label class="col-6">Debug level</label>
<div class="col-6">
<select class="form-control form-control-sm" name="debugLevel">
<option value="1" ${config.debugLevel1}>Verbose</option>
<option value="2" ${config.debugLevel2}>Debug</option>
<option value="3" ${config.debugLevel3}>Info</option>
<option value="4" ${config.debugLevel4}>Warning</option>

View File

@ -10,10 +10,9 @@
</div>
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="application-${version}.js"></script>

View File

@ -52,7 +52,7 @@
<ul class="navbar-nav bd-navbar-nav flex-row">
<li class="nav-item">
<div class="dropdown">
<a class="dropdown-toggle nav-link" href="#" role="button" id="config-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<a class="dropdown-toggle nav-link" href="#" role="button" id="config-link" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Config<span class="d-none d-md-inline d-lg-none d-xl-inline">uration</span>
</a>
@ -70,7 +70,7 @@
</li>
<li class="nav-item">
<div class="dropdown">
<a class="dropdown-toggle nav-link" href="#" role="button" id="system-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<a class="dropdown-toggle nav-link" href="#" role="button" id="system-link" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sys<span class="d-none d-sm-inline">tem</span>
</a>
<div class="dropdown-menu" aria-labelledby="system-link">

View File

@ -52,7 +52,7 @@
<ul class="navbar-nav bd-navbar-nav flex-row">
<li class="nav-item">
<div class="dropdown">
<a class="dropdown-toggle nav-link" href="#" role="button" id="config-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<a class="dropdown-toggle nav-link" href="#" role="button" id="config-link" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Config<span class="d-none d-md-inline d-lg-none d-xl-inline">uration</span>
</a>
@ -69,7 +69,7 @@
</li>
<li class="nav-item">
<div class="dropdown">
<a class="dropdown-toggle nav-link" href="#" role="button" id="system-link" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<a class="dropdown-toggle nav-link" href="#" role="button" id="system-link" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Sys<span class="d-none d-sm-inline">tem</span>
</a>
<div class="dropdown-menu" aria-labelledby="system-link">

View File

@ -1,21 +1,21 @@
<div class="bg-white rounded shadow p-1 mb-3">
<div class="row">
<div class="col-md-2 col-6">
<div class="d-flex flex-wrap">
<div class="flex-fill">
<div class="text-center">Up <span class="ju">{cs}</span></div>
</div>
<div class="col-md-3 col-6 rt ">
<div class="flex-fill rt">
<div class="text-center">Temperature: <span class="jt">{temp}</span>&deg;C</div>
</div>
<div class="col-md-2 col-6 rv">
<div class="flex-fill rv">
<div class="text-center">ESP volt: <span class="jv">{vcc}</span>V</div>
</div>
<div class="col-md-3 col-6">
<div class="flex-fill">
<div class="text-center">WiFi RSSI: <span class="jr">{rssi}</span>dBm</div>
</div>
<div class="col-md-2 col-6">
<div class="flex-fill">
<div class="text-center">Free mem: <span class="jm">{mem}</span>kb</div>
</div>
<div class="col-md-3 col-6 rc">
<div class="flex-fill rc">
<div class="text-center"><span class="jc"></span></div>
</div>
</div>
@ -34,7 +34,8 @@
</span>
</div>
<div class="row ric" style="display: {da};">
<div class="col-12 text-right"><span class="jic">{tPI}</span> kWh</div>
<div class="col-5"><span class="jmt"></span></div>
<div class="col-7 text-right"><span class="jic">{tPI}</span> kWh</div>
</div>
</div>
</div>