mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-16 08:43:13 +00:00
Month plot fix and some other things
This commit is contained in:
parent
8fe1a1edf2
commit
327fed6f08
@ -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;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -31,5 +31,6 @@
|
||||
"mm" : %d,
|
||||
"me" : %d,
|
||||
"p" : %s,
|
||||
"c" : %lu
|
||||
"c" : %lu,
|
||||
"mt" : %d
|
||||
}
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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">
|
||||
|
||||
@ -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>°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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user