Fixed day graph

This commit is contained in:
Gunnar Skjold 2021-12-08 20:35:53 +01:00
parent e6d3b47d4f
commit a336f711b0
6 changed files with 131 additions and 49 deletions

View File

@ -563,6 +563,14 @@ bool AmsConfiguration::hasConfig() {
configVersion = 0;
return false;
}
case 89:
configVersion = -1; // Prevent loop
if(relocateConfig89()) {
configVersion = 90;
} else {
configVersion = 0;
return false;
}
case EEPROM_CHECK_SUM:
return true;
default:
@ -799,6 +807,30 @@ bool AmsConfiguration::relocateConfig88() {
return ret;
}
bool AmsConfiguration::relocateConfig89() {
EntsoeConfig89 entose89;
EEPROM.begin(EEPROM_SIZE);
EEPROM.get(CONFIG_ENTSOE_START_89, entose89);
uint32_t multiplier = entose89.multiplier;
EntsoeConfig entsoe = {
0x0,
0x0,
0x0,
multiplier
};
strcpy(entsoe.token, entose89.token);
strcpy(entsoe.area, entose89.area);
strcpy(entsoe.currency, entose89.currency);
EEPROM.put(CONFIG_ENTSOE_START, entsoe);
EEPROM.put(EEPROM_CONFIG_ADDRESS, 90);
bool ret = EEPROM.commit();
EEPROM.end();
return ret;
}
bool AmsConfiguration::save() {
EEPROM.begin(EEPROM_SIZE);
EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM);

View File

@ -4,7 +4,7 @@
#include "Arduino.h"
#define EEPROM_SIZE 1024*3
#define EEPROM_CHECK_SUM 89 // Used to check if config is stored. Change if structure changes
#define EEPROM_CHECK_SUM 90 // Used to check if config is stored. Change if structure changes
#define EEPROM_CONFIG_ADDRESS 0
#define EEPROM_TEMP_CONFIG_ADDRESS 2048
@ -12,16 +12,17 @@
#define CONFIG_WIFI_START 16
#define CONFIG_METER_START 224
#define CONFIG_GPIO_START 266
#define CONFIG_ENTSOE_START 286
#define CONFIG_WEB_START 648
#define CONFIG_DEBUG_START 824
#define CONFIG_DOMOTICZ_START 856
#define CONFIG_NTP_START 872
#define CONFIG_ENTSOE_START 944
#define CONFIG_MQTT_START 1004
#define CONFIG_MQTT_START_86 224
#define CONFIG_METER_START_87 784
#define CONFIG_GPIO_START_88 832
#define CONFIG_ENTSOE_START_89 944
struct SystemConfig {
@ -149,13 +150,20 @@ struct NtpConfig {
char server[64];
}; // 70
struct EntsoeConfig {
struct EntsoeConfig89 {
char token[37];
char area[17];
char currency[4];
uint16_t multiplier;
}; // 60
struct EntsoeConfig {
char token[37];
char area[17];
char currency[4];
uint32_t multiplier;
}; // 62
struct ConfigObject83 {
uint8_t boardType;
char wifiSsid[32];
@ -316,6 +324,7 @@ private:
bool relocateConfig86();
bool relocateConfig87();
bool relocateConfig88(); // dev 1.6
bool relocateConfig89(); // dev 1.6
int readString(int pAddress, char* pString[]);
int readInt(int pAddress, int *pValue);

View File

@ -40,11 +40,14 @@ bool AmsDataStorage::update(AmsData* data) {
}
tmElements_t tm, last;
breakTime(now, tm);
if(now > EPOCH_2021_01_01) {
tmElements_t last;
breakTime(now, tm);
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)) {
@ -55,6 +58,9 @@ bool AmsDataStorage::update(AmsData* data) {
}
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);
@ -64,15 +70,16 @@ bool AmsDataStorage::update(AmsData* data) {
}
for(int i = last.Day; i < tm.Day; i++) {
if(debugger->isActive(RemoteDebug::DEBUG)) {
//if(debugger->isActive(RemoteDebug::DEBUG)) {
debugger->printf("(AmsDataStorage) Clearing day: %d\n", i);
}
//}
setDay(i, 0);
}
}
}
if(data->getListType() != 3) return false;
else if(tm.Minute > 5) return false;
// Update day plot
if(day.activeImport == 0 || now - day.lastMeterReadTime > 86400) {
@ -87,9 +94,9 @@ bool AmsDataStorage::update(AmsData* data) {
int16_t val = (((data->getActiveImportCounter() * 1000) - day.activeImport) - ((data->getActiveExportCounter() * 1000) - day.activeExport));
setHour(tm.Hour, val);
if(debugger->isActive(RemoteDebug::INFO)) {
//if(debugger->isActive(RemoteDebug::INFO)) {
debugger->printf("(AmsDataStorage) Usage for hour %d: %d\n", tm.Hour, val);
}
//}
day.activeImport = data->getActiveImportCounter() * 1000;
day.activeExport = data->getActiveExportCounter() * 1000;
@ -101,28 +108,36 @@ bool AmsDataStorage::update(AmsData* data) {
float ipm = im / mins;
float epm = ex / mins;
while(now - day.lastMeterReadTime > 3590) {
time_t cur = day.lastMeterReadTime + 3600;
tmElements_t tm;
breakTime(cur, tm);
uint8_t minutes = 60 - tm.Minute;
float val = ((ipm * minutes) - (epm * minutes));
setHour(tm.Hour-1, val);
//if(debugger->isActive(RemoteDebug::DEBUG)) {
debugger->printf("(AmsDataStorage) Since last day update, minutes: %.1f, import: %d (%.2f/min), export: %d (%.2f/min)\n", mins, im, ipm, ex, epm);
//}
if(debugger->isActive(RemoteDebug::INFO)) {
debugger->printf("(AmsDataStorage) Estimated usage for hour %d: %d\n", tm.Hour, val);
}
breakTime(day.lastMeterReadTime, tm);
day.lastMeterReadTime = day.lastMeterReadTime - (tm.Minute * 60) - tm.Second;
breakTime(now, tm);
time_t stopAt = now - (tm.Minute * 60) - tm.Second;
while(day.lastMeterReadTime < stopAt) {
time_t cur = min(day.lastMeterReadTime + 3600, stopAt);
uint8_t minutes = round((cur - day.lastMeterReadTime) / 60.0);
if(minutes < 1) break;
breakTime(day.lastMeterReadTime, last);
float val = ((ipm * minutes) - (epm * minutes));
setHour(last.Hour, val);
//if(debugger->isActive(RemoteDebug::INFO)) {
debugger->printf("(AmsDataStorage) Estimated usage for hour %u: %.1f (%lu)\n", last.Hour, val, cur);
//}
day.activeImport += ipm * minutes;
day.activeExport += epm * minutes;
day.lastMeterReadTime += 60 * minutes;
day.lastMeterReadTime = cur;
}
}
// Update month plot
if(tz != NULL) {
time_t local = tz->toLocal(now);
breakTime(local, tm);
breakTime(tz->toLocal(now), tm);
} else {
breakTime(now, tm);
}
@ -159,21 +174,43 @@ bool AmsDataStorage::update(AmsData* data) {
float iph = im / hrs;
float eph = ex / hrs;
while(now - month.lastMeterReadTime > 86000) {
time_t cur = month.lastMeterReadTime + 86400;
tmElements_t tm;
breakTime(cur, tm);
uint8_t hours = 24 - tm.Hour;
//if(debugger->isActive(RemoteDebug::DEBUG)) {
debugger->printf("(AmsDataStorage) Since last month update, hours: %.1f, import: %d (%.2f/hr), export: %d (%.2f/hr)\n", hrs, im, iph, ex, eph);
//}
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(tz != NULL) {
breakTime(tz->toLocal(now), tm);
} else {
breakTime(now, tm);
}
time_t stopAt = now - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second;
while(month.lastMeterReadTime < stopAt) {
time_t cur = min(month.lastMeterReadTime + 86400, stopAt);
uint8_t hours = round((cur - month.lastMeterReadTime) / 3600.0);
if(tz != NULL) {
breakTime(tz->toLocal(month.lastMeterReadTime), last);
} else {
breakTime(month.lastMeterReadTime, last);
}
float val = ((iph * hours) - (eph * hours));
setDay(tm.Day-1, val);
setDay(last.Day, val);
//if(debugger->isActive(RemoteDebug::INFO)) {
debugger->printf("(AmsDataStorage) Estimated usage for day %d: %d\n", tm.Day, val);
debugger->printf("(AmsDataStorage) Estimated usage for day %u: %.1f (%lu)\n", last.Day, val, cur);
//}
month.activeImport += iph * hours;
month.activeExport += eph * hours;
month.lastMeterReadTime += 24 * hours;
month.lastMeterReadTime += cur;
}
}
}
@ -200,7 +237,7 @@ int32_t AmsDataStorage::getDay(uint8_t day) {
return (month.points[day-1] * 10);
}
bool AmsDataStorage::load(AmsData* meterState) {
bool AmsDataStorage::load() {
if(!LittleFS.begin()) {
if(debugger->isActive(RemoteDebug::ERROR)) {
debugger->printf("(AmsDataStorage) Unable to load LittleFS\n");

View File

@ -30,7 +30,7 @@ public:
bool update(AmsData*);
int16_t getHour(uint8_t);
int32_t getDay(uint8_t);
bool load(AmsData*);
bool load();
bool save();
private:

View File

@ -299,7 +299,7 @@ void setup() {
ds.setTimezone(tz);
}
ds.load(&meterState);
ds.load();
} else {
if(Debug.isActive(RemoteDebug::INFO)) {
debugI("No configuration, booting AP");
@ -752,20 +752,6 @@ void readHanPort() {
if(data.getListType() >= 2) {
mqttHandler->publishSystem(&hw);
}
time_t now = time(nullptr);
if(now < EPOCH_2021_01_01 && data.getListType() == 3 && !ntpEnabled) {
if(data.getMeterTimestamp() > EPOCH_2021_01_01) {
debugI("Using timestamp from meter");
now = data.getMeterTimestamp();
} else if(data.getPackageTimestamp() > EPOCH_2021_01_01) {
debugI("Using timestamp from meter (DLMS)");
now = data.getPackageTimestamp();
}
if(now > EPOCH_2021_01_01) {
timeval tv { now, 0};
settimeofday(&tv, nullptr);
}
}
}
if(mqtt != NULL) {
mqtt->loop();
@ -773,6 +759,24 @@ void readHanPort() {
}
}
time_t now = time(nullptr);
if(now < EPOCH_2021_01_01 && data.getListType() == 3 && !ntpEnabled) {
if(data.getMeterTimestamp() > EPOCH_2021_01_01) {
debugI("Using timestamp from meter");
now = data.getMeterTimestamp();
} else if(data.getPackageTimestamp() > EPOCH_2021_01_01) {
debugI("Using timestamp from meter (DLMS)");
now = data.getPackageTimestamp();
}
if(now > EPOCH_2021_01_01) {
timeval tv { now, 0};
settimeofday(&tv, nullptr);
}
}
if(meterState.getListType() < 3 && now > EPOCH_2021_01_01) {
// TODO: Load an estimated value from dayplot
}
meterState.apply(data);
if(ds.update(&data)) {

View File

@ -77,7 +77,7 @@ float EntsoeApi::getValueForHour(time_t cur, uint8_t hour) {
}
bool EntsoeApi::loop() {
if(strlen(config->token) == 0)
if(strlen(getToken()) == 0)
return false;
bool ret = false;
@ -116,7 +116,7 @@ bool EntsoeApi::loop() {
char url[256];
snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s",
"https://transparency.entsoe.eu/api", config->token,
"https://transparency.entsoe.eu/api", getToken(),
d1.Year+1970, d1.Month, d1.Day, 23, 00,
d2.Year+1970, d2.Month, d2.Day, 23, 00,
config->area, config->area);
@ -146,7 +146,7 @@ bool EntsoeApi::loop() {
char url[256];
snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s",
"https://transparency.entsoe.eu/api", config->token,
"https://transparency.entsoe.eu/api", getToken(),
d1.Year+1970, d1.Month, d1.Day, 23, 00,
d2.Year+1970, d2.Month, d2.Day, 23, 00,
config->area, config->area);