mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-01-18 09:21:57 +00:00
Fixed day graph
This commit is contained in:
parent
e6d3b47d4f
commit
a336f711b0
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)) {
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user