From 1a92cd197808f8b1e0b54e980e4dde53a76ae380 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 12 Aug 2022 20:41:53 +0200 Subject: [PATCH 01/66] Fetch prices from hub --- platformio.ini | 2 +- src/AmsDataStorage.cpp | 4 +- src/AmsToMqttBridge.ino | 19 +-- src/entsoe/EntsoeA44Parser.cpp | 32 ++++ src/entsoe/EntsoeA44Parser.h | 2 + src/entsoe/EntsoeApi.cpp | 250 +++++++++++++++++++---------- src/entsoe/EntsoeApi.h | 10 +- src/entsoe/PricesContainer.h | 8 + src/entsoe/PricesFromHubStream.cpp | 4 + src/entsoe/PricesFromHubStream.h | 2 + src/web/AmsWebServer.cpp | 50 +++--- 11 files changed, 255 insertions(+), 128 deletions(-) create mode 100644 src/entsoe/PricesContainer.h diff --git a/platformio.ini b/platformio.ini index 37670bed..9e7a9d04 100755 --- a/platformio.ini +++ b/platformio.ini @@ -10,7 +10,7 @@ platform = espressif8266@3.2.0 framework = arduino board = esp12e board_build.ldscript = eagle.flash.4m2m.ld -build_flags = -D WEBSOCKET_DISABLED=1 +build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions lib_deps = ${common.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = diff --git a/src/AmsDataStorage.cpp b/src/AmsDataStorage.cpp index 091eef04..75bf4b56 100644 --- a/src/AmsDataStorage.cpp +++ b/src/AmsDataStorage.cpp @@ -67,7 +67,7 @@ bool AmsDataStorage::update(AmsData* data) { } tmElements_t last; breakTime(day.lastMeterReadTime, last); - for(int i = last.Hour; i < utc.Hour; i++) { + for(int i = last.Hour; i <= utc.Hour; i++) { if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) Clearing hour: %d\n", i); } @@ -90,7 +90,7 @@ bool AmsDataStorage::update(AmsData* data) { } tmElements_t last; breakTime(tz->toLocal(month.lastMeterReadTime), last); - for(int i = last.Day; i < ltz.Day; i++) { + for(int i = last.Day; i <= ltz.Day; i++) { if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) Clearing day: %d\n", i); } diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index e40d4e25..3e8ede72 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -195,14 +195,11 @@ void setup() { hw.ledBlink(LED_GREEN, 1); hw.ledBlink(LED_BLUE, 1); - #if defined(ESP32) EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe) && strlen(entsoe.token) > 0) { - eapi = new EntsoeApi(&Debug); - eapi->setup(entsoe); - ws.setEntsoeApi(eapi); - } - #endif + eapi = new EntsoeApi(&Debug); + config.getEntsoeConfig(entsoe); + eapi->setup(entsoe); + ws.setEntsoeApi(eapi); bool shared = false; config.getMeterConfig(meterConfig); @@ -514,7 +511,6 @@ void loop() { mqtt->disconnect(); } - #if defined(ESP32) try { if(eapi != NULL && ntpEnabled) { if(eapi->loop() && mqtt != NULL && mqttHandler != NULL && mqtt->connected()) { @@ -524,24 +520,19 @@ void loop() { if(config.isEntsoeChanged()) { EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe) && strlen(entsoe.token) > 0) { + if(config.getEntsoeConfig(entsoe)) { if(eapi == NULL) { eapi = new EntsoeApi(&Debug); ea.setEapi(eapi); ws.setEntsoeApi(eapi); } eapi->setup(entsoe); - } else if(eapi != NULL) { - delete eapi; - eapi = NULL; - ws.setEntsoeApi(NULL); } config.ackEntsoeChange(); } } catch(const std::exception& e) { debugE("Exception in ENTSO-E loop (%s)", e.what()); } - #endif ws.loop(); } if(mqtt != NULL) { diff --git a/src/entsoe/EntsoeA44Parser.cpp b/src/entsoe/EntsoeA44Parser.cpp index 1d7fa9b2..c08b5cb0 100644 --- a/src/entsoe/EntsoeA44Parser.cpp +++ b/src/entsoe/EntsoeA44Parser.cpp @@ -102,3 +102,35 @@ size_t EntsoeA44Parser::write(uint8_t byte) { } return 1; } + +void EntsoeA44Parser::get(PricesContainer* container) { + strcpy(container->currency, currency); + strcpy(container->measurementUnit, measurementUnit); + + container->points[0] = points[0] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[0] * 10000; + container->points[1] = points[1] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[1] * 10000; + container->points[2] = points[2] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[2] * 10000; + container->points[3] = points[3] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[3] * 10000; + container->points[4] = points[4] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[4] * 10000; + container->points[5] = points[5] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[5] * 10000; + container->points[6] = points[6] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[6] * 10000; + container->points[7] = points[7] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[7] * 10000; + container->points[8] = points[8] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[8] * 10000; + container->points[9] = points[9] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[9] * 10000; + + container->points[10] = points[10] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[10] * 10000; + container->points[11] = points[11] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[11] * 10000; + container->points[12] = points[12] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[12] * 10000; + container->points[13] = points[13] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[13] * 10000; + container->points[14] = points[14] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[14] * 10000; + container->points[15] = points[15] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[15] * 10000; + container->points[16] = points[16] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[16] * 10000; + container->points[17] = points[17] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[17] * 10000; + container->points[18] = points[18] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[18] * 10000; + container->points[19] = points[19] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[19] * 10000; + + container->points[20] = points[20] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[20] * 10000; + container->points[21] = points[21] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[21] * 10000; + container->points[22] = points[22] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[22] * 10000; + container->points[23] = points[23] == ENTSOE_NO_VALUE ? ENTSOE_NO_VALUE : points[23] * 10000; +} \ No newline at end of file diff --git a/src/entsoe/EntsoeA44Parser.h b/src/entsoe/EntsoeA44Parser.h index 4d860214..33154d63 100644 --- a/src/entsoe/EntsoeA44Parser.h +++ b/src/entsoe/EntsoeA44Parser.h @@ -2,6 +2,7 @@ #define _ENTSOEA44PARSER_H #include "Stream.h" +#include "PricesContainer.h" #define DOCPOS_SEEK 0 #define DOCPOS_CURRENCY 1 @@ -25,6 +26,7 @@ public: void flush(); size_t write(const uint8_t *buffer, size_t size); size_t write(uint8_t); + void get(PricesContainer*); private: char currency[4]; diff --git a/src/entsoe/EntsoeApi.cpp b/src/entsoe/EntsoeApi.cpp index 886e7201..e5c6b010 100644 --- a/src/entsoe/EntsoeApi.cpp +++ b/src/entsoe/EntsoeApi.cpp @@ -5,6 +5,8 @@ #include "DnbCurrParser.h" #include "version.h" +#include "ams/GcmParser.h" + #if defined(ESP32) #include #endif @@ -31,6 +33,12 @@ void EntsoeApi::setup(EntsoeConfig& config) { if(today != NULL) delete today; if(tomorrow != NULL) delete tomorrow; today = tomorrow = NULL; + + http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + http.setReuse(false); + http.setTimeout(60000); + http.setUserAgent("ams2mqtt/" + String(VERSION)); + http.useHTTP10(true); } char* EntsoeApi::getToken() { @@ -60,25 +68,33 @@ float EntsoeApi::getValueForHour(time_t cur, int8_t hour) { if(pos > 23) { if(tomorrow == NULL) return ENTSOE_NO_VALUE; - value = tomorrow->getPoint(pos-24); - if(value != ENTSOE_NO_VALUE && strcmp(tomorrow->getMeasurementUnit(), "MWH") == 0) { + if(tomorrow->points[pos-24] == ENTSOE_NO_VALUE) + return ENTSOE_NO_VALUE; + value = tomorrow->points[pos-24] / 10000.0; + if(strcmp(tomorrow->measurementUnit, "KWH") == 0) { + // Multiplier is 1 + } else if(strcmp(tomorrow->measurementUnit, "MWH") == 0) { multiplier *= 0.001; } else { return ENTSOE_NO_VALUE; } - float mult = getCurrencyMultiplier(tomorrow->getCurrency(), config->currency); + float mult = getCurrencyMultiplier(tomorrow->currency, config->currency); if(mult == 0) return ENTSOE_NO_VALUE; multiplier *= mult; } else if(pos >= 0) { if(today == NULL) return ENTSOE_NO_VALUE; - value = today->getPoint(pos); - if(value != ENTSOE_NO_VALUE && strcmp(today->getMeasurementUnit(), "MWH") == 0) { + if(today->points[pos] == ENTSOE_NO_VALUE) + return ENTSOE_NO_VALUE; + value = today->points[pos] / 10000.0; + if(strcmp(today->measurementUnit, "KWH") == 0) { + // Multiplier is 1 + } else if(strcmp(today->measurementUnit, "MWH") == 0) { multiplier *= 0.001; } else { return ENTSOE_NO_VALUE; } - float mult = getCurrencyMultiplier(today->getCurrency(), config->currency); + float mult = getCurrencyMultiplier(today->currency, config->currency); if(mult == 0) return ENTSOE_NO_VALUE; multiplier *= mult; } @@ -86,15 +102,22 @@ float EntsoeApi::getValueForHour(time_t cur, int8_t hour) { } bool EntsoeApi::loop() { - if(strlen(getToken()) == 0) - return false; - uint64_t now = millis64(); if(now < 10000) return false; // Grace period time_t t = time(nullptr); if(t < BUILD_EPOCH) return false; + #ifndef AMS2MQTT_PRICE_KEY + if(strlen(getToken()) == 0) { + return false; + } + #endif + if(strlen(config->area) == 0) + return false; + if(strlen(config->currency) == 0) + return false; + bool ret = false; tmElements_t tm; breakTime(tz->toLocal(t), tm); @@ -120,39 +143,10 @@ bool EntsoeApi::loop() { midnightMillis = 0; // Force new midnight millis calculation return true; } else { - breakTime(t, tm); // Break UTC to find UTC midnight if(today == NULL && (lastTodayFetch == 0 || now - lastTodayFetch > 60000)) { lastTodayFetch = now; - time_t e1 = t - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second; // UTC midnight - time_t e2 = e1 + SECS_PER_DAY; - tmElements_t d1, d2; - breakTime(tz->toUTC(e1), d1); // To get day and hour for CET/CEST at UTC midnight - breakTime(tz->toUTC(e2), d2); - - snprintf(buf, BufferSize, "%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", getToken(), - d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, - d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, - config->area, config->area); - - #if defined(ESP32) - esp_task_wdt_reset(); - #elif defined(ESP8266) - ESP.wdtFeed(); - #endif - - - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for today\n"); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); - EntsoeA44Parser* a44 = new EntsoeA44Parser(); - if(retrieve(buf, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { - today = a44; - return true; - } else if(a44 != NULL) { - delete a44; - today = NULL; - return false; - } + today = fetchPrices(t); + return today != NULL; } // Prices for next day are published at 13:00 CE(S)T, but to avoid heavy server traffic at that time, we will @@ -161,49 +155,18 @@ bool EntsoeApi::loop() { && midnightMillis - now < tomorrowFetchMillis && (lastTomorrowFetch == 0 || now - lastTomorrowFetch > 900000) ) { + breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight lastTomorrowFetch = now; - time_t e1 = t - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second + (SECS_PER_DAY); - time_t e2 = e1 + SECS_PER_DAY; - tmElements_t d1, d2; - breakTime(tz->toUTC(e1), d1); - breakTime(tz->toUTC(e2), d2); - - snprintf(buf, BufferSize, "%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", getToken(), - d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, - d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, - config->area, config->area); - - #if defined(ESP32) - esp_task_wdt_reset(); - #elif defined(ESP8266) - ESP.wdtFeed(); - #endif - - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for tomorrow\n"); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); - EntsoeA44Parser* a44 = new EntsoeA44Parser(); - if(retrieve(buf, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { - tomorrow = a44; - return true; - } else if(a44 != NULL) { - delete a44; - tomorrow = NULL; - return false; - } + tomorrow = fetchPrices(t+SECS_PER_DAY); + return tomorrow != NULL; } } return ret; } bool EntsoeApi::retrieve(const char* url, Stream* doc) { - HTTPClient https; - https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); - https.setReuse(false); - https.setTimeout(50000); - https.setUserAgent("ams2mqtt/" + String(VERSION)); #if defined(ESP32) - if(https.begin(url)) { + if(http.begin(url)) { printD("Connection established"); #if defined(ESP32) @@ -212,7 +175,7 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { ESP.wdtFeed(); #endif - int status = https.GET(); + int status = http.GET(); #if defined(ESP32) esp_task_wdt_reset(); @@ -222,15 +185,15 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { if(status == HTTP_CODE_OK) { printD("Receiving data"); - https.writeToStream(doc); - https.end(); + http.writeToStream(doc); + http.end(); return true; } else { if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); - printE(https.errorToString(status)); - printD(https.getString()); + printE(http.errorToString(status)); + printD(http.getString()); - https.end(); + http.end(); return false; } } else { @@ -282,6 +245,115 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { return currencyMultiplier; } +PricesContainer* EntsoeApi::fetchPrices(time_t t) { + tmElements_t tm; + breakTime(t, tm); + if(strlen(getToken()) == 0) { + String data; + snprintf(buf, BufferSize, "%s/%s/%d/%d/%d?currency=%s", + "http://ams2mqtt.rewiredinvent.no/hub/price", + config->area, + tm.Year+1970, + tm.Month, + tm.Day, + config->currency + ); + #if defined(ESP8266) + WiFiClient client; + client.setTimeout(5000); + if(http.begin(client, buf)) { + #elif defined(ESP32) + if(http.begin(buf)) { + #endif + int status = http.GET(); + + #if defined(ESP32) + esp_task_wdt_reset(); + #elif defined(ESP8266) + ESP.wdtFeed(); + #endif + + if(status == HTTP_CODE_OK) { + printD("Receiving data"); + data = http.getString(); + http.end(); + } else { + if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); + printE(http.errorToString(status)); + printD(http.getString()); + + http.end(); + } + } + uint8_t* content = (uint8_t*) (data.c_str()); + if(debugger->isActive(RemoteDebug::DEBUG)) { + printD("Received content for prices:"); + debugPrint(content, 0, data.length()); + } + + #if defined(AMS2MQTT_PRICE_KEY) + uint8_t key[] = AMS2MQTT_PRICE_KEY; + #else + uint8_t key[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + #endif + #if defined(AMS2MQTT_PRICE_AUTHENTICATION) + uint8_t auth[] = AMS2MQTT_PRICE_AUTHENTICATION; + #else + uint8_t auth[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + #endif + + DataParserContext ctx; + ctx.length = data.length(); + GCMParser gcm(key, auth); + int8_t gcmRet = gcm.parse(content, ctx); + if(debugger->isActive(RemoteDebug::DEBUG)) { + printD("Decrypted content for prices:"); + debugPrint(content, 0, data.length()); + } + if(gcmRet > 0) { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) Price data starting at: %d\n", gcmRet); + PricesContainer* ret = new PricesContainer(); + memcpy(ret, content+gcmRet, sizeof(*ret)); + for(uint8_t i = 0; i < 24; i++) { + ret->points[i] = ntohl(ret->points[i]); + } + return ret; + } else { + if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Error code while decrypting prices: %d\n", gcmRet); + } + } else { + time_t e1 = t - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second; // UTC midnight + time_t e2 = e1 + SECS_PER_DAY; + tmElements_t d1, d2; + breakTime(tz->toUTC(e1), d1); // To get day and hour for CET/CEST at UTC midnight + breakTime(tz->toUTC(e2), d2); + + snprintf(buf, BufferSize, "%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", getToken(), + d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, + d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, + config->area, config->area); + + #if defined(ESP32) + esp_task_wdt_reset(); + #elif defined(ESP8266) + ESP.wdtFeed(); + #endif + + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for %d.%d.%d\n", tm.Day, tm.Month, tm.Year+1970); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); + EntsoeA44Parser a44; + if(retrieve(buf, &a44) && a44.getPoint(0) != ENTSOE_NO_VALUE) { + PricesContainer* ret = new PricesContainer(); + a44.get(ret); + return ret; + } else { + return NULL; + } + } + return NULL; +} + void EntsoeApi::printD(String fmt, ...) { va_list args; va_start(args, fmt); @@ -295,3 +367,19 @@ void EntsoeApi::printE(String fmt, ...) { if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(String("(EntsoeApi)" + fmt + "\n").c_str(), args); va_end(args); } + +void EntsoeApi::debugPrint(byte *buffer, int start, int length) { + for (int i = start; i < start + length; i++) { + if (buffer[i] < 0x10) + debugger->print("0"); + debugger->print(buffer[i], HEX); + debugger->print(" "); + if ((i - start + 1) % 16 == 0) + debugger->println(""); + else if ((i - start + 1) % 4 == 0) + debugger->print(" "); + + yield(); // Let other get some resources too + } + debugger->println(""); +} diff --git a/src/entsoe/EntsoeApi.h b/src/entsoe/EntsoeApi.h index b382719c..28b270ed 100644 --- a/src/entsoe/EntsoeApi.h +++ b/src/entsoe/EntsoeApi.h @@ -4,8 +4,9 @@ #include "TimeLib.h" #include "Timezone.h" #include "RemoteDebug.h" -#include "EntsoeA44Parser.h" #include "AmsConfiguration.h" +#include "PricesFromHubStream.h" +#include "EntsoeA44Parser.h" #if defined(ESP8266) #include @@ -31,6 +32,7 @@ public: private: RemoteDebug* debugger; EntsoeConfig* config = NULL; + HTTPClient http; uint8_t currentDay = 0, currentHour = 0; uint32_t tomorrowFetchMillis = 36000000; // Number of ms before midnight. Default fetch 10hrs before midnight (14:00 CE(S)T) @@ -38,8 +40,8 @@ private: uint64_t lastTodayFetch = 0; uint64_t lastTomorrowFetch = 0; uint64_t lastCurrencyFetch = 0; - EntsoeA44Parser* today = NULL; - EntsoeA44Parser* tomorrow = NULL; + PricesContainer* today = NULL; + PricesContainer* tomorrow = NULL; Timezone* tz = NULL; @@ -48,10 +50,12 @@ private: float currencyMultiplier = 0; + PricesContainer* fetchPrices(time_t); bool retrieve(const char* url, Stream* doc); float getCurrencyMultiplier(const char* from, const char* to); void printD(String fmt, ...); void printE(String fmt, ...); + void debugPrint(byte *buffer, int start, int length); }; #endif diff --git a/src/entsoe/PricesContainer.h b/src/entsoe/PricesContainer.h new file mode 100644 index 00000000..cb6d687a --- /dev/null +++ b/src/entsoe/PricesContainer.h @@ -0,0 +1,8 @@ +#ifndef _PRICESCONTAINER_H +#define _PRICESCONTAINER_H +struct PricesContainer { + char currency[4]; + char measurementUnit[4]; + int32_t points[24]; +}; +#endif diff --git a/src/entsoe/PricesFromHubStream.cpp b/src/entsoe/PricesFromHubStream.cpp index f82f27c0..2e1e0ff3 100644 --- a/src/entsoe/PricesFromHubStream.cpp +++ b/src/entsoe/PricesFromHubStream.cpp @@ -27,3 +27,7 @@ size_t PricesFromHubStream::write(uint8_t b) { buf[pos++] = b; return 1; } + +void PricesFromHubStream::get(PricesContainer* container) { + memcpy(container, buf, pos); +} \ No newline at end of file diff --git a/src/entsoe/PricesFromHubStream.h b/src/entsoe/PricesFromHubStream.h index b672393d..ab25252a 100644 --- a/src/entsoe/PricesFromHubStream.h +++ b/src/entsoe/PricesFromHubStream.h @@ -2,6 +2,7 @@ #define _PRICESFROMHUBSTREAM_H #include "Stream.h" +#include "PricesContainer.h" class PricesFromHubStream: public Stream { public: @@ -9,6 +10,7 @@ public: int read(); int peek(); void flush(); + void get(PricesContainer*); size_t write(const uint8_t *buffer, size_t size); size_t write(uint8_t); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 13770818..e9522349 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -547,38 +547,34 @@ void AmsWebServer::configEntsoeHtml() { EntsoeConfig entsoe; config->getEntsoeConfig(entsoe); - if(ESP.getFreeHeap() > 25000) { - String html = String((const __FlashStringHelper*) ENTSOE_HTML); + String html = String((const __FlashStringHelper*) ENTSOE_HTML); - html.replace("{et}", entsoe.token); - html.replace("{em}", String(entsoe.multiplier / 1000.0, 3)); + html.replace("{et}", entsoe.token); + html.replace("{em}", String(entsoe.multiplier / 1000.0, 3)); - html.replace("{eaNo1}", strcmp(entsoe.area, "10YNO-1--------2") == 0 ? "selected" : ""); - html.replace("{eaNo2}", strcmp(entsoe.area, "10YNO-2--------T") == 0 ? "selected" : ""); - html.replace("{eaNo3}", strcmp(entsoe.area, "10YNO-3--------J") == 0 ? "selected" : ""); - html.replace("{eaNo4}", strcmp(entsoe.area, "10YNO-4--------9") == 0 ? "selected" : ""); - html.replace("{eaNo5}", strcmp(entsoe.area, "10Y1001A1001A48H") == 0 ? "selected" : ""); + html.replace("{eaNo1}", strcmp(entsoe.area, "10YNO-1--------2") == 0 ? "selected" : ""); + html.replace("{eaNo2}", strcmp(entsoe.area, "10YNO-2--------T") == 0 ? "selected" : ""); + html.replace("{eaNo3}", strcmp(entsoe.area, "10YNO-3--------J") == 0 ? "selected" : ""); + html.replace("{eaNo4}", strcmp(entsoe.area, "10YNO-4--------9") == 0 ? "selected" : ""); + html.replace("{eaNo5}", strcmp(entsoe.area, "10Y1001A1001A48H") == 0 ? "selected" : ""); - html.replace("{eaSe1}", strcmp(entsoe.area, "10Y1001A1001A44P") == 0 ? "selected" : ""); - html.replace("{eaSe2}", strcmp(entsoe.area, "10Y1001A1001A45N") == 0 ? "selected" : ""); - html.replace("{eaSe3}", strcmp(entsoe.area, "10Y1001A1001A46L") == 0 ? "selected" : ""); - html.replace("{eaSe4}", strcmp(entsoe.area, "10Y1001A1001A47J") == 0 ? "selected" : ""); + html.replace("{eaSe1}", strcmp(entsoe.area, "10Y1001A1001A44P") == 0 ? "selected" : ""); + html.replace("{eaSe2}", strcmp(entsoe.area, "10Y1001A1001A45N") == 0 ? "selected" : ""); + html.replace("{eaSe3}", strcmp(entsoe.area, "10Y1001A1001A46L") == 0 ? "selected" : ""); + html.replace("{eaSe4}", strcmp(entsoe.area, "10Y1001A1001A47J") == 0 ? "selected" : ""); - html.replace("{eaDk1}", strcmp(entsoe.area, "10YDK-1--------W") == 0 ? "selected" : ""); - html.replace("{eaDk2}", strcmp(entsoe.area, "10YDK-2--------M") == 0 ? "selected" : ""); + html.replace("{eaDk1}", strcmp(entsoe.area, "10YDK-1--------W") == 0 ? "selected" : ""); + html.replace("{eaDk2}", strcmp(entsoe.area, "10YDK-2--------M") == 0 ? "selected" : ""); - html.replace("{ecNOK}", strcmp(entsoe.currency, "NOK") == 0 ? "selected" : ""); - html.replace("{ecSEK}", strcmp(entsoe.currency, "SEK") == 0 ? "selected" : ""); - html.replace("{ecDKK}", strcmp(entsoe.currency, "DKK") == 0 ? "selected" : ""); - html.replace("{ecEUR}", strcmp(entsoe.currency, "EUR") == 0 ? "selected" : ""); + html.replace("{ecNOK}", strcmp(entsoe.currency, "NOK") == 0 ? "selected" : ""); + html.replace("{ecSEK}", strcmp(entsoe.currency, "SEK") == 0 ? "selected" : ""); + html.replace("{ecDKK}", strcmp(entsoe.currency, "DKK") == 0 ? "selected" : ""); + html.replace("{ecEUR}", strcmp(entsoe.currency, "EUR") == 0 ? "selected" : ""); - server.setContentLength(html.length() + HEAD_HTML_LEN + FOOT_HTML_LEN); - server.send_P(200, MIME_HTML, HEAD_HTML); - server.sendContent(html); - server.sendContent_P(FOOT_HTML); - } else { - notFound(); - } + server.setContentLength(html.length() + HEAD_HTML_LEN + FOOT_HTML_LEN); + server.send_P(200, MIME_HTML, HEAD_HTML); + server.sendContent(html); + server.sendContent_P(FOOT_HTML); } void AmsWebServer::configThresholdsHtml() { @@ -705,7 +701,7 @@ void AmsWebServer::dataJson() { } float price = ENTSOE_NO_VALUE; - if(eapi != NULL && strlen(eapi->getToken()) > 0) + if(eapi != NULL) price = eapi->getValueForHour(0); snprintf_P(buf, BufferSize, DATA_JSON, From 68b3415a6c776874c0328fd057a8574fbc24ff37 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 13 Aug 2022 16:32:55 +0200 Subject: [PATCH 02/66] Cleanup for price API --- src/AmsConfiguration.cpp | 6 +-- src/AmsToMqttBridge.ino | 16 +++--- src/entsoe/EntsoeApi.cpp | 85 ++++++++++++++++-------------- src/entsoe/EntsoeApi.h | 5 +- src/web/AmsWebServer.cpp | 20 ++++--- src/web/AmsWebServer.h | 2 +- web/head.html | 2 +- web/{entsoe.html => priceapi.html} | 19 +++---- 8 files changed, 85 insertions(+), 70 deletions(-) rename web/{entsoe.html => priceapi.html} (92%) diff --git a/src/AmsConfiguration.cpp b/src/AmsConfiguration.cpp index 0d03f68c..c3079bfe 100644 --- a/src/AmsConfiguration.cpp +++ b/src/AmsConfiguration.cpp @@ -1059,12 +1059,12 @@ void AmsConfiguration::print(Print* debugger) EntsoeConfig entsoe; if(getEntsoeConfig(entsoe)) { - debugger->println("--ENTSO-E configuration--"); - debugger->printf("Token: %s\r\n", entsoe.token); - if(strlen(entsoe.token) > 0) { + if(strlen(entsoe.area) > 0) { + debugger->println("--ENTSO-E configuration--"); debugger->printf("Area: %s\r\n", entsoe.area); debugger->printf("Currency: %s\r\n", entsoe.currency); debugger->printf("Multiplier: %f\r\n", entsoe.multiplier / 1000.0); + debugger->printf("Token: %s\r\n", entsoe.token); } debugger->println(""); delay(10); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 0eb1ad23..a20dd0b2 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -196,11 +196,11 @@ void setup() { hw.ledBlink(LED_BLUE, 1); EntsoeConfig entsoe; - eapi = new EntsoeApi(&Debug); - config.getEntsoeConfig(entsoe); - eapi->setup(entsoe); - ws.setEntsoeApi(eapi); - + if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) { + eapi = new EntsoeApi(&Debug); + eapi->setup(entsoe); + ws.setEntsoeApi(eapi); + } bool shared = false; config.getMeterConfig(meterConfig); Serial.flush(); @@ -520,13 +520,17 @@ void loop() { if(config.isEntsoeChanged()) { EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe)) { + if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) { if(eapi == NULL) { eapi = new EntsoeApi(&Debug); ea.setEapi(eapi); ws.setEntsoeApi(eapi); } eapi->setup(entsoe); + } else if(eapi != NULL) { + delete eapi; + eapi = NULL; + ws.setEntsoeApi(NULL); } config.ackEntsoeChange(); } diff --git a/src/entsoe/EntsoeApi.cpp b/src/entsoe/EntsoeApi.cpp index e5c6b010..793d024b 100644 --- a/src/entsoe/EntsoeApi.cpp +++ b/src/entsoe/EntsoeApi.cpp @@ -39,6 +39,20 @@ void EntsoeApi::setup(EntsoeConfig& config) { http.setTimeout(60000); http.setUserAgent("ams2mqtt/" + String(VERSION)); http.useHTTP10(true); + + #if defined(AMS2MQTT_PRICE_KEY) + key = new uint8_t[16] AMS2MQTT_PRICE_KEY; + hub = true; + #else + hub = false; + #endif + #if defined(AMS2MQTT_PRICE_AUTHENTICATION) + auth = new uint8_t[16] AMS2MQTT_PRICE_AUTHENTICATION; + hub = hub && true; + #else + hub = false; + #endif + } char* EntsoeApi::getToken() { @@ -248,7 +262,36 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { PricesContainer* EntsoeApi::fetchPrices(time_t t) { tmElements_t tm; breakTime(t, tm); - if(strlen(getToken()) == 0) { + if(strlen(getToken()) > 0) { + time_t e1 = t - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second; // UTC midnight + time_t e2 = e1 + SECS_PER_DAY; + tmElements_t d1, d2; + breakTime(tz->toUTC(e1), d1); // To get day and hour for CET/CEST at UTC midnight + breakTime(tz->toUTC(e2), d2); + + snprintf(buf, BufferSize, "%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", getToken(), + d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, + d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, + config->area, config->area); + + #if defined(ESP32) + esp_task_wdt_reset(); + #elif defined(ESP8266) + ESP.wdtFeed(); + #endif + + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for %d.%d.%d\n", tm.Day, tm.Month, tm.Year+1970); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); + EntsoeA44Parser a44; + if(retrieve(buf, &a44) && a44.getPoint(0) != ENTSOE_NO_VALUE) { + PricesContainer* ret = new PricesContainer(); + a44.get(ret); + return ret; + } else { + return NULL; + } + } else if(hub) { String data; snprintf(buf, BufferSize, "%s/%s/%d/%d/%d?currency=%s", "http://ams2mqtt.rewiredinvent.no/hub/price", @@ -291,17 +334,6 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { debugPrint(content, 0, data.length()); } - #if defined(AMS2MQTT_PRICE_KEY) - uint8_t key[] = AMS2MQTT_PRICE_KEY; - #else - uint8_t key[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - #endif - #if defined(AMS2MQTT_PRICE_AUTHENTICATION) - uint8_t auth[] = AMS2MQTT_PRICE_AUTHENTICATION; - #else - uint8_t auth[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - #endif - DataParserContext ctx; ctx.length = data.length(); GCMParser gcm(key, auth); @@ -321,35 +353,6 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { } else { if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Error code while decrypting prices: %d\n", gcmRet); } - } else { - time_t e1 = t - (tm.Hour * 3600) - (tm.Minute * 60) - tm.Second; // UTC midnight - time_t e2 = e1 + SECS_PER_DAY; - tmElements_t d1, d2; - breakTime(tz->toUTC(e1), d1); // To get day and hour for CET/CEST at UTC midnight - breakTime(tz->toUTC(e2), d2); - - snprintf(buf, BufferSize, "%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", getToken(), - d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, - d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, - config->area, config->area); - - #if defined(ESP32) - esp_task_wdt_reset(); - #elif defined(ESP8266) - ESP.wdtFeed(); - #endif - - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for %d.%d.%d\n", tm.Day, tm.Month, tm.Year+1970); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); - EntsoeA44Parser a44; - if(retrieve(buf, &a44) && a44.getPoint(0) != ENTSOE_NO_VALUE) { - PricesContainer* ret = new PricesContainer(); - a44.get(ret); - return ret; - } else { - return NULL; - } } return NULL; } diff --git a/src/entsoe/EntsoeApi.h b/src/entsoe/EntsoeApi.h index 28b270ed..4e21466e 100644 --- a/src/entsoe/EntsoeApi.h +++ b/src/entsoe/EntsoeApi.h @@ -5,7 +5,6 @@ #include "Timezone.h" #include "RemoteDebug.h" #include "AmsConfiguration.h" -#include "PricesFromHubStream.h" #include "EntsoeA44Parser.h" #if defined(ESP8266) @@ -48,6 +47,10 @@ private: static const uint16_t BufferSize = 256; char* buf; + bool hub = false; + uint8_t* key = NULL; + uint8_t* auth = NULL; + float currencyMultiplier = 0; PricesContainer* fetchPrices(time_t); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index e9522349..15769ab3 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -18,7 +18,7 @@ #include "root/mqtt_html.h" #include "root/web_html.h" #include "root/domoticz_html.h" -#include "root/entsoe_html.h" +#include "root/priceapi_html.h" #include "root/ntp_html.h" #include "root/gpio_html.h" #include "root/debugging_html.h" @@ -71,7 +71,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on("/mqtt", HTTP_GET, std::bind(&AmsWebServer::configMqttHtml, this)); server.on("/web", HTTP_GET, std::bind(&AmsWebServer::configWebHtml, this)); server.on("/domoticz",HTTP_GET, std::bind(&AmsWebServer::configDomoticzHtml, this)); - server.on("/entsoe",HTTP_GET, std::bind(&AmsWebServer::configEntsoeHtml, this)); + server.on("/priceapi",HTTP_GET, std::bind(&AmsWebServer::configPriceApiHtml, this)); server.on("/thresholds",HTTP_GET, std::bind(&AmsWebServer::configThresholdsHtml, this)); server.on("/boot.css", HTTP_GET, std::bind(&AmsWebServer::bootCss, this)); server.on("/github.svg", HTTP_GET, std::bind(&AmsWebServer::githubSvg, this)); @@ -538,8 +538,8 @@ void AmsWebServer::configDomoticzHtml() { server.sendContent_P(FOOT_HTML); } -void AmsWebServer::configEntsoeHtml() { - printD("Serving /entsoe.html over http..."); +void AmsWebServer::configPriceApiHtml() { + printD("Serving /priceapi.html over http..."); if(!checkSecurity(1)) return; @@ -547,9 +547,15 @@ void AmsWebServer::configEntsoeHtml() { EntsoeConfig entsoe; config->getEntsoeConfig(entsoe); - String html = String((const __FlashStringHelper*) ENTSOE_HTML); + String html = String((const __FlashStringHelper*) PRICEAPI_HTML); - html.replace("{et}", entsoe.token); + if(ESP.getFreeHeap() > 32000) { + html.replace("{et}", entsoe.token); + html.replace("{dt}", ""); + } else { + html.replace("{et}", ""); + html.replace("{dt}", "d-none"); + } html.replace("{em}", String(entsoe.multiplier / 1000.0, 3)); html.replace("{eaNo1}", strcmp(entsoe.area, "10YNO-1--------2") == 0 ? "selected" : ""); @@ -1664,8 +1670,6 @@ void AmsWebServer::firmwareUpload() { } } -const uint8_t githubFingerprint[] = {0x59, 0x74, 0x61, 0x88, 0x13, 0xCA, 0x12, 0x34, 0x15, 0x4D, 0x11, 0x0A, 0xC1, 0x7F, 0xE6, 0x67, 0x07, 0x69, 0x42, 0xF5}; - void AmsWebServer::firmwareDownload() { if(!checkSecurity(1)) return; diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index 0a0ac6b3..bee1b1f0 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -84,7 +84,7 @@ private: void configMqttHtml(); void configWebHtml(); void configDomoticzHtml(); - void configEntsoeHtml(); + void configPriceApiHtml(); void configNtpHtml(); void configGpioHtml(); void configDebugHtml(); diff --git a/web/head.html b/web/head.html index 343c3c8f..5bad2571 100644 --- a/web/head.html +++ b/web/head.html @@ -63,7 +63,7 @@ MQTT Web NTP - ENTSO-E API + Price API
Documentation diff --git a/web/entsoe.html b/web/priceapi.html similarity index 92% rename from web/entsoe.html rename to web/priceapi.html index 43b254c9..217fdc71 100644 --- a/web/entsoe.html +++ b/web/priceapi.html @@ -1,22 +1,15 @@
-
ENTSO-E API
+
Price API
-
-
-
- Token -
- -
-
Region
+
+
+
+ ENTSO-E token +
+ +
+

From 8b0d4185d386ccc298379eb8ecd6ae19ef95a9cc Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 3 Sep 2022 12:19:56 +0200 Subject: [PATCH 03/66] Created new UI with Svelte --- .gitignore | 2 + ui/svelte/.gitignore | 24 + ui/svelte/index.html | 12 + ui/svelte/jsconfig.json | 34 + ui/svelte/package-lock.json | 3106 ++++++++++++++++++++++ ui/svelte/package.json | 22 + ui/svelte/postcss.config.cjs | 13 + ui/svelte/src/App.svelte | 15 + ui/svelte/src/app.postcss | 8 + ui/svelte/src/assets/github.svg | 6 + ui/svelte/src/lib/AccountingData.svelte | 33 + ui/svelte/src/lib/AmpPlot.svelte | 64 + ui/svelte/src/lib/Badge.svelte | 14 + ui/svelte/src/lib/BarChart.svelte | 121 + ui/svelte/src/lib/Clock.svelte | 12 + ui/svelte/src/lib/Counter.svelte | 10 + ui/svelte/src/lib/Dashboard.svelte | 78 + ui/svelte/src/lib/DataStores.js | 72 + ui/svelte/src/lib/DayPlot.svelte | 92 + ui/svelte/src/lib/Header.svelte | 35 + ui/svelte/src/lib/Helpers.js | 44 + ui/svelte/src/lib/MonthPlot.svelte | 93 + ui/svelte/src/lib/PowerGauge.svelte | 43 + ui/svelte/src/lib/PowerGaugeSvg.svelte | 39 + ui/svelte/src/lib/PricePlot.svelte | 85 + ui/svelte/src/lib/ReactiveData.svelte | 24 + ui/svelte/src/lib/TemperaturePlot.svelte | 72 + ui/svelte/src/lib/VoltPlot.svelte | 61 + ui/svelte/src/main.js | 9 + ui/svelte/src/vite-env.d.ts | 2 + ui/svelte/svelte.config.js | 11 + ui/svelte/tailwind.config.cjs | 11 + ui/svelte/vite.config.js | 16 + 33 files changed, 4283 insertions(+) create mode 100644 ui/svelte/.gitignore create mode 100644 ui/svelte/index.html create mode 100644 ui/svelte/jsconfig.json create mode 100644 ui/svelte/package-lock.json create mode 100644 ui/svelte/package.json create mode 100644 ui/svelte/postcss.config.cjs create mode 100644 ui/svelte/src/App.svelte create mode 100644 ui/svelte/src/app.postcss create mode 100644 ui/svelte/src/assets/github.svg create mode 100644 ui/svelte/src/lib/AccountingData.svelte create mode 100644 ui/svelte/src/lib/AmpPlot.svelte create mode 100644 ui/svelte/src/lib/Badge.svelte create mode 100644 ui/svelte/src/lib/BarChart.svelte create mode 100644 ui/svelte/src/lib/Clock.svelte create mode 100644 ui/svelte/src/lib/Counter.svelte create mode 100644 ui/svelte/src/lib/Dashboard.svelte create mode 100644 ui/svelte/src/lib/DataStores.js create mode 100644 ui/svelte/src/lib/DayPlot.svelte create mode 100644 ui/svelte/src/lib/Header.svelte create mode 100644 ui/svelte/src/lib/Helpers.js create mode 100644 ui/svelte/src/lib/MonthPlot.svelte create mode 100644 ui/svelte/src/lib/PowerGauge.svelte create mode 100644 ui/svelte/src/lib/PowerGaugeSvg.svelte create mode 100644 ui/svelte/src/lib/PricePlot.svelte create mode 100644 ui/svelte/src/lib/ReactiveData.svelte create mode 100644 ui/svelte/src/lib/TemperaturePlot.svelte create mode 100644 ui/svelte/src/lib/VoltPlot.svelte create mode 100644 ui/svelte/src/main.js create mode 100644 ui/svelte/src/vite-env.d.ts create mode 100644 ui/svelte/svelte.config.js create mode 100644 ui/svelte/tailwind.config.cjs create mode 100644 ui/svelte/vite.config.js diff --git a/.gitignore b/.gitignore index 8fa788c6..9a9d7b4c 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ platformio-user.ini /sdkconfig /.tmp /*.zip +node_modules +/gui/dist \ No newline at end of file diff --git a/ui/svelte/.gitignore b/ui/svelte/.gitignore new file mode 100644 index 00000000..a547bf36 --- /dev/null +++ b/ui/svelte/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/ui/svelte/index.html b/ui/svelte/index.html new file mode 100644 index 00000000..4a138bae --- /dev/null +++ b/ui/svelte/index.html @@ -0,0 +1,12 @@ + + + + + + AMS reader + + +
+ + + diff --git a/ui/svelte/jsconfig.json b/ui/svelte/jsconfig.json new file mode 100644 index 00000000..ee5e92f2 --- /dev/null +++ b/ui/svelte/jsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "moduleResolution": "Node", + "target": "ESNext", + "module": "ESNext", + /** + * svelte-preprocess cannot figure out whether you have + * a value or a type, so tell TypeScript to enforce using + * `import type` instead of `import` for Types. + */ + "importsNotUsedAsValues": "error", + "isolatedModules": true, + "resolveJsonModule": true, + /** + * To have warnings / errors of the Svelte compiler at the + * correct position, enable source maps by default. + */ + "sourceMap": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "baseUrl": ".", + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable this if you'd like to use dynamic types. + */ + "checkJs": true + }, + /** + * Use global.d.ts instead of compilerOptions.types + * to avoid limiting type declarations. + */ + "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"] +} diff --git a/ui/svelte/package-lock.json b/ui/svelte/package-lock.json new file mode 100644 index 00000000..01780a58 --- /dev/null +++ b/ui/svelte/package-lock.json @@ -0,0 +1,3106 @@ +{ + "name": "svelte-gui", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "svelte-gui", + "version": "0.0.0", + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "autoprefixer": "^10.4.7", + "http-proxy-middleware": "^2.0.1", + "postcss": "^8.4.14", + "postcss-load-config": "^4.0.1", + "svelte": "^3.49.0", + "svelte-preprocess": "^4.10.7", + "tailwindcss": "^3.1.5", + "vite": "^3.0.7" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "dependencies": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/@sveltejs/vite-plugin-svelte": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.4.tgz", + "integrity": "sha512-UZco2fdj0OVuRWC0SUJjEOftITc2IeHLFJNp00ym9MuQ9dShnlO4P29G8KUxRlcS7kSpzHuko6eCR9MOALj7lQ==", + "dev": true, + "dependencies": { + "@rollup/pluginutils": "^4.2.1", + "debug": "^4.3.4", + "deepmerge": "^4.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.26.2", + "svelte-hmr": "^0.14.12" + }, + "engines": { + "node": "^14.18.0 || >= 16" + }, + "peerDependencies": { + "diff-match-patch": "^1.0.5", + "svelte": "^3.44.0", + "vite": "^3.0.0 || ^3.1.0-beta.1" + }, + "peerDependenciesMeta": { + "diff-match-patch": { + "optional": true + } + } + }, + "node_modules/@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "18.7.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz", + "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", + "dev": true + }, + "node_modules/@types/pug": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", + "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", + "dev": true + }, + "node_modules/@types/sass": { + "version": "1.43.1", + "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz", + "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "node_modules/autoprefixer": { + "version": "10.4.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", + "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.3", + "caniuse-lite": "^1.0.30001373", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001388", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001388.tgz", + "integrity": "sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", + "dev": true + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "dependencies": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "node_modules/electron-to-chromium": { + "version": "1.4.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.240.tgz", + "integrity": "sha512-r20dUOtZ4vUPTqAajDGonIM1uas5tf85Up+wPdtNBNvBSqGCfkpvMVvQ1T8YJzPV9/Y9g3FbUDcXb94Rafycow==", + "dev": true + }, + "node_modules/es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "node_modules/esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/magic-string": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.3.tgz", + "integrity": "sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dev": true, + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + }, + "engines": { + "node": ">= 14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.6" + }, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "dependencies": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "node_modules/sorcery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", + "integrity": "sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==", + "dev": true, + "dependencies": { + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0", + "sourcemap-codec": "^1.3.0" + }, + "bin": { + "sorcery": "bin/index.js" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svelte": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.49.0.tgz", + "integrity": "sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/svelte-hmr": { + "version": "0.14.12", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.14.12.tgz", + "integrity": "sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==", + "dev": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": ">=3.19.0" + } + }, + "node_modules/svelte-preprocess": { + "version": "4.10.7", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.7.tgz", + "integrity": "sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@types/pug": "^2.0.4", + "@types/sass": "^1.16.0", + "detect-indent": "^6.0.0", + "magic-string": "^0.25.7", + "sorcery": "^0.10.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">= 9.11.2" + }, + "peerDependencies": { + "@babel/core": "^7.10.2", + "coffeescript": "^2.5.1", + "less": "^3.11.3 || ^4.0.0", + "postcss": "^7 || ^8", + "postcss-load-config": "^2.1.0 || ^3.0.0 || ^4.0.0", + "pug": "^3.0.0", + "sass": "^1.26.8", + "stylus": "^0.55.0", + "sugarss": "^2.0.0", + "svelte": "^3.23.0", + "typescript": "^3.9.5 || ^4.0.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "coffeescript": { + "optional": true + }, + "less": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "postcss": { + "optional": true + }, + "postcss-load-config": { + "optional": true + }, + "pug": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/svelte-preprocess/node_modules/magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.8" + } + }, + "node_modules/tailwindcss": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", + "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==", + "dev": true, + "dependencies": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.14", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "5.0.6", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "node_modules/tailwindcss/node_modules/postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "dependencies": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": ">=8.0.9", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "postcss": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/tailwindcss/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.6.tgz", + "integrity": "sha512-We7BqM9XFlcW94Op93uW8+2LXvGezs7QA0WY+f1H7RR1q46B06W6hZF6LbmOlpCS1HU22q/6NOGTGW5sCm7NJQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/vite": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.0.9.tgz", + "integrity": "sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==", + "dev": true, + "dependencies": { + "esbuild": "^0.14.47", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": ">=2.75.6 <2.77.0 || ~2.77.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "less": "*", + "sass": "*", + "stylus": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yaml": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz", + "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==", + "dev": true, + "engines": { + "node": ">= 14" + } + } + }, + "dependencies": { + "@esbuild/linux-loong64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz", + "integrity": "sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw==", + "dev": true, + "optional": true + }, + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@rollup/pluginutils": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz", + "integrity": "sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==", + "dev": true, + "requires": { + "estree-walker": "^2.0.1", + "picomatch": "^2.2.2" + } + }, + "@sveltejs/vite-plugin-svelte": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@sveltejs/vite-plugin-svelte/-/vite-plugin-svelte-1.0.4.tgz", + "integrity": "sha512-UZco2fdj0OVuRWC0SUJjEOftITc2IeHLFJNp00ym9MuQ9dShnlO4P29G8KUxRlcS7kSpzHuko6eCR9MOALj7lQ==", + "dev": true, + "requires": { + "@rollup/pluginutils": "^4.2.1", + "debug": "^4.3.4", + "deepmerge": "^4.2.2", + "kleur": "^4.1.5", + "magic-string": "^0.26.2", + "svelte-hmr": "^0.14.12" + } + }, + "@types/http-proxy": { + "version": "1.17.9", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.9.tgz", + "integrity": "sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "18.7.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz", + "integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA==", + "dev": true + }, + "@types/pug": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.6.tgz", + "integrity": "sha512-SnHmG9wN1UVmagJOnyo/qkk0Z7gejYxOYYmaAwr5u2yFYfsupN3sg10kyzN8Hep/2zbHxCnsumxOoRIRMBwKCg==", + "dev": true + }, + "@types/sass": { + "version": "1.43.1", + "resolved": "https://registry.npmjs.org/@types/sass/-/sass-1.43.1.tgz", + "integrity": "sha512-BPdoIt1lfJ6B7rw35ncdwBZrAssjcwzI5LByIrYs+tpXlj/CAkuVdRsgZDdP4lq5EjyWzwxZCqAoFyHKFwp32g==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true + }, + "autoprefixer": { + "version": "10.4.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz", + "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==", + "dev": true, + "requires": { + "browserslist": "^4.21.3", + "caniuse-lite": "^1.0.30001373", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001388", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001388.tgz", + "integrity": "sha512-znVbq4OUjqgLxMxoNX2ZeeLR0d7lcDiE5uJ4eUiWdml1J1EkxbnQq6opT9jb9SMfJxB0XA16/ziHwni4u1I3GQ==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha512-Y2caI5+ZwS5c3RiNDJ6u53VhQHv+hHKwhkI1iHvceKUHw9Df6EK2zRLfjejRgMuCuxK7PfSWIMwWecceVvThjQ==", + "dev": true + }, + "detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true + }, + "detective": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", + "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", + "dev": true, + "requires": { + "acorn-node": "^1.8.2", + "defined": "^1.0.0", + "minimist": "^1.2.6" + } + }, + "didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "dev": true + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.4.240", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.240.tgz", + "integrity": "sha512-r20dUOtZ4vUPTqAajDGonIM1uas5tf85Up+wPdtNBNvBSqGCfkpvMVvQ1T8YJzPV9/Y9g3FbUDcXb94Rafycow==", + "dev": true + }, + "es6-promise": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", + "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", + "dev": true + }, + "esbuild": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz", + "integrity": "sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA==", + "dev": true, + "requires": { + "@esbuild/linux-loong64": "0.14.54", + "esbuild-android-64": "0.14.54", + "esbuild-android-arm64": "0.14.54", + "esbuild-darwin-64": "0.14.54", + "esbuild-darwin-arm64": "0.14.54", + "esbuild-freebsd-64": "0.14.54", + "esbuild-freebsd-arm64": "0.14.54", + "esbuild-linux-32": "0.14.54", + "esbuild-linux-64": "0.14.54", + "esbuild-linux-arm": "0.14.54", + "esbuild-linux-arm64": "0.14.54", + "esbuild-linux-mips64le": "0.14.54", + "esbuild-linux-ppc64le": "0.14.54", + "esbuild-linux-riscv64": "0.14.54", + "esbuild-linux-s390x": "0.14.54", + "esbuild-netbsd-64": "0.14.54", + "esbuild-openbsd-64": "0.14.54", + "esbuild-sunos-64": "0.14.54", + "esbuild-windows-32": "0.14.54", + "esbuild-windows-64": "0.14.54", + "esbuild-windows-arm64": "0.14.54" + } + }, + "esbuild-android-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz", + "integrity": "sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ==", + "dev": true, + "optional": true + }, + "esbuild-android-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz", + "integrity": "sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg==", + "dev": true, + "optional": true + }, + "esbuild-darwin-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz", + "integrity": "sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug==", + "dev": true, + "optional": true + }, + "esbuild-darwin-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz", + "integrity": "sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz", + "integrity": "sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg==", + "dev": true, + "optional": true + }, + "esbuild-freebsd-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz", + "integrity": "sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q==", + "dev": true, + "optional": true + }, + "esbuild-linux-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz", + "integrity": "sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw==", + "dev": true, + "optional": true + }, + "esbuild-linux-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz", + "integrity": "sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz", + "integrity": "sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw==", + "dev": true, + "optional": true + }, + "esbuild-linux-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz", + "integrity": "sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig==", + "dev": true, + "optional": true + }, + "esbuild-linux-mips64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz", + "integrity": "sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw==", + "dev": true, + "optional": true + }, + "esbuild-linux-ppc64le": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz", + "integrity": "sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ==", + "dev": true, + "optional": true + }, + "esbuild-linux-riscv64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz", + "integrity": "sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg==", + "dev": true, + "optional": true + }, + "esbuild-linux-s390x": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz", + "integrity": "sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA==", + "dev": true, + "optional": true + }, + "esbuild-netbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz", + "integrity": "sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w==", + "dev": true, + "optional": true + }, + "esbuild-openbsd-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz", + "integrity": "sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw==", + "dev": true, + "optional": true + }, + "esbuild-sunos-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz", + "integrity": "sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw==", + "dev": true, + "optional": true + }, + "esbuild-windows-32": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz", + "integrity": "sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w==", + "dev": true, + "optional": true + }, + "esbuild-windows-64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz", + "integrity": "sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ==", + "dev": true, + "optional": true + }, + "esbuild-windows-arm64": { + "version": "0.14.54", + "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz", + "integrity": "sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "follow-redirects": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.1.tgz", + "integrity": "sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==", + "dev": true + }, + "fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", + "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true + }, + "lilconfig": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.6.tgz", + "integrity": "sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg==", + "dev": true + }, + "magic-string": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.26.3.tgz", + "integrity": "sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "node-releases": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true + }, + "object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true + }, + "postcss": { + "version": "8.4.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", + "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-import": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-14.1.0.tgz", + "integrity": "sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + } + }, + "postcss-js": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.0.tgz", + "integrity": "sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ==", + "dev": true, + "requires": { + "camelcase-css": "^2.0.1" + } + }, + "postcss-load-config": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz", + "integrity": "sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==", + "dev": true, + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^2.1.1" + } + }, + "postcss-nested": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz", + "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.6" + } + }, + "postcss-selector-parser": { + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", + "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "dev": true, + "requires": { + "pify": "^2.3.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "rollup": { + "version": "2.77.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz", + "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "sander": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/sander/-/sander-0.5.1.tgz", + "integrity": "sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==", + "dev": true, + "requires": { + "es6-promise": "^3.1.2", + "graceful-fs": "^4.1.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.2" + } + }, + "sorcery": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/sorcery/-/sorcery-0.10.0.tgz", + "integrity": "sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.5", + "minimist": "^1.2.0", + "sander": "^0.5.0", + "sourcemap-codec": "^1.3.0" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "svelte": { + "version": "3.49.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.49.0.tgz", + "integrity": "sha512-+lmjic1pApJWDfPCpUUTc1m8azDqYCG1JN9YEngrx/hUyIcFJo6VZhj0A1Ai0wqoHcEIuQy+e9tk+4uDgdtsFA==", + "dev": true + }, + "svelte-hmr": { + "version": "0.14.12", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.14.12.tgz", + "integrity": "sha512-4QSW/VvXuqVcFZ+RhxiR8/newmwOCTlbYIezvkeN6302YFRE8cXy0naamHcjz8Y9Ce3ITTZtrHrIL0AGfyo61w==", + "dev": true, + "requires": {} + }, + "svelte-preprocess": { + "version": "4.10.7", + "resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.10.7.tgz", + "integrity": "sha512-sNPBnqYD6FnmdBrUmBCaqS00RyCsCpj2BG58A1JBswNF7b0OKviwxqVrOL/CKyJrLSClrSeqQv5BXNg2RUbPOw==", + "dev": true, + "requires": { + "@types/pug": "^2.0.4", + "@types/sass": "^1.16.0", + "detect-indent": "^6.0.0", + "magic-string": "^0.25.7", + "sorcery": "^0.10.0", + "strip-indent": "^3.0.0" + }, + "dependencies": { + "magic-string": { + "version": "0.25.9", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.9.tgz", + "integrity": "sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.8" + } + } + } + }, + "tailwindcss": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.1.8.tgz", + "integrity": "sha512-YSneUCZSFDYMwk+TGq8qYFdCA3yfBRdBlS7txSq0LUmzyeqRe3a8fBQzbz9M3WS/iFT4BNf/nmw9mEzrnSaC0g==", + "dev": true, + "requires": { + "arg": "^5.0.2", + "chokidar": "^3.5.3", + "color-name": "^1.1.4", + "detective": "^5.2.1", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.2.11", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "lilconfig": "^2.0.6", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.0.0", + "postcss": "^8.4.14", + "postcss-import": "^14.1.0", + "postcss-js": "^4.0.0", + "postcss-load-config": "^3.1.4", + "postcss-nested": "5.0.6", + "postcss-selector-parser": "^6.0.10", + "postcss-value-parser": "^4.2.0", + "quick-lru": "^5.1.1", + "resolve": "^1.22.1" + }, + "dependencies": { + "postcss-load-config": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.4.tgz", + "integrity": "sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==", + "dev": true, + "requires": { + "lilconfig": "^2.0.5", + "yaml": "^1.10.2" + } + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + } + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "update-browserslist-db": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.6.tgz", + "integrity": "sha512-We7BqM9XFlcW94Op93uW8+2LXvGezs7QA0WY+f1H7RR1q46B06W6hZF6LbmOlpCS1HU22q/6NOGTGW5sCm7NJQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "vite": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/vite/-/vite-3.0.9.tgz", + "integrity": "sha512-waYABTM+G6DBTCpYAxvevpG50UOlZuynR0ckTK5PawNVt7ebX6X7wNXHaGIO6wYYFXSM7/WcuFuO2QzhBB6aMw==", + "dev": true, + "requires": { + "esbuild": "^0.14.47", + "fsevents": "~2.3.2", + "postcss": "^8.4.16", + "resolve": "^1.22.1", + "rollup": ">=2.75.6 <2.77.0 || ~2.77.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "yaml": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.1.1.tgz", + "integrity": "sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==", + "dev": true + } + } +} diff --git a/ui/svelte/package.json b/ui/svelte/package.json new file mode 100644 index 00000000..a8fa1336 --- /dev/null +++ b/ui/svelte/package.json @@ -0,0 +1,22 @@ +{ + "name": "svelte-gui", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^1.0.1", + "svelte": "^3.49.0", + "vite": "^3.0.7", + "postcss": "^8.4.14", + "postcss-load-config": "^4.0.1", + "svelte-preprocess": "^4.10.7", + "autoprefixer": "^10.4.7", + "tailwindcss": "^3.1.5", + "http-proxy-middleware": "^2.0.1" + } +} diff --git a/ui/svelte/postcss.config.cjs b/ui/svelte/postcss.config.cjs new file mode 100644 index 00000000..e48cff58 --- /dev/null +++ b/ui/svelte/postcss.config.cjs @@ -0,0 +1,13 @@ +const tailwindcss = require("tailwindcss"); +const autoprefixer = require("autoprefixer"); + +const config = { + plugins: [ + //Some plugins, like tailwindcss/nesting, need to run before Tailwind, + tailwindcss(), + //But others, like autoprefixer, need to run after, + autoprefixer, + ], +}; + +module.exports = config; diff --git a/ui/svelte/src/App.svelte b/ui/svelte/src/App.svelte new file mode 100644 index 00000000..195458c5 --- /dev/null +++ b/ui/svelte/src/App.svelte @@ -0,0 +1,15 @@ + + +
+
+ +
diff --git a/ui/svelte/src/app.postcss b/ui/svelte/src/app.postcss new file mode 100644 index 00000000..7f7b70f8 --- /dev/null +++ b/ui/svelte/src/app.postcss @@ -0,0 +1,8 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +.gh-logo { + width: 2rem; + height: 2rem; +} \ No newline at end of file diff --git a/ui/svelte/src/assets/github.svg b/ui/svelte/src/assets/github.svg new file mode 100644 index 00000000..f25b68d5 --- /dev/null +++ b/ui/svelte/src/assets/github.svg @@ -0,0 +1,6 @@ + + + + GitHub + + diff --git a/ui/svelte/src/lib/AccountingData.svelte b/ui/svelte/src/lib/AccountingData.svelte new file mode 100644 index 00000000..6b85bf86 --- /dev/null +++ b/ui/svelte/src/lib/AccountingData.svelte @@ -0,0 +1,33 @@ + + +
+ Real time calculation + +
+
Hour
+
{data && data.h && data.h.u ? data.h.u.toFixed(2) : '-'} kWh
+
Day
+
{data && data.d && data.d.u ? data.d.u.toFixed(1) : '-'} kWh
+
Month
+
{data && data.m && data.m.u ? data.m.u.toFixed(0) : '-'} kWh
+
+ {#if currency} +
+
Hour
+
{data && data.h && data.h.c ? data.h.c.toFixed(2) : '-'} {currency}
+
Day
+
{data && data.d && data.d.c ? data.d.c.toFixed(1) : '-'} {currency}
+
Month
+
{data && data.m && data.m.c ? data.m.c.toFixed(0) : '-'} {currency}
+
+ {/if} +
+
Max
+
+ {data && data.x ? data.x.toFixed(1) : '-'} / {data && data.t ? data.t.toFixed(1) : '-'} kWh +
+
+
\ No newline at end of file diff --git a/ui/svelte/src/lib/AmpPlot.svelte b/ui/svelte/src/lib/AmpPlot.svelte new file mode 100644 index 00000000..ca495f3e --- /dev/null +++ b/ui/svelte/src/lib/AmpPlot.svelte @@ -0,0 +1,64 @@ + + diff --git a/ui/svelte/src/lib/Badge.svelte b/ui/svelte/src/lib/Badge.svelte new file mode 100644 index 00000000..43544479 --- /dev/null +++ b/ui/svelte/src/lib/Badge.svelte @@ -0,0 +1,14 @@ + +{#if color == 'green'} +{text} +{:else if color === `yellow`} +{text} +{:else if color === `red`} +{text} +{:else if color === `gray`} +{text} +{/if} \ No newline at end of file diff --git a/ui/svelte/src/lib/BarChart.svelte b/ui/svelte/src/lib/BarChart.svelte new file mode 100644 index 00000000..764822e8 --- /dev/null +++ b/ui/svelte/src/lib/BarChart.svelte @@ -0,0 +1,121 @@ + + +
+ + + + {#each config.y.ticks as tick} + + + {tick.label} + + {/each} + + + + + {#each config.x.ticks as point, i} + + {point.label} + + {/each} + + + + {#each config.points as point, i} + + {point.label} + {/each} + + +
+ + diff --git a/ui/svelte/src/lib/Clock.svelte b/ui/svelte/src/lib/Clock.svelte new file mode 100644 index 00000000..9d43dfed --- /dev/null +++ b/ui/svelte/src/lib/Clock.svelte @@ -0,0 +1,12 @@ + + +{#if Math.abs(new Date().getTime()-timestamp.getTime()) < 300000 } +{`${zeropad(timestamp.getDate())}. ${monthnames[timestamp.getMonth()]} ${zeropad(timestamp.getHours())}:${zeropad(timestamp.getMinutes())}`} +{:else} +{`${zeropad(timestamp.getDate())}.${zeropad(timestamp.getMonth())}.${timestamp.getFullYear()} ${zeropad(timestamp.getHours())}:${zeropad(timestamp.getMinutes())}`} +{/if} diff --git a/ui/svelte/src/lib/Counter.svelte b/ui/svelte/src/lib/Counter.svelte new file mode 100644 index 00000000..e45f9031 --- /dev/null +++ b/ui/svelte/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/ui/svelte/src/lib/Dashboard.svelte b/ui/svelte/src/lib/Dashboard.svelte new file mode 100644 index 00000000..4dc0fe1e --- /dev/null +++ b/ui/svelte/src/lib/Dashboard.svelte @@ -0,0 +1,78 @@ + + +
+
+ +
+
{data.mt ? metertype(data.mt) : '-'}
+
{data.ic ? data.ic.toFixed(1) : '-'} kWh
+
+
+ {#if data.om} +
+ +
+
+
{data.ec ? data.ec.toFixed(1) : '-'} kWh
+
+
+ {/if} +
+ +
+
+ +
+
+ +
+
+ +
+ {#if prices.currency} +
+ +
+ {/if} +
+ +
+
+ +
+ {#if data.t && data.t != -127 && temperatures.c > 1} +
+ +
+ {/if} +
\ No newline at end of file diff --git a/ui/svelte/src/lib/DataStores.js b/ui/svelte/src/lib/DataStores.js new file mode 100644 index 00000000..06b6600e --- /dev/null +++ b/ui/svelte/src/lib/DataStores.js @@ -0,0 +1,72 @@ +import { readable } from 'svelte/store'; + +let data = {}; +export const dataStore = readable(data, (set) => { + async function getData(){ + const response = await fetch("/data.json"); + data = (await response.json()) + set(data); + } + const interval = setInterval(getData, 5000); + getData(); + return function stop() { + clearInterval(interval); + } +}); + +let prices = {}; +export const pricesStore = readable(prices, (set) => { + async function getPrices(){ + const response = await fetch("/energyprice.json"); + prices = (await response.json()) + set(prices); + } + const date = new Date(); + const timeout = setTimeout(getPrices, (61-date.getMinutes())*60000) + getPrices(); + return function stop() {} +}); + +let dayPlot = {}; +export const dayPlotStore = readable(dayPlot, (set) => { + async function getDayPlot(){ + const response = await fetch("/dayplot.json"); + dayPlot = (await response.json()) + set(dayPlot); + } + const date = new Date(); + const timeout = setTimeout(getDayPlot, (61-date.getMinutes())*60000) + getDayPlot(); + return function stop() { + clearTimeout(timeout); + } +}); + +let monthPlot = {}; +export const monthPlotStore = readable(monthPlot, (set) => { + async function getmonthPlot(){ + const response = await fetch("/monthplot.json"); + monthPlot = (await response.json()) + set(monthPlot); + } + const date = new Date(); + const timeout = setTimeout(getmonthPlot, (24-date.getHours())*3600000) + getmonthPlot(); + return function stop() { + clearTimeout(timeout); + } +}); + +let temperatures = {}; +export const temperaturesStore = readable(temperatures, (set) => { + async function getTemperatures(){ + const response = await fetch("/temperature.json"); + temperatures = (await response.json()) + set(temperatures); + } + const interval = setInterval(getTemperatures, 60000); + getTemperatures(); + return function stop() { + clearTimeout(interval); + } +}); diff --git a/ui/svelte/src/lib/DayPlot.svelte b/ui/svelte/src/lib/DayPlot.svelte new file mode 100644 index 00000000..c6ac15f3 --- /dev/null +++ b/ui/svelte/src/lib/DayPlot.svelte @@ -0,0 +1,92 @@ + +
+ Energy use last 24 hours (kWh) + +
diff --git a/ui/svelte/src/lib/Header.svelte b/ui/svelte/src/lib/Header.svelte new file mode 100644 index 00000000..8f580a19 --- /dev/null +++ b/ui/svelte/src/lib/Header.svelte @@ -0,0 +1,35 @@ + + +
+
+
+ AMS reader v0.0.0 +
+
+
Up { data.u ? data.u : '-' }
+
{ data.t ? data.t.toFixed(1) : '-' }°C
+
Free mem: {data.m ? (data.m/1000).toFixed(1) : '-'}kb
+
+
+ 0 ? data.v.toFixed(2)+"V" : "ESP"} color={data.em === 1 ? 'green' : data.em === 2 ? 'yellow' : data.em === 3 ? 'red' : 'gray'}/> + + + +
+
+
+ GitHub repo +
+
+ +
+
+
+
\ No newline at end of file diff --git a/ui/svelte/src/lib/Helpers.js b/ui/svelte/src/lib/Helpers.js new file mode 100644 index 00000000..678d818c --- /dev/null +++ b/ui/svelte/src/lib/Helpers.js @@ -0,0 +1,44 @@ +export function voltcol(pct) { + if(pct > 85) return '#d90000'; + else if(pct > 75) return'#e32100'; + else if(pct > 70) return '#ffb800'; + else if(pct > 65) return '#dcd800'; + else if(pct > 35) return '#32d900'; + else if(pct > 25) return '#dcd800'; + else if(pct > 20) return '#ffb800'; + else if(pct > 15) return'#e32100'; + else return '#d90000'; +}; + +export function ampcol(pct) { + if(pct > 90) return '#d90000'; + else if(pct > 85) return'#e32100'; + else if(pct > 80) return '#ffb800'; + else if(pct > 75) return '#dcd800'; + else return '#32d900'; +}; + +export function metertype(mt) { + switch(mt) { + case 1: + return "Aidon"; + case 2: + return "Kaifa"; + case 3: + return "Kamstrup"; + case 8: + return "Iskra"; + case 9: + return "Landis"; + case 10: + return "Sagemcom"; + default: + return ""; + } +} + +export function zeropad(num) { + num = num.toString(); + while (num.length < 2) num = "0" + num; + return num; +} diff --git a/ui/svelte/src/lib/MonthPlot.svelte b/ui/svelte/src/lib/MonthPlot.svelte new file mode 100644 index 00000000..46727e65 --- /dev/null +++ b/ui/svelte/src/lib/MonthPlot.svelte @@ -0,0 +1,93 @@ + +
+ Energy use last month (kWh) + +
diff --git a/ui/svelte/src/lib/PowerGauge.svelte b/ui/svelte/src/lib/PowerGauge.svelte new file mode 100644 index 00000000..38d83be9 --- /dev/null +++ b/ui/svelte/src/lib/PowerGauge.svelte @@ -0,0 +1,43 @@ + + +
+ + + {val} + {unit} +
+ {label} +
+
+ + diff --git a/ui/svelte/src/lib/PowerGaugeSvg.svelte b/ui/svelte/src/lib/PowerGaugeSvg.svelte new file mode 100644 index 00000000..80a067f6 --- /dev/null +++ b/ui/svelte/src/lib/PowerGaugeSvg.svelte @@ -0,0 +1,39 @@ + + +
+ + + + + +
diff --git a/ui/svelte/src/lib/PricePlot.svelte b/ui/svelte/src/lib/PricePlot.svelte new file mode 100644 index 00000000..db992792 --- /dev/null +++ b/ui/svelte/src/lib/PricePlot.svelte @@ -0,0 +1,85 @@ + +
+ Future energy price ({json.currency}) + +
diff --git a/ui/svelte/src/lib/ReactiveData.svelte b/ui/svelte/src/lib/ReactiveData.svelte new file mode 100644 index 00000000..35e8df89 --- /dev/null +++ b/ui/svelte/src/lib/ReactiveData.svelte @@ -0,0 +1,24 @@ + + +
+ Reactive + +
+
Instant in
+
{typeof importInstant !== 'undefined' ? importInstant.toFixed(0) : '-'} VAr
+
Instant out
+
{typeof exportInstant !== 'undefined' ? exportInstant.toFixed(0) : '-'} VAr
+
+ +
+
Total in
+
{typeof importTotal !== 'undefined' ? importTotal.toFixed(1) : '-'} kVArh
+
Total out
+
{typeof exportTotal !== 'undefined' ? exportTotal.toFixed(1) : '-'} kVArh
+
+
\ No newline at end of file diff --git a/ui/svelte/src/lib/TemperaturePlot.svelte b/ui/svelte/src/lib/TemperaturePlot.svelte new file mode 100644 index 00000000..7ce8c409 --- /dev/null +++ b/ui/svelte/src/lib/TemperaturePlot.svelte @@ -0,0 +1,72 @@ + +
+ Temperature sensors (°C) + +
diff --git a/ui/svelte/src/lib/VoltPlot.svelte b/ui/svelte/src/lib/VoltPlot.svelte new file mode 100644 index 00000000..da328fa8 --- /dev/null +++ b/ui/svelte/src/lib/VoltPlot.svelte @@ -0,0 +1,61 @@ + + diff --git a/ui/svelte/src/main.js b/ui/svelte/src/main.js new file mode 100644 index 00000000..bc3d21d3 --- /dev/null +++ b/ui/svelte/src/main.js @@ -0,0 +1,9 @@ +import "./app.postcss"; +import App from "./App.svelte"; + + +const app = new App({ + target: document.getElementById("app"), +}); + +export default app; diff --git a/ui/svelte/src/vite-env.d.ts b/ui/svelte/src/vite-env.d.ts new file mode 100644 index 00000000..4078e747 --- /dev/null +++ b/ui/svelte/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/ui/svelte/svelte.config.js b/ui/svelte/svelte.config.js new file mode 100644 index 00000000..678adc0f --- /dev/null +++ b/ui/svelte/svelte.config.js @@ -0,0 +1,11 @@ +import preprocess from "svelte-preprocess"; + +const config = { + preprocess: [ + preprocess({ + postcss: true, + }), + ], +}; + +export default config; diff --git a/ui/svelte/tailwind.config.cjs b/ui/svelte/tailwind.config.cjs new file mode 100644 index 00000000..040301b3 --- /dev/null +++ b/ui/svelte/tailwind.config.cjs @@ -0,0 +1,11 @@ +const config = { + content: ["./index.html","./src/**/*.{html,js,svelte,ts}"], + + theme: { + extend: {}, + }, + + plugins: [], +}; + +module.exports = config; diff --git a/ui/svelte/vite.config.js b/ui/svelte/vite.config.js new file mode 100644 index 00000000..b4e3acb4 --- /dev/null +++ b/ui/svelte/vite.config.js @@ -0,0 +1,16 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], + server: { + proxy: { + "/data.json": "http://192.168.233.235", + "/energyprice.json": "http://192.168.233.235", + "/dayplot.json": "http://192.168.233.235", + "/monthplot.json": "http://192.168.233.235", + "/temperature.json": "http://192.168.233.235", + } + } +}) From 488c969858dde1dc2a7b78099049a253c80d7920 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 3 Sep 2022 13:12:29 +0200 Subject: [PATCH 04/66] Some serious restructuring to be able to swap between implementations --- .gitignore | 2 +- .../include}/AmsConfiguration.h | 0 .../AmsConfiguration/include}/AmsStorage.h | 0 .../AmsConfiguration/include}/hexutils.h | 0 .../src}/AmsConfiguration.cpp | 0 .../AmsConfiguration/src}/hexutils.cpp | 0 {src => lib/AmsData/include}/AmsData.h | 0 {src => lib/AmsData/src}/AmsData.cpp | 0 .../AmsDataStorage/include}/AmsDataStorage.h | 0 .../AmsDataStorage/src}/AmsDataStorage.cpp | 0 {web => lib/ClassicUi/html}/application.js | 0 {web => lib/ClassicUi/html}/boot.css | 0 {web => lib/ClassicUi/html}/configfile.html | 0 {web => lib/ClassicUi/html}/data.json | 0 {web => lib/ClassicUi/html}/dayplot.json | 0 {web => lib/ClassicUi/html}/debugging.html | 0 {web => lib/ClassicUi/html}/delete.html | 0 {web => lib/ClassicUi/html}/domoticz.html | 0 {web => lib/ClassicUi/html}/domoticz.json | 0 {web => lib/ClassicUi/html}/energyprice.json | 0 {web => lib/ClassicUi/html}/entsoe.html | 0 {web => lib/ClassicUi/html}/firmware.html | 0 {web => lib/ClassicUi/html}/foot.html | 0 {web => lib/ClassicUi/html}/github.svg | 0 {web => lib/ClassicUi/html}/gpio.html | 0 {web => lib/ClassicUi/html}/ha1.json | 0 {web => lib/ClassicUi/html}/ha2.json | 0 {web => lib/ClassicUi/html}/ha3.json | 0 {web => lib/ClassicUi/html}/hadiscover.json | 0 {web => lib/ClassicUi/html}/head.html | 0 {web => lib/ClassicUi/html}/index.html | 0 {web => lib/ClassicUi/html}/json1.json | 0 {web => lib/ClassicUi/html}/json2.json | 0 {web => lib/ClassicUi/html}/json3.json | 0 {web => lib/ClassicUi/html}/json4.json | 0 {web => lib/ClassicUi/html}/jsonprices.json | 0 {web => lib/ClassicUi/html}/jsonsys.json | 0 {web => lib/ClassicUi/html}/meter.html | 0 .../ClassicUi/html}/meteradvanced.html | 0 {web => lib/ClassicUi/html}/monthplot.json | 0 {web => lib/ClassicUi/html}/mqtt.html | 0 {web => lib/ClassicUi/html}/notfound.html | 0 {web => lib/ClassicUi/html}/ntp.html | 0 {web => lib/ClassicUi/html}/reset.html | 0 {web => lib/ClassicUi/html}/restart.html | 0 {web => lib/ClassicUi/html}/restartwait.html | 0 {web => lib/ClassicUi/html}/setup.html | 0 {web => lib/ClassicUi/html}/temperature.html | 0 {web => lib/ClassicUi/html}/tempsensor.json | 0 {web => lib/ClassicUi/html}/thresholds.html | 0 {web => lib/ClassicUi/html}/upload.html | 0 {web => lib/ClassicUi/html}/web.html | 0 {web => lib/ClassicUi/html}/wifi.html | 0 lib/ClassicUi/include/.gitignore | 1 + .../ClassicUi/include}/AmsWebHeaders.h | 0 .../ClassicUi/include}/AmsWebServer.h | 2 +- .../ClassicUi/scripts/generate_includes.py | 4 +-- .../ClassicUi/src}/AmsWebServer.cpp | 0 .../include}/EnergyAccounting.h | 2 +- .../src}/EnergyAccounting.cpp | 0 .../EntsoePriceApi/include}/DnbCurrParser.h | 0 .../EntsoePriceApi/include}/EntsoeA44Parser.h | 0 .../EntsoePriceApi/include}/EntsoeApi.h | 0 .../EntsoePriceApi/src}/DnbCurrParser.cpp | 0 .../EntsoePriceApi/src}/EntsoeA44Parser.cpp | 0 .../EntsoePriceApi/src}/EntsoeApi.cpp | 2 +- {src => lib/HwTools/include}/HwTools.h | 0 {src => lib/HwTools/src}/HwTools.cpp | 0 {src => lib/Uptime/include}/Uptime.h | 0 {src => lib/Uptime/src}/Uptime.cpp | 0 platformio.ini | 36 ++++++++++--------- scripts/addversion.py | 2 +- src/AmsToMqttBridge.ino | 4 +-- src/mqtt/AmsMqttHandler.h | 2 +- src/mqtt/DomoticzMqttHandler.cpp | 2 +- src/mqtt/HomeAssistantMqttHandler.cpp | 12 +++---- src/mqtt/JsonMqttHandler.cpp | 12 +++---- 77 files changed, 43 insertions(+), 40 deletions(-) rename {src => lib/AmsConfiguration/include}/AmsConfiguration.h (100%) rename {src => lib/AmsConfiguration/include}/AmsStorage.h (100%) rename {src => lib/AmsConfiguration/include}/hexutils.h (100%) rename {src => lib/AmsConfiguration/src}/AmsConfiguration.cpp (100%) rename {src => lib/AmsConfiguration/src}/hexutils.cpp (100%) rename {src => lib/AmsData/include}/AmsData.h (100%) rename {src => lib/AmsData/src}/AmsData.cpp (100%) rename {src => lib/AmsDataStorage/include}/AmsDataStorage.h (100%) rename {src => lib/AmsDataStorage/src}/AmsDataStorage.cpp (100%) rename {web => lib/ClassicUi/html}/application.js (100%) rename {web => lib/ClassicUi/html}/boot.css (100%) rename {web => lib/ClassicUi/html}/configfile.html (100%) rename {web => lib/ClassicUi/html}/data.json (100%) rename {web => lib/ClassicUi/html}/dayplot.json (100%) rename {web => lib/ClassicUi/html}/debugging.html (100%) rename {web => lib/ClassicUi/html}/delete.html (100%) rename {web => lib/ClassicUi/html}/domoticz.html (100%) rename {web => lib/ClassicUi/html}/domoticz.json (100%) rename {web => lib/ClassicUi/html}/energyprice.json (100%) rename {web => lib/ClassicUi/html}/entsoe.html (100%) rename {web => lib/ClassicUi/html}/firmware.html (100%) rename {web => lib/ClassicUi/html}/foot.html (100%) rename {web => lib/ClassicUi/html}/github.svg (100%) rename {web => lib/ClassicUi/html}/gpio.html (100%) rename {web => lib/ClassicUi/html}/ha1.json (100%) rename {web => lib/ClassicUi/html}/ha2.json (100%) rename {web => lib/ClassicUi/html}/ha3.json (100%) rename {web => lib/ClassicUi/html}/hadiscover.json (100%) rename {web => lib/ClassicUi/html}/head.html (100%) rename {web => lib/ClassicUi/html}/index.html (100%) rename {web => lib/ClassicUi/html}/json1.json (100%) rename {web => lib/ClassicUi/html}/json2.json (100%) rename {web => lib/ClassicUi/html}/json3.json (100%) rename {web => lib/ClassicUi/html}/json4.json (100%) rename {web => lib/ClassicUi/html}/jsonprices.json (100%) rename {web => lib/ClassicUi/html}/jsonsys.json (100%) rename {web => lib/ClassicUi/html}/meter.html (100%) rename {web => lib/ClassicUi/html}/meteradvanced.html (100%) rename {web => lib/ClassicUi/html}/monthplot.json (100%) rename {web => lib/ClassicUi/html}/mqtt.html (100%) rename {web => lib/ClassicUi/html}/notfound.html (100%) rename {web => lib/ClassicUi/html}/ntp.html (100%) rename {web => lib/ClassicUi/html}/reset.html (100%) rename {web => lib/ClassicUi/html}/restart.html (100%) rename {web => lib/ClassicUi/html}/restartwait.html (100%) rename {web => lib/ClassicUi/html}/setup.html (100%) rename {web => lib/ClassicUi/html}/temperature.html (100%) rename {web => lib/ClassicUi/html}/tempsensor.json (100%) rename {web => lib/ClassicUi/html}/thresholds.html (100%) rename {web => lib/ClassicUi/html}/upload.html (100%) rename {web => lib/ClassicUi/html}/web.html (100%) rename {web => lib/ClassicUi/html}/wifi.html (100%) create mode 100644 lib/ClassicUi/include/.gitignore rename {src/web => lib/ClassicUi/include}/AmsWebHeaders.h (100%) rename {src/web => lib/ClassicUi/include}/AmsWebServer.h (99%) rename scripts/makeweb.py => lib/ClassicUi/scripts/generate_includes.py (96%) rename {src/web => lib/ClassicUi/src}/AmsWebServer.cpp (100%) rename {src => lib/EnergyAccounting/include}/EnergyAccounting.h (98%) rename {src => lib/EnergyAccounting/src}/EnergyAccounting.cpp (100%) rename {src/entsoe => lib/EntsoePriceApi/include}/DnbCurrParser.h (100%) rename {src/entsoe => lib/EntsoePriceApi/include}/EntsoeA44Parser.h (100%) rename {src/entsoe => lib/EntsoePriceApi/include}/EntsoeApi.h (100%) rename {src/entsoe => lib/EntsoePriceApi/src}/DnbCurrParser.cpp (100%) rename {src/entsoe => lib/EntsoePriceApi/src}/EntsoeA44Parser.cpp (100%) rename {src/entsoe => lib/EntsoePriceApi/src}/EntsoeApi.cpp (99%) rename {src => lib/HwTools/include}/HwTools.h (100%) rename {src => lib/HwTools/src}/HwTools.cpp (100%) rename {src => lib/Uptime/include}/Uptime.h (100%) rename {src => lib/Uptime/src}/Uptime.cpp (100%) diff --git a/.gitignore b/.gitignore index 9a9d7b4c..768987c7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ .vscode .pio platformio-user.ini -/src/version.h +/lib/AmsConfiguration/include/version.h /src/web/root /src/AmsToMqttBridge.ino.cpp /test diff --git a/src/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h similarity index 100% rename from src/AmsConfiguration.h rename to lib/AmsConfiguration/include/AmsConfiguration.h diff --git a/src/AmsStorage.h b/lib/AmsConfiguration/include/AmsStorage.h similarity index 100% rename from src/AmsStorage.h rename to lib/AmsConfiguration/include/AmsStorage.h diff --git a/src/hexutils.h b/lib/AmsConfiguration/include/hexutils.h similarity index 100% rename from src/hexutils.h rename to lib/AmsConfiguration/include/hexutils.h diff --git a/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp similarity index 100% rename from src/AmsConfiguration.cpp rename to lib/AmsConfiguration/src/AmsConfiguration.cpp diff --git a/src/hexutils.cpp b/lib/AmsConfiguration/src/hexutils.cpp similarity index 100% rename from src/hexutils.cpp rename to lib/AmsConfiguration/src/hexutils.cpp diff --git a/src/AmsData.h b/lib/AmsData/include/AmsData.h similarity index 100% rename from src/AmsData.h rename to lib/AmsData/include/AmsData.h diff --git a/src/AmsData.cpp b/lib/AmsData/src/AmsData.cpp similarity index 100% rename from src/AmsData.cpp rename to lib/AmsData/src/AmsData.cpp diff --git a/src/AmsDataStorage.h b/lib/AmsDataStorage/include/AmsDataStorage.h similarity index 100% rename from src/AmsDataStorage.h rename to lib/AmsDataStorage/include/AmsDataStorage.h diff --git a/src/AmsDataStorage.cpp b/lib/AmsDataStorage/src/AmsDataStorage.cpp similarity index 100% rename from src/AmsDataStorage.cpp rename to lib/AmsDataStorage/src/AmsDataStorage.cpp diff --git a/web/application.js b/lib/ClassicUi/html/application.js similarity index 100% rename from web/application.js rename to lib/ClassicUi/html/application.js diff --git a/web/boot.css b/lib/ClassicUi/html/boot.css similarity index 100% rename from web/boot.css rename to lib/ClassicUi/html/boot.css diff --git a/web/configfile.html b/lib/ClassicUi/html/configfile.html similarity index 100% rename from web/configfile.html rename to lib/ClassicUi/html/configfile.html diff --git a/web/data.json b/lib/ClassicUi/html/data.json similarity index 100% rename from web/data.json rename to lib/ClassicUi/html/data.json diff --git a/web/dayplot.json b/lib/ClassicUi/html/dayplot.json similarity index 100% rename from web/dayplot.json rename to lib/ClassicUi/html/dayplot.json diff --git a/web/debugging.html b/lib/ClassicUi/html/debugging.html similarity index 100% rename from web/debugging.html rename to lib/ClassicUi/html/debugging.html diff --git a/web/delete.html b/lib/ClassicUi/html/delete.html similarity index 100% rename from web/delete.html rename to lib/ClassicUi/html/delete.html diff --git a/web/domoticz.html b/lib/ClassicUi/html/domoticz.html similarity index 100% rename from web/domoticz.html rename to lib/ClassicUi/html/domoticz.html diff --git a/web/domoticz.json b/lib/ClassicUi/html/domoticz.json similarity index 100% rename from web/domoticz.json rename to lib/ClassicUi/html/domoticz.json diff --git a/web/energyprice.json b/lib/ClassicUi/html/energyprice.json similarity index 100% rename from web/energyprice.json rename to lib/ClassicUi/html/energyprice.json diff --git a/web/entsoe.html b/lib/ClassicUi/html/entsoe.html similarity index 100% rename from web/entsoe.html rename to lib/ClassicUi/html/entsoe.html diff --git a/web/firmware.html b/lib/ClassicUi/html/firmware.html similarity index 100% rename from web/firmware.html rename to lib/ClassicUi/html/firmware.html diff --git a/web/foot.html b/lib/ClassicUi/html/foot.html similarity index 100% rename from web/foot.html rename to lib/ClassicUi/html/foot.html diff --git a/web/github.svg b/lib/ClassicUi/html/github.svg similarity index 100% rename from web/github.svg rename to lib/ClassicUi/html/github.svg diff --git a/web/gpio.html b/lib/ClassicUi/html/gpio.html similarity index 100% rename from web/gpio.html rename to lib/ClassicUi/html/gpio.html diff --git a/web/ha1.json b/lib/ClassicUi/html/ha1.json similarity index 100% rename from web/ha1.json rename to lib/ClassicUi/html/ha1.json diff --git a/web/ha2.json b/lib/ClassicUi/html/ha2.json similarity index 100% rename from web/ha2.json rename to lib/ClassicUi/html/ha2.json diff --git a/web/ha3.json b/lib/ClassicUi/html/ha3.json similarity index 100% rename from web/ha3.json rename to lib/ClassicUi/html/ha3.json diff --git a/web/hadiscover.json b/lib/ClassicUi/html/hadiscover.json similarity index 100% rename from web/hadiscover.json rename to lib/ClassicUi/html/hadiscover.json diff --git a/web/head.html b/lib/ClassicUi/html/head.html similarity index 100% rename from web/head.html rename to lib/ClassicUi/html/head.html diff --git a/web/index.html b/lib/ClassicUi/html/index.html similarity index 100% rename from web/index.html rename to lib/ClassicUi/html/index.html diff --git a/web/json1.json b/lib/ClassicUi/html/json1.json similarity index 100% rename from web/json1.json rename to lib/ClassicUi/html/json1.json diff --git a/web/json2.json b/lib/ClassicUi/html/json2.json similarity index 100% rename from web/json2.json rename to lib/ClassicUi/html/json2.json diff --git a/web/json3.json b/lib/ClassicUi/html/json3.json similarity index 100% rename from web/json3.json rename to lib/ClassicUi/html/json3.json diff --git a/web/json4.json b/lib/ClassicUi/html/json4.json similarity index 100% rename from web/json4.json rename to lib/ClassicUi/html/json4.json diff --git a/web/jsonprices.json b/lib/ClassicUi/html/jsonprices.json similarity index 100% rename from web/jsonprices.json rename to lib/ClassicUi/html/jsonprices.json diff --git a/web/jsonsys.json b/lib/ClassicUi/html/jsonsys.json similarity index 100% rename from web/jsonsys.json rename to lib/ClassicUi/html/jsonsys.json diff --git a/web/meter.html b/lib/ClassicUi/html/meter.html similarity index 100% rename from web/meter.html rename to lib/ClassicUi/html/meter.html diff --git a/web/meteradvanced.html b/lib/ClassicUi/html/meteradvanced.html similarity index 100% rename from web/meteradvanced.html rename to lib/ClassicUi/html/meteradvanced.html diff --git a/web/monthplot.json b/lib/ClassicUi/html/monthplot.json similarity index 100% rename from web/monthplot.json rename to lib/ClassicUi/html/monthplot.json diff --git a/web/mqtt.html b/lib/ClassicUi/html/mqtt.html similarity index 100% rename from web/mqtt.html rename to lib/ClassicUi/html/mqtt.html diff --git a/web/notfound.html b/lib/ClassicUi/html/notfound.html similarity index 100% rename from web/notfound.html rename to lib/ClassicUi/html/notfound.html diff --git a/web/ntp.html b/lib/ClassicUi/html/ntp.html similarity index 100% rename from web/ntp.html rename to lib/ClassicUi/html/ntp.html diff --git a/web/reset.html b/lib/ClassicUi/html/reset.html similarity index 100% rename from web/reset.html rename to lib/ClassicUi/html/reset.html diff --git a/web/restart.html b/lib/ClassicUi/html/restart.html similarity index 100% rename from web/restart.html rename to lib/ClassicUi/html/restart.html diff --git a/web/restartwait.html b/lib/ClassicUi/html/restartwait.html similarity index 100% rename from web/restartwait.html rename to lib/ClassicUi/html/restartwait.html diff --git a/web/setup.html b/lib/ClassicUi/html/setup.html similarity index 100% rename from web/setup.html rename to lib/ClassicUi/html/setup.html diff --git a/web/temperature.html b/lib/ClassicUi/html/temperature.html similarity index 100% rename from web/temperature.html rename to lib/ClassicUi/html/temperature.html diff --git a/web/tempsensor.json b/lib/ClassicUi/html/tempsensor.json similarity index 100% rename from web/tempsensor.json rename to lib/ClassicUi/html/tempsensor.json diff --git a/web/thresholds.html b/lib/ClassicUi/html/thresholds.html similarity index 100% rename from web/thresholds.html rename to lib/ClassicUi/html/thresholds.html diff --git a/web/upload.html b/lib/ClassicUi/html/upload.html similarity index 100% rename from web/upload.html rename to lib/ClassicUi/html/upload.html diff --git a/web/web.html b/lib/ClassicUi/html/web.html similarity index 100% rename from web/web.html rename to lib/ClassicUi/html/web.html diff --git a/web/wifi.html b/lib/ClassicUi/html/wifi.html similarity index 100% rename from web/wifi.html rename to lib/ClassicUi/html/wifi.html diff --git a/lib/ClassicUi/include/.gitignore b/lib/ClassicUi/include/.gitignore new file mode 100644 index 00000000..1530ce82 --- /dev/null +++ b/lib/ClassicUi/include/.gitignore @@ -0,0 +1 @@ +root/*.h diff --git a/src/web/AmsWebHeaders.h b/lib/ClassicUi/include/AmsWebHeaders.h similarity index 100% rename from src/web/AmsWebHeaders.h rename to lib/ClassicUi/include/AmsWebHeaders.h diff --git a/src/web/AmsWebServer.h b/lib/ClassicUi/include/AmsWebServer.h similarity index 99% rename from src/web/AmsWebServer.h rename to lib/ClassicUi/include/AmsWebServer.h index 0a0ac6b3..19705afd 100644 --- a/src/web/AmsWebServer.h +++ b/lib/ClassicUi/include/AmsWebServer.h @@ -13,7 +13,7 @@ #include "EnergyAccounting.h" #include "Uptime.h" #include "RemoteDebug.h" -#include "entsoe/EntsoeApi.h" +#include "EntsoeApi.h" #if defined(ESP8266) #include diff --git a/scripts/makeweb.py b/lib/ClassicUi/scripts/generate_includes.py similarity index 96% rename from scripts/makeweb.py rename to lib/ClassicUi/scripts/generate_includes.py index 658f4ca4..bb5efbeb 100644 --- a/scripts/makeweb.py +++ b/lib/ClassicUi/scripts/generate_includes.py @@ -25,8 +25,8 @@ except: print("WARN: Unable to load minifier") -webroot = "web" -srcroot = "src/web/root" +webroot = "lib/ClassicUi/html" +srcroot = "lib/ClassicUi/include/root" version = os.environ.get('GITHUB_TAG') if version == None: diff --git a/src/web/AmsWebServer.cpp b/lib/ClassicUi/src/AmsWebServer.cpp similarity index 100% rename from src/web/AmsWebServer.cpp rename to lib/ClassicUi/src/AmsWebServer.cpp diff --git a/src/EnergyAccounting.h b/lib/EnergyAccounting/include/EnergyAccounting.h similarity index 98% rename from src/EnergyAccounting.h rename to lib/EnergyAccounting/include/EnergyAccounting.h index c0c76e32..1a577fc4 100644 --- a/src/EnergyAccounting.h +++ b/lib/EnergyAccounting/include/EnergyAccounting.h @@ -4,7 +4,7 @@ #include "Arduino.h" #include "AmsData.h" #include "AmsDataStorage.h" -#include "entsoe/EntsoeApi.h" +#include "EntsoeApi.h" struct EnergyAccountingPeak { uint8_t day; diff --git a/src/EnergyAccounting.cpp b/lib/EnergyAccounting/src/EnergyAccounting.cpp similarity index 100% rename from src/EnergyAccounting.cpp rename to lib/EnergyAccounting/src/EnergyAccounting.cpp diff --git a/src/entsoe/DnbCurrParser.h b/lib/EntsoePriceApi/include/DnbCurrParser.h similarity index 100% rename from src/entsoe/DnbCurrParser.h rename to lib/EntsoePriceApi/include/DnbCurrParser.h diff --git a/src/entsoe/EntsoeA44Parser.h b/lib/EntsoePriceApi/include/EntsoeA44Parser.h similarity index 100% rename from src/entsoe/EntsoeA44Parser.h rename to lib/EntsoePriceApi/include/EntsoeA44Parser.h diff --git a/src/entsoe/EntsoeApi.h b/lib/EntsoePriceApi/include/EntsoeApi.h similarity index 100% rename from src/entsoe/EntsoeApi.h rename to lib/EntsoePriceApi/include/EntsoeApi.h diff --git a/src/entsoe/DnbCurrParser.cpp b/lib/EntsoePriceApi/src/DnbCurrParser.cpp similarity index 100% rename from src/entsoe/DnbCurrParser.cpp rename to lib/EntsoePriceApi/src/DnbCurrParser.cpp diff --git a/src/entsoe/EntsoeA44Parser.cpp b/lib/EntsoePriceApi/src/EntsoeA44Parser.cpp similarity index 100% rename from src/entsoe/EntsoeA44Parser.cpp rename to lib/EntsoePriceApi/src/EntsoeA44Parser.cpp diff --git a/src/entsoe/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp similarity index 99% rename from src/entsoe/EntsoeApi.cpp rename to lib/EntsoePriceApi/src/EntsoeApi.cpp index 886e7201..00d25bde 100644 --- a/src/entsoe/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -201,7 +201,7 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { https.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); https.setReuse(false); https.setTimeout(50000); - https.setUserAgent("ams2mqtt/" + String(VERSION)); + https.setUserAgent("ams2mqtt"); #if defined(ESP32) if(https.begin(url)) { printD("Connection established"); diff --git a/src/HwTools.h b/lib/HwTools/include/HwTools.h similarity index 100% rename from src/HwTools.h rename to lib/HwTools/include/HwTools.h diff --git a/src/HwTools.cpp b/lib/HwTools/src/HwTools.cpp similarity index 100% rename from src/HwTools.cpp rename to lib/HwTools/src/HwTools.cpp diff --git a/src/Uptime.h b/lib/Uptime/include/Uptime.h similarity index 100% rename from src/Uptime.h rename to lib/Uptime/include/Uptime.h diff --git a/src/Uptime.cpp b/lib/Uptime/src/Uptime.cpp similarity index 100% rename from src/Uptime.cpp rename to lib/Uptime/src/Uptime.cpp diff --git a/platformio.ini b/platformio.ini index 37670bed..b4d27b19 100755 --- a/platformio.ini +++ b/platformio.ini @@ -2,8 +2,14 @@ extra_configs = platformio-user.ini [common] -lib_deps = Timezone@1.2.4, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1 +lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, EntsoePriceApi, EnergyAccounting, ClassicUi lib_ignore = OneWire +extra_scripts = + pre:scripts/addversion.py + lib/ClassicUi/scripts/generate_includes.py + +[esp32] +lib_deps = WiFi, ESPmDNS, WiFiClientSecure, HTTPClient, FS, Update, HTTPUpdate, WebServer, ${common.lib_deps} [env:esp8266] platform = espressif8266@3.2.0 @@ -11,11 +17,10 @@ framework = arduino board = esp12e board_build.ldscript = eagle.flash.4m2m.ld build_flags = -D WEBSOCKET_DISABLED=1 -lib_deps = ${common.lib_deps} +lib_ldf_mode = off +lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP8266httpUpdate, ${common.lib_deps} lib_ignore = ${common.lib_ignore} -extra_scripts = - pre:scripts/addversion.py - scripts/makeweb.py +extra_scripts = ${common.extra_scripts} # Sticking to v2.0.3 because of #298 @@ -25,11 +30,10 @@ framework = arduino board = esp32dev board_build.f_cpu = 160000000L build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions -lib_deps = ${common.lib_deps} +lib_ldf_mode = off +lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} -extra_scripts = - pre:scripts/addversion.py - scripts/makeweb.py +extra_scripts = ${common.extra_scripts} # Tasmota has pre-built platform for C3, S2, S3 and Solo, more information at: # https://github.com/Jason2866/esp32-arduino-lib-builder @@ -45,11 +49,10 @@ board_build.flash_mode = qio board_build.f_cpu = 160000000L board_build.f_flash = 40000000L build_flags = -D WEBSOCKET_DISABLED=1 -lib_deps = ${common.lib_deps} +lib_ldf_mode = off +lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} -extra_scripts = - pre:scripts/addversion.py - scripts/makeweb.py +extra_scripts = ${common.extra_scripts} [env:esp32solo] platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-solo1-v.2.0.3.zip @@ -57,8 +60,7 @@ framework = arduino board = esp32dev board_build.f_cpu = 160000000L build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions -lib_deps = ${common.lib_deps} +lib_ldf_mode = off +lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} -extra_scripts = - pre:scripts/addversion.py - scripts/makeweb.py +extra_scripts = ${common.extra_scripts} diff --git a/scripts/addversion.py b/scripts/addversion.py index 47fc1d48..b373784c 100644 --- a/scripts/addversion.py +++ b/scripts/addversion.py @@ -2,7 +2,7 @@ import os import subprocess from time import time -FILENAME_VERSION_H = 'src/version.h' +FILENAME_VERSION_H = 'lib/AmsConfiguration/include/version.h' version = os.environ.get('GITHUB_TAG') if version == None: try: diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index a10be9ac..69f4a5f7 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -49,9 +49,9 @@ ADC_MODE(ADC_VCC); #include "hexutils.h" #include "HwTools.h" -#include "entsoe/EntsoeApi.h" +#include "EntsoeApi.h" -#include "web/AmsWebServer.h" +#include "AmsWebServer.h" #include "AmsConfiguration.h" #include "mqtt/AmsMqttHandler.h" diff --git a/src/mqtt/AmsMqttHandler.h b/src/mqtt/AmsMqttHandler.h index e5364e4e..3472e3f6 100644 --- a/src/mqtt/AmsMqttHandler.h +++ b/src/mqtt/AmsMqttHandler.h @@ -7,7 +7,7 @@ #include "AmsConfiguration.h" #include "EnergyAccounting.h" #include "HwTools.h" -#include "entsoe/EntsoeApi.h" +#include "EntsoeApi.h" class AmsMqttHandler { public: diff --git a/src/mqtt/DomoticzMqttHandler.cpp b/src/mqtt/DomoticzMqttHandler.cpp index 11975d34..90cbb182 100644 --- a/src/mqtt/DomoticzMqttHandler.cpp +++ b/src/mqtt/DomoticzMqttHandler.cpp @@ -1,5 +1,5 @@ #include "DomoticzMqttHandler.h" -#include "web/root/domoticz_json.h" +#include "root/domoticz_json.h" bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) { bool ret = false; diff --git a/src/mqtt/HomeAssistantMqttHandler.cpp b/src/mqtt/HomeAssistantMqttHandler.cpp index f8678796..1fe9ead0 100644 --- a/src/mqtt/HomeAssistantMqttHandler.cpp +++ b/src/mqtt/HomeAssistantMqttHandler.cpp @@ -3,12 +3,12 @@ #include "hexutils.h" #include "Uptime.h" #include "version.h" -#include "web/root/ha1_json.h" -#include "web/root/ha2_json.h" -#include "web/root/ha3_json.h" -#include "web/root/jsonsys_json.h" -#include "web/root/jsonprices_json.h" -#include "web/root/hadiscover_json.h" +#include "root/ha1_json.h" +#include "root/ha2_json.h" +#include "root/ha3_json.h" +#include "root/jsonsys_json.h" +#include "root/jsonprices_json.h" +#include "root/hadiscover_json.h" bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) { if(topic.isEmpty() || !mqtt->connected()) diff --git a/src/mqtt/JsonMqttHandler.cpp b/src/mqtt/JsonMqttHandler.cpp index 132d8e32..8408b226 100644 --- a/src/mqtt/JsonMqttHandler.cpp +++ b/src/mqtt/JsonMqttHandler.cpp @@ -2,12 +2,12 @@ #include "version.h" #include "hexutils.h" #include "Uptime.h" -#include "web/root/json1_json.h" -#include "web/root/json2_json.h" -#include "web/root/json3_json.h" -#include "web/root/json4_json.h" -#include "web/root/jsonsys_json.h" -#include "web/root/jsonprices_json.h" +#include "root/json1_json.h" +#include "root/json2_json.h" +#include "root/json3_json.h" +#include "root/json4_json.h" +#include "root/jsonsys_json.h" +#include "root/jsonprices_json.h" bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) { if(topic.isEmpty() || !mqtt->connected()) From 493c4b433701eaabf4f9355c7d3b3e72f26d7bdf Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 3 Sep 2022 13:41:11 +0200 Subject: [PATCH 05/66] Moved Svelte UI to lib folder --- {ui/svelte => lib/SvelteUi/app}/.gitignore | 0 {ui/svelte => lib/SvelteUi/app}/index.html | 0 {ui/svelte => lib/SvelteUi/app}/jsconfig.json | 0 .../SvelteUi/app}/package-lock.json | 0 {ui/svelte => lib/SvelteUi/app}/package.json | 0 .../SvelteUi/app}/postcss.config.cjs | 0 .../SvelteUi/app}/src/App.svelte | 0 .../SvelteUi/app}/src/app.postcss | 0 .../SvelteUi/app}/src/assets/github.svg | 0 .../app}/src/lib/AccountingData.svelte | 0 .../SvelteUi/app}/src/lib/AmpPlot.svelte | 0 .../SvelteUi/app}/src/lib/Badge.svelte | 0 .../SvelteUi/app}/src/lib/BarChart.svelte | 4 - .../SvelteUi/app}/src/lib/Clock.svelte | 0 .../SvelteUi/app}/src/lib/Counter.svelte | 0 .../SvelteUi/app}/src/lib/Dashboard.svelte | 0 .../SvelteUi/app}/src/lib/DataStores.js | 0 .../SvelteUi/app}/src/lib/DayPlot.svelte | 0 .../SvelteUi/app}/src/lib/Header.svelte | 0 .../SvelteUi/app}/src/lib/Helpers.js | 0 .../SvelteUi/app}/src/lib/MonthPlot.svelte | 0 .../SvelteUi/app}/src/lib/PowerGauge.svelte | 0 .../app}/src/lib/PowerGaugeSvg.svelte | 0 .../SvelteUi/app}/src/lib/PricePlot.svelte | 0 .../SvelteUi/app}/src/lib/ReactiveData.svelte | 0 .../app}/src/lib/TemperaturePlot.svelte | 0 .../SvelteUi/app}/src/lib/VoltPlot.svelte | 0 {ui/svelte => lib/SvelteUi/app}/src/main.js | 0 .../SvelteUi/app}/src/vite-env.d.ts | 0 .../SvelteUi/app}/svelte.config.js | 0 .../SvelteUi/app}/tailwind.config.cjs | 0 .../SvelteUi/app}/vite.config.js | 11 +++ lib/SvelteUi/include/.gitignore | 1 + lib/SvelteUi/include/AmsWebServer.h | 86 +++++++++++++++++++ lib/SvelteUi/scripts/generate_includes.py | 80 +++++++++++++++++ lib/SvelteUi/src/AmsWebServer.cpp | 16 ++++ 36 files changed, 194 insertions(+), 4 deletions(-) rename {ui/svelte => lib/SvelteUi/app}/.gitignore (100%) rename {ui/svelte => lib/SvelteUi/app}/index.html (100%) rename {ui/svelte => lib/SvelteUi/app}/jsconfig.json (100%) rename {ui/svelte => lib/SvelteUi/app}/package-lock.json (100%) rename {ui/svelte => lib/SvelteUi/app}/package.json (100%) rename {ui/svelte => lib/SvelteUi/app}/postcss.config.cjs (100%) rename {ui/svelte => lib/SvelteUi/app}/src/App.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/app.postcss (100%) rename {ui/svelte => lib/SvelteUi/app}/src/assets/github.svg (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/AccountingData.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/AmpPlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Badge.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/BarChart.svelte (99%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Clock.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Counter.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Dashboard.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/DataStores.js (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/DayPlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Header.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/Helpers.js (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/MonthPlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/PowerGauge.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/PowerGaugeSvg.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/PricePlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/ReactiveData.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/TemperaturePlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/lib/VoltPlot.svelte (100%) rename {ui/svelte => lib/SvelteUi/app}/src/main.js (100%) rename {ui/svelte => lib/SvelteUi/app}/src/vite-env.d.ts (100%) rename {ui/svelte => lib/SvelteUi/app}/svelte.config.js (100%) rename {ui/svelte => lib/SvelteUi/app}/tailwind.config.cjs (100%) rename {ui/svelte => lib/SvelteUi/app}/vite.config.js (67%) create mode 100644 lib/SvelteUi/include/.gitignore create mode 100644 lib/SvelteUi/include/AmsWebServer.h create mode 100644 lib/SvelteUi/scripts/generate_includes.py create mode 100644 lib/SvelteUi/src/AmsWebServer.cpp diff --git a/ui/svelte/.gitignore b/lib/SvelteUi/app/.gitignore similarity index 100% rename from ui/svelte/.gitignore rename to lib/SvelteUi/app/.gitignore diff --git a/ui/svelte/index.html b/lib/SvelteUi/app/index.html similarity index 100% rename from ui/svelte/index.html rename to lib/SvelteUi/app/index.html diff --git a/ui/svelte/jsconfig.json b/lib/SvelteUi/app/jsconfig.json similarity index 100% rename from ui/svelte/jsconfig.json rename to lib/SvelteUi/app/jsconfig.json diff --git a/ui/svelte/package-lock.json b/lib/SvelteUi/app/package-lock.json similarity index 100% rename from ui/svelte/package-lock.json rename to lib/SvelteUi/app/package-lock.json diff --git a/ui/svelte/package.json b/lib/SvelteUi/app/package.json similarity index 100% rename from ui/svelte/package.json rename to lib/SvelteUi/app/package.json diff --git a/ui/svelte/postcss.config.cjs b/lib/SvelteUi/app/postcss.config.cjs similarity index 100% rename from ui/svelte/postcss.config.cjs rename to lib/SvelteUi/app/postcss.config.cjs diff --git a/ui/svelte/src/App.svelte b/lib/SvelteUi/app/src/App.svelte similarity index 100% rename from ui/svelte/src/App.svelte rename to lib/SvelteUi/app/src/App.svelte diff --git a/ui/svelte/src/app.postcss b/lib/SvelteUi/app/src/app.postcss similarity index 100% rename from ui/svelte/src/app.postcss rename to lib/SvelteUi/app/src/app.postcss diff --git a/ui/svelte/src/assets/github.svg b/lib/SvelteUi/app/src/assets/github.svg similarity index 100% rename from ui/svelte/src/assets/github.svg rename to lib/SvelteUi/app/src/assets/github.svg diff --git a/ui/svelte/src/lib/AccountingData.svelte b/lib/SvelteUi/app/src/lib/AccountingData.svelte similarity index 100% rename from ui/svelte/src/lib/AccountingData.svelte rename to lib/SvelteUi/app/src/lib/AccountingData.svelte diff --git a/ui/svelte/src/lib/AmpPlot.svelte b/lib/SvelteUi/app/src/lib/AmpPlot.svelte similarity index 100% rename from ui/svelte/src/lib/AmpPlot.svelte rename to lib/SvelteUi/app/src/lib/AmpPlot.svelte diff --git a/ui/svelte/src/lib/Badge.svelte b/lib/SvelteUi/app/src/lib/Badge.svelte similarity index 100% rename from ui/svelte/src/lib/Badge.svelte rename to lib/SvelteUi/app/src/lib/Badge.svelte diff --git a/ui/svelte/src/lib/BarChart.svelte b/lib/SvelteUi/app/src/lib/BarChart.svelte similarity index 99% rename from ui/svelte/src/lib/BarChart.svelte rename to lib/SvelteUi/app/src/lib/BarChart.svelte index 764822e8..fb5f5c74 100644 --- a/ui/svelte/src/lib/BarChart.svelte +++ b/lib/SvelteUi/app/src/lib/BarChart.svelte @@ -68,10 +68,6 @@ diff --git a/lib/SvelteUi/app/src/lib/Clock.svelte b/lib/SvelteUi/app/src/lib/Clock.svelte index f59e557c..e0f5dc57 100644 --- a/lib/SvelteUi/app/src/lib/Clock.svelte +++ b/lib/SvelteUi/app/src/lib/Clock.svelte @@ -1,8 +1,7 @@ {#if Math.abs(new Date().getTime()-timestamp.getTime()) < 300000 } diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index c69f928e..9f1b2e0a 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -5,6 +5,9 @@ import Mask from './Mask.svelte' import Badge from './Badge.svelte'; import HelpIcon from './HelpIcon.svelte'; + import CountrySelectOptions from './CountrySelectOptions.svelte'; + import { Link, navigate } from 'svelte-navigator'; + export let sysinfo = {} @@ -87,71 +90,95 @@ }); loadingOrSaving = false; - getConfiguration(); + navigate("/"); } + + async function reboot() { + const response = await fetch('/reboot', { + method: 'POST' + }); + let res = (await response.json()) + } + + const askReboot = function() { + if(confirm('Are you sure you want to reboot the device?')) { + sysinfoStore.update(s => { + s.booting = true; + return s; + }); + reboot(); + } + } + + const updateMqttPort = function() { + if(configuration.q.s.e) { + if(configuration.q.p == 1883) configuration.q.p = 8883; + } else { + if(configuration.q.p == 8883) configuration.q.p = 1883; + } + }
-
+
General
Hostname
- +
- Timezone
- +
+
+ Price region
+ +
-
- Price region
- -
Currency
- @@ -160,7 +187,7 @@
Multiplier
- +
@@ -168,13 +195,13 @@
{#if configuration.p.e} -
+
{/if}
{/if}
Security
- @@ -183,22 +210,22 @@ {#if configuration.g.s > 0}
Username
- +
Password
- +
{/if}
-
+
Meter
Serial configuration
- @@ -207,37 +234,37 @@ - - +
+
+ Voltage
+ +
-
- Voltage
- -
-
+
Main fuse
-
+
Production
@@ -247,13 +274,13 @@
{#if configuration.m.e.e} -
+
{/if}
{#if configuration.m.e.e}
Authentication key
- +
{/if} @@ -262,39 +289,39 @@
Instant
- +
Volt
- +
Amp
- +
Acc.
- +
{/if}
-
+
WiFi
SSID
- +
Password
- +
Power saving
- @@ -304,24 +331,24 @@
Power
-
+
Network
IP
- - - + +
DNS
- - + +
{/if} @@ -348,62 +375,70 @@
NTP
- +
-
+
MQTT
Server - + {#if sysinfo.chip != 'esp8266'} + + {/if}
- - + +
{#if configuration.q.s.e}
- {#if configuration.q.s.c} - - {:else} - - {/if} + + {#if configuration.q.s.c} + + {:else} + + {/if} + - {#if configuration.q.s.r} - - {:else} - - {/if} + + {#if configuration.q.s.r} + + {:else} + + {/if} + - {#if configuration.q.s.k} - - {:else} - - {/if} + + {#if configuration.q.s.k} + + {:else} + + {/if} +
{/if}
Username
- +
Password
- +
Client ID
- +
Payload
- @@ -415,70 +450,70 @@
Publish topic
- +
{#if configuration.p.r.startsWith("10YNO") || configuration.p.r == '10Y1001A1001A48H'} -
+
Tariff thresholds
{/if} {#if sysinfo.board > 20 || sysinfo.chip == 'esp8266'} -
+
Hardware {#if sysinfo.board > 20} @@ -486,48 +521,48 @@
HAN
-
AP button
- +
LED
- +
RGB
- - - + + +
Temperature
- +
Analog temp
- +
{#if sysinfo.chip != 'esp8266'}
Vcc
- +
{/if} {#if configuration.i.v.p > 0}
Voltage divider
- - + +
{/if} @@ -538,38 +573,39 @@
Vcc offset
- +
- multiplier
- + Multiplier
+
{#if sysinfo.board == 2 || sysinfo.board == 100} -
- boot limit
- +
+ Boot limit
+
{/if}
{/if}
{/if} -
+
Debugging +
{#if configuration.d.s} -
Debug can cause sudden reboots. Do not leave on!
+
Debug can cause sudden reboots. Do not leave on!
{#if configuration.d.t} -
Telnet is unsafe and should be off when not in use
+
Telnet is unsafe and should be off when not in use
{/if}
- @@ -579,8 +615,17 @@ {/if}
- - +
+
+ +
+
+ +
+
+ +
+
diff --git a/lib/SvelteUi/app/src/lib/Counter.svelte b/lib/SvelteUi/app/src/lib/Counter.svelte deleted file mode 100644 index e45f9031..00000000 --- a/lib/SvelteUi/app/src/lib/Counter.svelte +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/lib/SvelteUi/app/src/lib/CountrySelectOptions.svelte b/lib/SvelteUi/app/src/lib/CountrySelectOptions.svelte new file mode 100644 index 00000000..c3ff3ac5 --- /dev/null +++ b/lib/SvelteUi/app/src/lib/CountrySelectOptions.svelte @@ -0,0 +1,10 @@ + + + +{#each europe as c} + +{/each} diff --git a/lib/SvelteUi/app/src/lib/Dashboard.svelte b/lib/SvelteUi/app/src/lib/Dashboard.svelte index a09727e8..254f8ac4 100644 --- a/lib/SvelteUi/app/src/lib/Dashboard.svelte +++ b/lib/SvelteUi/app/src/lib/Dashboard.svelte @@ -32,7 +32,7 @@
-
+
@@ -42,7 +42,7 @@
{#if data.om || data.e > 0} -
+
@@ -52,36 +52,40 @@
{/if} -
+ {#if data.u1 > 100 || data.u2 > 100 || data.u3 > 100} +
-
+ {/if} + {#if data.i1 > 0.01 || data.i2 > 0.01 || data.i3 > 0.01} +
-
+ {/if} +
-
+
- {#if prices.currency == 'NOK'} -
+ {#if data && data.ea} +
{/if} {#if prices.currency} -
+
{/if} -
+
-
+
{#if data.t && data.t != -127 && temperatures.c > 1} -
+
{/if} diff --git a/lib/SvelteUi/app/src/lib/DataStores.js b/lib/SvelteUi/app/src/lib/DataStores.js index b1b8aade..215ce85a 100644 --- a/lib/SvelteUi/app/src/lib/DataStores.js +++ b/lib/SvelteUi/app/src/lib/DataStores.js @@ -127,6 +127,19 @@ export const temperaturesStore = writable(temperatures, (set) => { return function stop() {} }); +let tariff = {}; +export async function getTariff() { + const response = await fetchWithTimeout("/tariff.json"); + tariff = (await response.json()) + tariffStore.set(tariff); + let date = new Date(); + setTimeout(getTariff, (61-date.getMinutes())*60000) +} + +export const tariffStore = writable(tariff, (set) => { + return function stop() {} +}); + let releases = []; export const gitHubReleaseStore = writable(releases); diff --git a/lib/SvelteUi/app/src/lib/DayPlot.svelte b/lib/SvelteUi/app/src/lib/DayPlot.svelte index db0495fb..7ee09bdc 100644 --- a/lib/SvelteUi/app/src/lib/DayPlot.svelte +++ b/lib/SvelteUi/app/src/lib/DayPlot.svelte @@ -14,6 +14,7 @@ let xTicks = []; let points = []; let cur = new Date(); + let offset = -cur.getTimezoneOffset()/60; for(i = cur.getUTCHours(); i<24; i++) { let imp = json["i"+zeropad(i)]; let exp = json["e"+zeropad(i)]; @@ -21,7 +22,7 @@ if(exp === undefined) exp = 0; xTicks.push({ - label: zeropad(i) + label: zeropad((i+offset)%24) }); points.push({ label: imp.toFixed(1), @@ -40,7 +41,7 @@ if(exp === undefined) exp = 0; xTicks.push({ - label: zeropad(i) + label: zeropad((i+offset)%24) }); points.push({ label: imp.toFixed(1), @@ -58,13 +59,15 @@ max = boundary; min = min == 0 ? 0 : boundary*-1; - let yTickDistDown = min/4; - for(i = 0; i < 5; i++) { - let val = (yTickDistDown*i); - yTicks.push({ - value: val, - label: (val/10).toFixed(1) - }); + if(min < 0) { + let yTickDistDown = min/4; + for(i = 1; i < 5; i++) { + let val = (yTickDistDown*i); + yTicks.push({ + value: val, + label: (val/10).toFixed(1) + }); + } } let yTickDistUp = max/4; diff --git a/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte b/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte new file mode 100644 index 00000000..46c4dc78 --- /dev/null +++ b/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte @@ -0,0 +1,18 @@ + + +
+
+ Upload {title} +

Select a suitable file and click upload

+
+ +
+ +
+
+
+
diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index 3520b8a8..c6265dd1 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -10,7 +10,6 @@ import GearIcon from './GearIcon.svelte'; import InfoIcon from "./InfoIcon.svelte"; import HelpIcon from "./HelpIcon.svelte"; - import ReloadIcon from "./ReloadIcon.svelte"; import DownloadIcon from "./DownloadIcon.svelte"; export let data = {} diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index a71db001..14ce27c6 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -1,3 +1,5 @@ +export let monthnames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; + export function voltcol(pct) { if(pct > 85) return '#d90000'; else if(pct > 75) return'#e32100'; diff --git a/lib/SvelteUi/app/src/lib/MonthPlot.svelte b/lib/SvelteUi/app/src/lib/MonthPlot.svelte index 87905a00..15991410 100644 --- a/lib/SvelteUi/app/src/lib/MonthPlot.svelte +++ b/lib/SvelteUi/app/src/lib/MonthPlot.svelte @@ -61,13 +61,15 @@ max = boundary; min = min == 0 ? 0 : boundary*-1; - let yTickDistDown = min/4; - for(i = 0; i < 5; i++) { - let val = (yTickDistDown*i); - yTicks.push({ - value: val, - label: val.toFixed(0) - }); + if(min < 0) { + let yTickDistDown = min/4; + for(i = 0; i < 5; i++) { + let val = (yTickDistDown*i); + yTicks.push({ + value: val, + label: val.toFixed(0) + }); + } } let yTickDistUp = max/4; diff --git a/lib/SvelteUi/app/src/lib/PowerGauge.svelte b/lib/SvelteUi/app/src/lib/PowerGauge.svelte index 334adf43..a04151b9 100644 --- a/lib/SvelteUi/app/src/lib/PowerGauge.svelte +++ b/lib/SvelteUi/app/src/lib/PowerGauge.svelte @@ -8,35 +8,12 @@ export let label; -
+
- - {val} - {unit} + + {val} + {unit}
- {label} + {label}
- - diff --git a/lib/SvelteUi/app/src/lib/PricePlot.svelte b/lib/SvelteUi/app/src/lib/PricePlot.svelte index f2e9c2a2..8d2509ef 100644 --- a/lib/SvelteUi/app/src/lib/PricePlot.svelte +++ b/lib/SvelteUi/app/src/lib/PricePlot.svelte @@ -56,13 +56,15 @@ max = Math.ceil(max); min = Math.floor(min); - let yTickDistDown = min/4; - for(i = 0; i < 5; i++) { - let val = (yTickDistDown*i); - yTicks.push({ - value: val, - label: (val/100).toFixed(2) - }); + if(min < 0) { + let yTickDistDown = min/4; + for(i = 1; i < 5; i++) { + let val = (yTickDistDown*i); + yTicks.push({ + value: val, + label: (val/100).toFixed(2) + }); + } } let yTickDistUp = max/4; @@ -74,6 +76,8 @@ }); } + console.log(yTicks); + config = { title: "Future energy price (" + json.currency + ")", padding: { top: 20, right: 15, bottom: 20, left: 35 }, diff --git a/lib/SvelteUi/app/src/lib/ReloadIcon.svelte b/lib/SvelteUi/app/src/lib/ReloadIcon.svelte deleted file mode 100644 index d1bbaff3..00000000 --- a/lib/SvelteUi/app/src/lib/ReloadIcon.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte index 6f7713e7..087a71f6 100644 --- a/lib/SvelteUi/app/src/lib/SetupPanel.svelte +++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte @@ -65,30 +65,30 @@ -
-
+
+
Setup
SSID
- +
PSK
- +
Hostname: - +
{#if staticIp}
- - + +
DNS
- +
{/if} @@ -113,7 +113,7 @@ Read more
- +
diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index cf842279..c15dbb2b 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -3,11 +3,9 @@ import { getSysinfo, gitHubReleaseStore, sysinfoStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; import DownloadIcon from './DownloadIcon.svelte'; - import UploadIcon from './UploadIcon.svelte'; - export let sysinfo = {} - export let data = {} - + export let sysinfo; + let nextVersion = {}; gitHubReleaseStore.subscribe(releases => { nextVersion = getNextVersion(sysinfo.version, releases); @@ -45,14 +43,12 @@ } } - let fileinput; - getSysinfo();
-
+
Device information
Chip: {sysinfo.chip} @@ -68,7 +64,7 @@
{#if sysinfo.meter} -
+
Meter
Manufacturer: {metertype(sysinfo.meter.mfg)} @@ -82,7 +78,7 @@
{/if} {#if sysinfo.net} -
+
Network
IP: {sysinfo.net.ip} @@ -98,7 +94,7 @@
{/if} -
+
Firmware
Installed version: {sysinfo.version} @@ -115,12 +111,12 @@
{#if sysinfo.fwconsent === 2}
-
You have disabled one-click firmware upgrade, link to self-upgrade is disabled
+
You have disabled one-click firmware upgrade, link to self-upgrade is disabled
{/if} {/if} {#if sysinfo.board == 2 || sysinfo.board == 4 || sysinfo.board == 7 } -
+
{boardtype(sysinfo.chip, sysinfo.board)} must be connected to an external power supply during firmware upgrade. Failure to do so may cause power-down during upload resulting in non-functioning unit.
{/if} diff --git a/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte b/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte index da039149..859a4ab7 100644 --- a/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte +++ b/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte @@ -1,16 +1,17 @@ -{#if chip == 'esp8266'} +{#if chip == 'esp8266'} - - - - - - - - - {/if} {#if chip == 'esp32' || chip == 'esp32solo'} - +{/if} +{#if chip == 'esp32s2'} + +{/if} +{#if chip.startsWith('esp32')} +{/if} +{#if chip == 'esp8266'} + +{/if} +{#if chip.startsWith('esp32')} +{/if} + +{#if chip.startsWith('esp32')} +{#if chip != 'esp32s2'} +{/if} @@ -45,33 +50,6 @@ {/if} {#if chip == 'esp32s2'} - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/lib/SvelteUi/app/src/lib/UpgradeHelper.js b/lib/SvelteUi/app/src/lib/UpgradeHelper.js index 31ab6ca3..ec2cb068 100644 --- a/lib/SvelteUi/app/src/lib/UpgradeHelper.js +++ b/lib/SvelteUi/app/src/lib/UpgradeHelper.js @@ -1,5 +1,3 @@ - - export async function upgrade(version) { const data = new URLSearchParams() data.append('version', version.tag_name); diff --git a/lib/SvelteUi/app/src/lib/UploadIcon.svelte b/lib/SvelteUi/app/src/lib/UploadIcon.svelte deleted file mode 100644 index 4aefd39e..00000000 --- a/lib/SvelteUi/app/src/lib/UploadIcon.svelte +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index d3801879..33f8d8d0 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -31,27 +31,27 @@ } -
-
+
+
Initial configuration
Board type
-
{#if sysinfo.board && sysinfo.board > 20}
HAN GPIO
-
{/if}
- +
 
diff --git a/lib/SvelteUi/app/vite.config.js b/lib/SvelteUi/app/vite.config.js index 9e1ad30c..dbfba4be 100644 --- a/lib/SvelteUi/app/vite.config.js +++ b/lib/SvelteUi/app/vite.config.js @@ -17,17 +17,18 @@ export default defineConfig({ plugins: [svelte()], server: { proxy: { - "/data.json": "http://192.168.233.229", - "/energyprice.json": "http://192.168.233.235", - "/dayplot.json": "http://192.168.233.235", - "/monthplot.json": "http://192.168.233.235", - "/temperature.json": "http://192.168.233.235", - "/sysinfo.json": "http://192.168.233.229", - "/configuration.json": "http://192.168.233.229", - "/save": "http://192.168.233.229", - "/reboot": "http://192.168.233.229", - "/firmware": "http://192.168.233.229", - "/upgrade": "http://192.168.233.229" + "/data.json": "http://192.168.233.244", + "/energyprice.json": "http://192.168.233.244", + "/dayplot.json": "http://192.168.233.244", + "/monthplot.json": "http://192.168.233.244", + "/temperature.json": "http://192.168.233.244", + "/sysinfo.json": "http://192.168.233.244", + "/configuration.json": "http://192.168.233.244", + "/tariff.json": "http://192.168.233.244", + "/save": "http://192.168.233.244", + "/reboot": "http://192.168.233.244", + "/firmware": "http://192.168.233.244", + "/upgrade": "http://192.168.233.244" } } }) diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index e763325e..4dc01981 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -84,6 +84,7 @@ private: void energyPriceJson(); void temperatureJson(); void wifiScanJson(); + void tariffJson(); void configurationJson(); void handleSave(); @@ -93,6 +94,9 @@ private: void firmwareUpload(); void isAliveCheck(); + void mqttCaUpload(); + void mqttCertUpload(); + void mqttKeyUpload(); HTTPUpload& uploadFile(const char* path); void factoryResetPost(); diff --git a/lib/SvelteUi/json/data.json b/lib/SvelteUi/json/data.json index 0581d6ac..eefea149 100644 --- a/lib/SvelteUi/json/data.json +++ b/lib/SvelteUi/json/data.json @@ -53,5 +53,6 @@ "p" : %.2f } }, + "pr" : "%s", "c" : %lu } \ No newline at end of file diff --git a/lib/SvelteUi/json/response.json b/lib/SvelteUi/json/response.json new file mode 100644 index 00000000..7a5c6ee3 --- /dev/null +++ b/lib/SvelteUi/json/response.json @@ -0,0 +1,5 @@ +{ + "success": %s, + "message": "%s", + "reboot": %s +} \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index f95226f0..ac82b70a 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -14,6 +14,7 @@ #include "html/monthplot_json.h" #include "html/energyprice_json.h" #include "html/tempsensor_json.h" +#include "html/response_json.h" #include "version.h" @@ -40,6 +41,10 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/configuration"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/status"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/mqtt-ca"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/mqtt-cert"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/mqtt-key"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/index.css"), HTTP_GET, std::bind(&AmsWebServer::indexCss, this)); server.on(F("/index.js"), HTTP_GET, std::bind(&AmsWebServer::indexJs, this)); server.on(F("/github.svg"), HTTP_GET, std::bind(&AmsWebServer::githubSvg, this)); @@ -50,6 +55,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/monthplot.json"), HTTP_GET, std::bind(&AmsWebServer::monthplotJson, this)); server.on(F("/energyprice.json"), HTTP_GET, std::bind(&AmsWebServer::energyPriceJson, this)); server.on(F("/temperature.json"), HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this)); + server.on(F("/tariff.json"), HTTP_GET, std::bind(&AmsWebServer::tariffJson, this)); server.on(F("/wifiscan.json"), HTTP_GET, std::bind(&AmsWebServer::wifiScanJson, this)); @@ -64,6 +70,10 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/robots.txt"), HTTP_GET, std::bind(&AmsWebServer::robotstxt, this)); + server.on(F("/mqtt-ca"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttCaUpload, this)); + server.on(F("/mqtt-cert"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttCertUpload, this)); + server.on(F("/mqtt-key"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttKeyUpload, this)); + server.onNotFound(std::bind(&AmsWebServer::notFound, this)); server.begin(); // Web server start @@ -157,55 +167,55 @@ void AmsWebServer::sysinfoJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /sysinfo.json over http...\n"); DynamicJsonDocument doc(512); - doc["version"] = VERSION; + doc[PSTR("version")] = VERSION; #if defined(CONFIG_IDF_TARGET_ESP32S2) - doc["chip"] = "esp32s2"; + doc[PSTR("chip")] = "esp32s2"; #elif defined(CONFIG_IDF_TARGET_ESP32C3) - doc["chip"] = "esp32c3"; + doc[PSTR("chip")] = "esp32c3"; #elif defined(ESP32) - doc["chip"] = "esp32"; + doc[PSTR("chip")] = "esp32"; #elif defined(ESP8266) - doc["chip"] = "esp8266"; + doc[PSTR("chip")] = "esp8266"; #endif - uint16_t chipId; + uint32_t chipId; #if defined(ESP32) - chipId = ESP.getEfuseMac(); + chipId = ( ESP.getEfuseMac() >> 32 ) % 0xFFFFFFFF; #else chipId = ESP.getChipId(); #endif String chipIdStr = String(chipId, HEX);; - doc["chipId"] = chipIdStr; - doc["mac"] = WiFi.macAddress(); + doc[PSTR("chipId")] = chipIdStr; + doc[PSTR("mac")] = WiFi.macAddress(); SystemConfig sys; config->getSystemConfig(sys); - doc["board"] = sys.boardType; - doc["vndcfg"] = sys.vendorConfigured; - doc["usrcfg"] = sys.userConfigured; - doc["fwconsent"] = sys.dataCollectionConsent; - doc["country"] = sys.country; + doc[PSTR("board")] = sys.boardType; + doc[PSTR("vndcfg")] = sys.vendorConfigured; + doc[PSTR("usrcfg")] = sys.userConfigured; + doc[PSTR("fwconsent")] = sys.dataCollectionConsent; + doc[PSTR("country")] = sys.country; if(sys.userConfigured) { WiFiConfig wifiConfig; config->getWiFiConfig(wifiConfig); - doc["hostname"] = wifiConfig.hostname; + doc[PSTR("hostname")] = wifiConfig.hostname; } else { - doc["hostname"] = "ams-"+chipIdStr; + doc[PSTR("hostname")] = "ams-"+chipIdStr; } - doc["booting"] = performRestart; - doc["upgrading"] = rebootForUpgrade; + doc[PSTR("booting")] = performRestart; + doc[PSTR("upgrading")] = rebootForUpgrade; - doc["net"]["ip"] = WiFi.localIP().toString(); - doc["net"]["mask"] = WiFi.subnetMask().toString(); - doc["net"]["gw"] = WiFi.gatewayIP().toString(); - doc["net"]["dns1"] = WiFi.dnsIP(0).toString(); - doc["net"]["dns2"] = WiFi.dnsIP(1).toString(); + doc[PSTR("net")][PSTR("ip")] = WiFi.localIP().toString(); + doc[PSTR("net")][PSTR("mask")] = WiFi.subnetMask().toString(); + doc[PSTR("net")][PSTR("gw")] = WiFi.gatewayIP().toString(); + doc[PSTR("net")][PSTR("dns1")] = WiFi.dnsIP(0).toString(); + doc[PSTR("net")][PSTR("dns2")] = WiFi.dnsIP(1).toString(); - doc["meter"]["mfg"] = meterState->getMeterType(); - doc["meter"]["model"] = meterState->getMeterModel(); - doc["meter"]["id"] = meterState->getMeterId(); + doc[PSTR("meter")][PSTR("mfg")] = meterState->getMeterType(); + doc[PSTR("meter")][PSTR("model")] = meterState->getMeterModel(); + doc[PSTR("meter")][PSTR("id")] = meterState->getMeterId(); serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -300,7 +310,7 @@ void AmsWebServer::dataJson() { String peaks = ""; for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) { if(!peaks.isEmpty()) peaks += ","; - peaks += String(ea->getPeak(i)); + peaks += String(ea->getPeak(i).value); } snprintf_P(buf, BufferSize, DATA_JSON, @@ -350,6 +360,7 @@ void AmsWebServer::dataJson() { ea->getUseThisMonth(), ea->getCostThisMonth(), ea->getProducedThisMonth(), + eapi == NULL ? "" : eapi->getArea(), (uint32_t) time(nullptr) ); @@ -659,7 +670,7 @@ void AmsWebServer::configurationJson() { return; DynamicJsonDocument doc(2048); - doc["version"] = VERSION; + doc[PSTR("version")] = VERSION; NtpConfig ntpConfig; config->getNtpConfig(ntpConfig); @@ -668,15 +679,11 @@ void AmsWebServer::configurationJson() { WebConfig webConfig; config->getWebConfig(webConfig); - if(ntpConfig.offset == 0 && ntpConfig.summerOffset == 0) - doc["g"]["t"] = "UTC"; - else if(ntpConfig.offset == 360 && ntpConfig.summerOffset == 360) - doc["g"]["t"] = "CET/CEST"; - - doc["g"]["h"] = wifiConfig.hostname; - doc["g"]["s"] = webConfig.security; - doc["g"]["u"] = webConfig.username; - doc["g"]["p"] = strlen(webConfig.password) > 0 ? "***" : ""; + doc[PSTR("g")][PSTR("t")] = ntpConfig.timezone; + doc[PSTR("g")][PSTR("h")] = wifiConfig.hostname; + doc[PSTR("g")][PSTR("s")] = webConfig.security; + doc[PSTR("g")][PSTR("u")] = webConfig.username; + doc[PSTR("g")][PSTR("p")] = strlen(webConfig.password) > 0 ? "***" : ""; bool encen = false; for(uint8_t i = 0; i < 16; i++) { @@ -686,161 +693,161 @@ void AmsWebServer::configurationJson() { } config->getMeterConfig(*meterConfig); - doc["m"]["b"] = meterConfig->baud; - doc["m"]["p"] = meterConfig->parity; - doc["m"]["i"] = meterConfig->invert; - doc["m"]["d"] = meterConfig->distributionSystem; - doc["m"]["f"] = meterConfig->mainFuse; - doc["m"]["r"] = meterConfig->productionCapacity; - doc["m"]["e"]["e"] = encen; - doc["m"]["e"]["k"] = toHex(meterConfig->encryptionKey, 16); - doc["m"]["e"]["a"] = toHex(meterConfig->authenticationKey, 16); - doc["m"]["m"]["e"] = meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1; - doc["m"]["m"]["w"] = meterConfig->wattageMultiplier / 1000.0; - doc["m"]["m"]["v"] = meterConfig->voltageMultiplier / 1000.0; - doc["m"]["m"]["a"] = meterConfig->amperageMultiplier / 1000.0; - doc["m"]["m"]["c"] = meterConfig->accumulatedMultiplier / 1000.0; + doc[PSTR("m")][PSTR("b")] = meterConfig->baud; + doc[PSTR("m")][PSTR("p")] = meterConfig->parity; + doc[PSTR("m")][PSTR("i")] = meterConfig->invert; + doc[PSTR("m")][PSTR("d")] = meterConfig->distributionSystem; + doc[PSTR("m")][PSTR("f")] = meterConfig->mainFuse; + doc[PSTR("m")][PSTR("r")] = meterConfig->productionCapacity; + doc[PSTR("m")][PSTR("e")][PSTR("e")] = encen; + doc[PSTR("m")][PSTR("e")][PSTR("k")] = toHex(meterConfig->encryptionKey, 16); + doc[PSTR("m")][PSTR("e")][PSTR("a")] = toHex(meterConfig->authenticationKey, 16); + doc[PSTR("m")][PSTR("m")][PSTR("e")] = meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1; + doc[PSTR("m")][PSTR("m")][PSTR("w")] = meterConfig->wattageMultiplier / 1000.0; + doc[PSTR("m")][PSTR("m")][PSTR("v")] = meterConfig->voltageMultiplier / 1000.0; + doc[PSTR("m")][PSTR("m")][PSTR("a")] = meterConfig->amperageMultiplier / 1000.0; + doc[PSTR("m")][PSTR("m")][PSTR("c")] = meterConfig->accumulatedMultiplier / 1000.0; EnergyAccountingConfig eac; config->getEnergyAccountingConfig(eac); - doc["t"]["t"][0] = eac.thresholds[0]; - doc["t"]["t"][1] = eac.thresholds[1]; - doc["t"]["t"][2] = eac.thresholds[2]; - doc["t"]["t"][3] = eac.thresholds[3]; - doc["t"]["t"][4] = eac.thresholds[4]; - doc["t"]["t"][5] = eac.thresholds[5]; - doc["t"]["t"][6] = eac.thresholds[6]; - doc["t"]["t"][7] = eac.thresholds[7]; - doc["t"]["t"][8] = eac.thresholds[8]; - doc["t"]["t"][9] = eac.thresholds[9]; - doc["t"]["h"] = eac.hours; + doc[PSTR("t")][PSTR("t")][0] = eac.thresholds[0]; + doc[PSTR("t")][PSTR("t")][1] = eac.thresholds[1]; + doc[PSTR("t")][PSTR("t")][2] = eac.thresholds[2]; + doc[PSTR("t")][PSTR("t")][3] = eac.thresholds[3]; + doc[PSTR("t")][PSTR("t")][4] = eac.thresholds[4]; + doc[PSTR("t")][PSTR("t")][5] = eac.thresholds[5]; + doc[PSTR("t")][PSTR("t")][6] = eac.thresholds[6]; + doc[PSTR("t")][PSTR("t")][7] = eac.thresholds[7]; + doc[PSTR("t")][PSTR("t")][8] = eac.thresholds[8]; + doc[PSTR("t")][PSTR("t")][9] = eac.thresholds[9]; + doc[PSTR("t")][PSTR("h")] = eac.hours; - doc["w"]["s"] = wifiConfig.ssid; - doc["w"]["p"] = strlen(wifiConfig.psk) > 0 ? "***" : ""; - doc["w"]["w"] = wifiConfig.power / 10.0; - doc["w"]["z"] = wifiConfig.sleep; + doc[PSTR("w")][PSTR("s")] = wifiConfig.ssid; + doc[PSTR("w")][PSTR("p")] = strlen(wifiConfig.psk) > 0 ? "***" : ""; + doc[PSTR("w")][PSTR("w")] = wifiConfig.power / 10.0; + doc[PSTR("w")][PSTR("z")] = wifiConfig.sleep; - doc["n"]["m"] = strlen(wifiConfig.ip) > 0 ? "static" : "dhcp"; - doc["n"]["i"] = wifiConfig.ip; - doc["n"]["s"] = wifiConfig.subnet; - doc["n"]["g"] = wifiConfig.gateway; - doc["n"]["d1"] = wifiConfig.dns1; - doc["n"]["d2"] = wifiConfig.dns2; - doc["n"]["d"] = wifiConfig.mdns; - doc["n"]["n1"] = ntpConfig.server; - doc["n"]["h"] = ntpConfig.dhcp; + doc[PSTR("n")][PSTR("m")] = strlen(wifiConfig.ip) > 0 ? "static" : "dhcp"; + doc[PSTR("n")][PSTR("i")] = wifiConfig.ip; + doc[PSTR("n")][PSTR("s")] = wifiConfig.subnet; + doc[PSTR("n")][PSTR("g")] = wifiConfig.gateway; + doc[PSTR("n")][PSTR("d1")] = wifiConfig.dns1; + doc[PSTR("n")][PSTR("d2")] = wifiConfig.dns2; + doc[PSTR("n")][PSTR("d")] = wifiConfig.mdns; + doc[PSTR("n")][PSTR("n1")] = ntpConfig.server; + doc[PSTR("n")][PSTR("h")] = ntpConfig.dhcp; MqttConfig mqttConfig; config->getMqttConfig(mqttConfig); - doc["q"]["h"] = mqttConfig.host; - doc["q"]["p"] = mqttConfig.port; - doc["q"]["u"] = mqttConfig.username; - doc["q"]["a"] = strlen(mqttConfig.password) > 0 ? "***" : ""; - doc["q"]["c"] = mqttConfig.clientId; - doc["q"]["b"] = mqttConfig.publishTopic; - doc["q"]["m"] = mqttConfig.payloadFormat; - doc["q"]["s"]["e"] = mqttConfig.ssl; + doc[PSTR("q")][PSTR("h")] = mqttConfig.host; + doc[PSTR("q")][PSTR("p")] = mqttConfig.port; + doc[PSTR("q")][PSTR("u")] = mqttConfig.username; + doc[PSTR("q")][PSTR("a")] = strlen(mqttConfig.password) > 0 ? "***" : ""; + doc[PSTR("q")][PSTR("c")] = mqttConfig.clientId; + doc[PSTR("q")][PSTR("b")] = mqttConfig.publishTopic; + doc[PSTR("q")][PSTR("m")] = mqttConfig.payloadFormat; + doc[PSTR("q")][PSTR("s")][PSTR("e")] = mqttConfig.ssl; if(LittleFS.begin()) { - doc["q"]["s"]["c"] = LittleFS.exists(FILE_MQTT_CA); - doc["q"]["s"]["r"] = LittleFS.exists(FILE_MQTT_CERT); - doc["q"]["s"]["k"] = LittleFS.exists(FILE_MQTT_KEY); + doc[PSTR("q")][PSTR("s")][PSTR("c")] = LittleFS.exists(FILE_MQTT_CA); + doc[PSTR("q")][PSTR("s")][PSTR("r")] = LittleFS.exists(FILE_MQTT_CERT); + doc[PSTR("q")][PSTR("s")][PSTR("k")] = LittleFS.exists(FILE_MQTT_KEY); LittleFS.end(); } else { - doc["q"]["s"]["c"] = false; - doc["q"]["s"]["r"] = false; - doc["q"]["s"]["k"] = false; + doc[PSTR("q")][PSTR("s")][PSTR("c")] = false; + doc[PSTR("q")][PSTR("s")][PSTR("r")] = false; + doc[PSTR("q")][PSTR("s")][PSTR("k")] = false; } EntsoeConfig entsoe; config->getEntsoeConfig(entsoe); - doc["p"]["e"] = strlen(entsoe.token) > 0; - doc["p"]["t"] = entsoe.token; - doc["p"]["r"] = entsoe.area; - doc["p"]["c"] = entsoe.currency; - doc["p"]["m"] = entsoe.multiplier / 1000.0; + doc[PSTR("p")][PSTR("e")] = strlen(entsoe.token) > 0; + doc[PSTR("p")][PSTR("t")] = entsoe.token; + doc[PSTR("p")][PSTR("r")] = entsoe.area; + doc[PSTR("p")][PSTR("c")] = entsoe.currency; + doc[PSTR("p")][PSTR("m")] = entsoe.multiplier / 1000.0; DebugConfig debugConfig; config->getDebugConfig(debugConfig); - doc["d"]["s"] = debugConfig.serial; - doc["d"]["t"] = debugConfig.telnet; - doc["d"]["l"] = debugConfig.level; + doc[PSTR("d")][PSTR("s")] = debugConfig.serial; + doc[PSTR("d")][PSTR("t")] = debugConfig.telnet; + doc[PSTR("d")][PSTR("l")] = debugConfig.level; GpioConfig gpioConfig; config->getGpioConfig(gpioConfig); if(gpioConfig.hanPin == 0xff) - doc["i"]["h"] = nullptr; + doc[PSTR("i")][PSTR("h")] = nullptr; else - doc["i"]["h"] = gpioConfig.hanPin; + doc[PSTR("i")][PSTR("h")] = gpioConfig.hanPin; if(gpioConfig.apPin == 0xff) - doc["i"]["a"] = nullptr; + doc[PSTR("i")][PSTR("a")] = nullptr; else - doc["i"]["a"] = gpioConfig.apPin; + doc[PSTR("i")][PSTR("a")] = gpioConfig.apPin; if(gpioConfig.ledPin == 0xff) - doc["i"]["l"]["p"] = nullptr; + doc[PSTR("i")][PSTR("l")][PSTR("p")] = nullptr; else - doc["i"]["l"]["p"] = gpioConfig.ledPin; + doc[PSTR("i")][PSTR("l")][PSTR("p")] = gpioConfig.ledPin; - doc["i"]["l"]["i"] = gpioConfig.ledInverted; + doc[PSTR("i")][PSTR("l")][PSTR("i")] = gpioConfig.ledInverted; if(gpioConfig.ledPinRed == 0xff) - doc["i"]["r"]["r"] = nullptr; + doc[PSTR("i")][PSTR("r")][PSTR("r")] = nullptr; else - doc["i"]["r"]["r"] = gpioConfig.ledPinRed; + doc[PSTR("i")][PSTR("r")][PSTR("r")] = gpioConfig.ledPinRed; if(gpioConfig.ledPinGreen == 0xff) - doc["i"]["r"]["g"] = nullptr; + doc[PSTR("i")][PSTR("r")][PSTR("g")] = nullptr; else - doc["i"]["r"]["g"] = gpioConfig.ledPinGreen; + doc[PSTR("i")][PSTR("r")][PSTR("g")] = gpioConfig.ledPinGreen; if(gpioConfig.ledPinBlue == 0xff) - doc["i"]["r"]["b"] = nullptr; + doc[PSTR("i")][PSTR("r")][PSTR("b")] = nullptr; else - doc["i"]["r"]["b"] = gpioConfig.ledPinBlue; + doc[PSTR("i")][PSTR("r")][PSTR("b")] = gpioConfig.ledPinBlue; - doc["i"]["r"]["i"] = gpioConfig.ledRgbInverted; + doc[PSTR("i")][PSTR("r")][PSTR("i")] = gpioConfig.ledRgbInverted; if(gpioConfig.tempSensorPin == 0xff) - doc["i"]["t"]["d"] = nullptr; + doc[PSTR("i")][PSTR("t")][PSTR("d")] = nullptr; else - doc["i"]["t"]["d"] = gpioConfig.tempSensorPin; + doc[PSTR("i")][PSTR("t")][PSTR("d")] = gpioConfig.tempSensorPin; if(gpioConfig.tempAnalogSensorPin == 0xff) - doc["i"]["t"]["a"] = nullptr; + doc[PSTR("i")][PSTR("t")][PSTR("a")] = nullptr; else - doc["i"]["t"]["a"] = gpioConfig.tempAnalogSensorPin; + doc[PSTR("i")][PSTR("t")][PSTR("a")] = gpioConfig.tempAnalogSensorPin; if(gpioConfig.vccPin == 0xff) - doc["i"]["v"]["p"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("p")] = nullptr; else - doc["i"]["v"]["p"] = gpioConfig.vccPin; + doc[PSTR("i")][PSTR("v")][PSTR("p")] = gpioConfig.vccPin; if(gpioConfig.vccOffset == 0) - doc["i"]["v"]["o"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("o")] = nullptr; else - doc["i"]["v"]["o"] = gpioConfig.vccOffset / 100.0; + doc[PSTR("i")][PSTR("v")][PSTR("o")] = gpioConfig.vccOffset / 100.0; if(gpioConfig.vccMultiplier == 0) - doc["i"]["v"]["m"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("m")] = nullptr; else - doc["i"]["v"]["m"] = gpioConfig.vccMultiplier / 1000.0; + doc[PSTR("i")][PSTR("v")][PSTR("m")] = gpioConfig.vccMultiplier / 1000.0; if(gpioConfig.vccResistorVcc == 0) - doc["i"]["v"]["d"]["v"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("v")] = nullptr; else - doc["i"]["v"]["d"]["v"] = gpioConfig.vccResistorVcc; + doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("v")] = gpioConfig.vccResistorVcc; if(gpioConfig.vccResistorGnd == 0) - doc["i"]["v"]["d"]["g"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("g")] = nullptr; else - doc["i"]["v"]["d"]["g"] = gpioConfig.vccResistorGnd; + doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("g")] = gpioConfig.vccResistorGnd; if(gpioConfig.vccBootLimit == 0) - doc["i"]["v"]["b"] = nullptr; + doc[PSTR("i")][PSTR("v")][PSTR("b")] = nullptr; else - doc["i"]["v"]["b"] = gpioConfig.vccBootLimit / 10.0; + doc[PSTR("i")][PSTR("v")][PSTR("b")] = gpioConfig.vccBootLimit / 10.0; serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -1094,18 +1101,23 @@ void AmsWebServer::handleSave() { if(server.hasArg(F("q")) && server.arg(F("q")) == F("true")) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received MQTT config")); MqttConfig mqtt; + config->getMqttConfig(mqtt); if(server.hasArg(F("qh")) && !server.arg(F("qh")).isEmpty()) { strcpy(mqtt.host, server.arg(F("qh")).c_str()); strcpy(mqtt.clientId, server.arg(F("qc")).c_str()); strcpy(mqtt.publishTopic, server.arg(F("qb")).c_str()); strcpy(mqtt.subscribeTopic, server.arg(F("qr")).c_str()); strcpy(mqtt.username, server.arg(F("qu")).c_str()); - String pass = server.arg(F("qp")); + String pass = server.arg(F("qa")); if(!pass.equals("***")) { strcpy(mqtt.password, pass.c_str()); } mqtt.payloadFormat = server.arg(F("qm")).toInt(); + #if defined(ESP8266) + mqtt.ssl = false; + #else mqtt.ssl = server.arg(F("qs")) == F("true"); + #endif mqtt.port = server.arg(F("qp")).toInt(); if(mqtt.port == 0) { @@ -1156,14 +1168,7 @@ void AmsWebServer::handleSave() { NtpConfig ntp; config->getNtpConfig(ntp); - String tz = server.arg(F("gt")); - if(tz.equals("UTC")) { - ntp.offset = 0; - ntp.summerOffset = 0; - } else if(tz.equals("CET/CEST")) { - ntp.offset = 360; - ntp.summerOffset = 360; - } + strcpy(ntp.timezone, server.arg(F("gt")).c_str()); config->setNtpConfig(ntp); } @@ -1251,22 +1256,23 @@ void AmsWebServer::handleSave() { if(debugger->isActive(RemoteDebug::INFO)) debugger->printf(PSTR("Saving configuration now...")); - DynamicJsonDocument doc(128); if (config->save()) { - doc["success"] = success; if(debugger->isActive(RemoteDebug::INFO)) debugger->printf(PSTR("Successfully saved.")); if(config->isWifiChanged() || performRestart) { performRestart = true; - doc["reboot"] = true; } else { - doc["reboot"] = false; hw->setup(gpioConfig, config); } } else { - doc["success"] = false; - doc["reboot"] = false; + success = false; } - serializeJson(doc, buf, BufferSize); + + snprintf_P(buf, BufferSize, RESPONSE_JSON, + success ? "true" : "false", + "", + performRestart ? "true" : "false" + ); + server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); server.handleClient(); @@ -1300,7 +1306,7 @@ void AmsWebServer::reboot() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /reboot over http...\n"); DynamicJsonDocument doc(128); - doc["reboot"] = true; + doc[PSTR("reboot")] = true; serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -1321,14 +1327,18 @@ void AmsWebServer::reboot() { void AmsWebServer::upgrade() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /upgrade over http...\n"); + if(!checkSecurity(1)) + return; + SystemConfig sys; config->getSystemConfig(sys); - DynamicJsonDocument doc(128); - doc["success"] = sys.dataCollectionConsent == 1; - doc["reboot"] = sys.dataCollectionConsent == 1; - - serializeJson(doc, buf, BufferSize); + snprintf_P(buf, BufferSize, RESPONSE_JSON, + sys.dataCollectionConsent == 1 ? "true" : "false", + "", + sys.dataCollectionConsent == 1 ? "true" : "false" + ); + server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); if(sys.dataCollectionConsent == 1) { @@ -1460,7 +1470,13 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { LittleFS.end(); if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("An Error has occurred while writing file")); - server.send_P(500, MIME_JSON, PSTR("{ \"success\": false, \"message\": \"Unable to upload\" }")); + snprintf_P(buf, BufferSize, RESPONSE_JSON, + "false", + "Unable to upload", + "false" + ); + server.setContentLength(strlen(buf)); + server.send(500, MIME_JSON, buf); } } } else if(upload.status == UPLOAD_FILE_END) { @@ -1469,7 +1485,13 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { file.close(); // LittleFS.end(); } else { - server.send_P(500, MIME_JSON, PSTR("{ \"success\": false, \"message\": \"Unable to upload\" }")); + snprintf_P(buf, BufferSize, RESPONSE_JSON, + "false", + "Unable to upload", + "false" + ); + server.setContentLength(strlen(buf)); + server.send(500, MIME_JSON, buf); } } return upload; @@ -1496,11 +1518,12 @@ void AmsWebServer::factoryResetPost() { success = true; } - DynamicJsonDocument doc(128); - doc["success"] = success; - doc["reboot"] = success; - - serializeJson(doc, buf, BufferSize); + snprintf_P(buf, BufferSize, RESPONSE_JSON, + success ? "true" : "false", + "", + "true" + ); + server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); server.handleClient(); @@ -1518,3 +1541,85 @@ void AmsWebServer::factoryResetPost() { void AmsWebServer::robotstxt() { server.send_P(200, MIME_HTML, PSTR("User-agent: *\nDisallow: /\n")); } + +void AmsWebServer::mqttCaUpload() { + if(!checkSecurity(1)) + return; + + uploadFile(FILE_MQTT_CA); + HTTPUpload& upload = server.upload(); + if(upload.status == UPLOAD_FILE_END) { + server.sendHeader(HEADER_LOCATION,F("/configuration")); + server.send(303); + + MqttConfig mqttConfig; + if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) { + config->setMqttChanged(); + } + } +} + +void AmsWebServer::mqttCertUpload() { + if(!checkSecurity(1)) + return; + + uploadFile(FILE_MQTT_CERT); + HTTPUpload& upload = server.upload(); + if(upload.status == UPLOAD_FILE_END) { + server.sendHeader(HEADER_LOCATION,F("/configuration")); + server.send(303); + MqttConfig mqttConfig; + if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) { + config->setMqttChanged(); + } + } +} + +void AmsWebServer::mqttKeyUpload() { + if(!checkSecurity(1)) + return; + + uploadFile(FILE_MQTT_KEY); + HTTPUpload& upload = server.upload(); + if(upload.status == UPLOAD_FILE_END) { + server.sendHeader(HEADER_LOCATION,F("/configuration")); + server.send(303); + MqttConfig mqttConfig; + if(config->getMqttConfig(mqttConfig) && mqttConfig.ssl) { + config->setMqttChanged(); + } + } +} + +void AmsWebServer::tariffJson() { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /tariff.json over http...\n"); + + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); + + if(!checkSecurity(1)) + return; + + EnergyAccountingConfig* eac = ea->getConfig(); + EnergyAccountingData data = ea->getData(); + + DynamicJsonDocument doc(512); + JsonArray thresholds = doc.createNestedArray(PSTR("t")); + for(uint8_t x = 0;x < 10; x++) { + thresholds.add(eac->thresholds[x]); + } + JsonArray peaks = doc.createNestedArray(PSTR("p")); + for(uint8_t x = 0;x < min((uint8_t) 5, eac->hours); x++) { + JsonObject p = peaks.createNestedObject(); + EnergyAccountingPeak peak = ea->getPeak(x); + p["d"] = peak.day; + p["v"] = peak.value / 100.0; + } + doc["c"] = ea->getCurrentThreshold(); + doc["m"] = ea->getMonthMax(); + + serializeJson(doc, buf, BufferSize); + server.send(200, MIME_JSON, buf); + +} \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 0a29ccbc..c11e0b3e 100755 --- a/platformio.ini +++ b/platformio.ini @@ -28,7 +28,7 @@ extra_scripts = ${common.extra_scripts} # Sticking to v2.0.3 because of #298 [env:esp32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.3/platform-espressif32-2.0.3.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip framework = arduino board = esp32dev board_build.f_cpu = 160000000L @@ -42,27 +42,26 @@ extra_scripts = ${common.extra_scripts} # https://github.com/Jason2866/esp32-arduino-lib-builder [env:esp32s2] -platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.3/platform-espressif32-2.0.3.zip -platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.3 +platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip framework = arduino -board = esp32dev +board = esp32-s2-saola-1 board_build.mcu = esp32s2 board_build.variant = esp32s2 board_build.flash_mode = qio board_build.f_cpu = 160000000L board_build.f_flash = 40000000L -build_flags = -D WEBSOCKET_DISABLED=1 +build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions lib_ldf_mode = off lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} [env:esp32solo] -platform = https://github.com/tasmota/platform-espressif32/releases/download/v.2.0.3/platform-espressif32-solo1-v.2.0.3.zip +platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip framework = arduino -board = esp32dev +board = esp32-solo1 board_build.f_cpu = 160000000L -build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions +build_flags = -D WEBSOCKET_DISABLED=1 -DFRAMEWORK_ARDUINO_SOLO1 -fexceptions lib_ldf_mode = off lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 05a8205a..8c112d51 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -72,6 +72,7 @@ ADC_MODE(ADC_VCC); #include "LNG.h" #include "ams/DataParsers.h" +#include "Timezones.h" uint8_t commonBuffer[BUF_SIZE_COMMON]; uint8_t hanBuffer[BUF_SIZE_HAN]; @@ -358,12 +359,10 @@ void setup() { NtpConfig ntp; if(config.getNtpConfig(ntp)) { - configTime(ntp.offset*10, ntp.summerOffset*10, ntp.enable ? strlen(ntp.server) > 0 ? ntp.server : (char*) F("pool.ntp.org") : (char*) F("")); // Add NTP server by default if none is configured + tz = resolveTimezone(ntp.timezone); + configTime(tz->toLocal(0), tz->toLocal(JULY1970)-JULY1970, ntp.enable ? strlen(ntp.server) > 0 ? ntp.server : (char*) F("pool.ntp.org") : (char*) F("")); // Add NTP server by default if none is configured sntp_servermode_dhcp(ntp.enable && ntp.dhcp ? 1 : 0); ntpEnabled = ntp.enable; - TimeChangeRule std = {"STD", Last, Sun, Oct, 3, ntp.offset / 6}; - TimeChangeRule dst = {"DST", Last, Sun, Mar, 2, (ntp.offset + ntp.summerOffset) / 6}; - tz = new Timezone(dst, std); ws.setTimezone(tz); ds.setTimezone(tz); ea.setTimezone(tz); @@ -489,14 +488,11 @@ void loop() { if(config.isNtpChanged()) { NtpConfig ntp; if(config.getNtpConfig(ntp)) { - configTime(ntp.offset*10, ntp.summerOffset*10, ntp.enable ? ntp.server : ""); + tz = resolveTimezone(ntp.timezone); + configTime(tz->toLocal(0), tz->toLocal(JULY1970)-JULY1970, ntp.enable ? strlen(ntp.server) > 0 ? ntp.server : (char*) F("pool.ntp.org") : (char*) F("")); // Add NTP server by default if none is configured sntp_servermode_dhcp(ntp.enable && ntp.dhcp ? 1 : 0); ntpEnabled = ntp.enable; - if(tz != NULL) delete tz; - TimeChangeRule std = {"STD", Last, Sun, Oct, 3, ntp.offset / 6}; - TimeChangeRule dst = {"DST", Last, Sun, Mar, 2, (ntp.offset + ntp.summerOffset) / 6}; - tz = new Timezone(dst, std); ws.setTimezone(tz); ds.setTimezone(tz); ea.setTimezone(tz); @@ -1324,12 +1320,19 @@ void MQTT_connect() { break; } + time_t epoch = time(nullptr); if(mqttConfig.ssl) { + if(epoch < BUILD_EPOCH) { + debugI("NTP not ready for MQTT SSL"); + return; + } debugI("MQTT SSL is configured (%dkb free heap)", ESP.getFreeHeap()); if(mqttSecureClient == NULL) { mqttSecureClient = new WiFiClientSecure(); #if defined(ESP8266) mqttSecureClient->setBufferSizes(512, 512); + debugD("ESP8266 firmware does not have enough memory..."); + return; #endif if(LittleFS.begin()) { @@ -1345,40 +1348,43 @@ void MQTT_connect() { mqttSecureClient->loadCACert(file, file.size()); #endif file.close(); + + if(LittleFS.exists(FILE_MQTT_CERT) && LittleFS.exists(FILE_MQTT_KEY)) { + #if defined(ESP8266) + debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap()); + file = LittleFS.open(FILE_MQTT_CERT, (char*) "r"); + BearSSL::X509List *serverCertList = new BearSSL::X509List(file); + file.close(); + + debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap()); + file = LittleFS.open(FILE_MQTT_KEY, (char*) "r"); + BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(file); + file.close(); + + debugD("Setting client certificates (%dkb free heap)", ESP.getFreeHeap()); + mqttSecureClient->setClientRSACert(serverCertList, serverPrivKey); + #elif defined(ESP32) + debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap()); + file = LittleFS.open(FILE_MQTT_CERT, (char*) "r"); + mqttSecureClient->loadCertificate(file, file.size()); + file.close(); + + debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap()); + file = LittleFS.open(FILE_MQTT_KEY, (char*) "r"); + mqttSecureClient->loadPrivateKey(file, file.size()); + file.close(); + #endif + mqttClient = mqttSecureClient; + } } - if(LittleFS.exists(FILE_MQTT_CERT) && LittleFS.exists(FILE_MQTT_KEY)) { - #if defined(ESP8266) - debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap()); - file = LittleFS.open(FILE_MQTT_CERT, (char*) "r"); - BearSSL::X509List *serverCertList = new BearSSL::X509List(file); - file.close(); - - debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap()); - file = LittleFS.open(FILE_MQTT_KEY, (char*) "r"); - BearSSL::PrivateKey *serverPrivKey = new BearSSL::PrivateKey(file); - file.close(); - - debugD("Setting client certificates (%dkb free heap)", ESP.getFreeHeap()); - mqttSecureClient->setClientRSACert(serverCertList, serverPrivKey); - #elif defined(ESP32) - debugI("Found MQTT certificate file (%dkb free heap)", ESP.getFreeHeap()); - file = LittleFS.open(FILE_MQTT_CERT, (char*) "r"); - mqttSecureClient->loadCertificate(file, file.size()); - file.close(); - - debugI("Found MQTT key file (%dkb free heap)", ESP.getFreeHeap()); - file = LittleFS.open(FILE_MQTT_KEY, (char*) "r"); - mqttSecureClient->loadPrivateKey(file, file.size()); - file.close(); - #endif - } LittleFS.end(); debugD("MQTT SSL setup complete (%dkb free heap)", ESP.getFreeHeap()); } } - mqttClient = mqttSecureClient; - } else if(mqttClient == NULL) { + } + + if(mqttClient == NULL) { mqttClient = new WiFiClient(); } @@ -1390,7 +1396,6 @@ void MQTT_connect() { #if defined(ESP8266) if(mqttSecureClient) { - time_t epoch = time(nullptr); debugD("Setting NTP time %lld for secure MQTT connection", epoch); mqttSecureClient->setX509Time(epoch); } @@ -1425,7 +1430,6 @@ void MQTT_connect() { yield(); } - void configFileParse() { debugD("Parsing config file"); @@ -1623,15 +1627,12 @@ void configFileParse() { } else if(strncmp_P(buf, PSTR("ntpDhcp "), 8) == 0) { if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; ntp.dhcp = String(buf+8).toInt() == 1; - } else if(strncmp_P(buf, PSTR("ntpOffset "), 10) == 0) { - if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; - ntp.offset = String(buf+10).toInt() / 10; - } else if(strncmp_P(buf, PSTR("ntpSummerOffset "), 16) == 0) { - if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; - ntp.summerOffset = String(buf+16).toInt() / 10; } else if(strncmp_P(buf, PSTR("ntpServer "), 10) == 0) { if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; memcpy(ntp.server, buf+10, size-10); + } else if(strncmp_P(buf, PSTR("ntpTimezone "), 12) == 0) { + if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; + memcpy(ntp.timezone, buf+12, size-12); } else if(strncmp_P(buf, PSTR("entsoeToken "), 12) == 0) { if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; }; memcpy(entsoe.token, buf+12, size-12); @@ -1768,4 +1769,4 @@ void configFileParse() { if(sDs) ds.save(); if(sEa) ea.save(); config.save(); -} +} \ No newline at end of file From 02ae3fc7f54ad0ef7158fa7e9744cde6aa4047d9 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 29 Nov 2022 20:20:56 +0100 Subject: [PATCH 18/66] More v2.2 --- lib/AmsConfiguration/src/AmsConfiguration.cpp | 9 +- lib/HwTools/src/HwTools.cpp | 2 +- lib/SvelteUi/app/src/App.svelte | 25 ++++-- lib/SvelteUi/app/src/app.postcss | 2 +- lib/SvelteUi/app/src/lib/BarChart.svelte | 2 +- .../app/src/lib/ConfigurationPanel.svelte | 89 ++++++++++--------- .../app/src/lib/ConsentComponent.svelte | 54 +++++++++++ lib/SvelteUi/app/src/lib/StatusPage.svelte | 6 +- .../app/src/lib/TariffPeakChart.svelte | 4 +- lib/SvelteUi/app/src/lib/VendorPanel.svelte | 2 + lib/SvelteUi/src/AmsWebServer.cpp | 12 ++- 11 files changed, 145 insertions(+), 62 deletions(-) create mode 100644 lib/SvelteUi/app/src/lib/ConsentComponent.svelte diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 0128a815..a0cb305d 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -860,12 +860,13 @@ bool AmsConfiguration::relocateConfig96() { EEPROM.get(CONFIG_NTP_START, ntp96); ntp.enable = ntp96.enable; ntp.dhcp = ntp96.dhcp; - if(ntp96.offset == 0 && ntp96.summerOffset == 0) { - strcpy(ntp.timezone, "GMT"); - } else if(ntp96.offset == 360 && ntp96.summerOffset == 360) { + if(ntp96.offset == 360 && ntp96.summerOffset == 360) { strcpy(ntp.timezone, "Europe/Oslo"); + } else { + strcpy(ntp.timezone, "GMT"); } - EEPROM.get(CONFIG_NTP_START, ntp); + strcpy(ntp.server, ntp96.server); + EEPROM.put(CONFIG_NTP_START, ntp); EEPROM.put(EEPROM_CONFIG_ADDRESS, 100); bool ret = EEPROM.commit(); diff --git a/lib/HwTools/src/HwTools.cpp b/lib/HwTools/src/HwTools.cpp index 4c5e3328..b97215d9 100644 --- a/lib/HwTools/src/HwTools.cpp +++ b/lib/HwTools/src/HwTools.cpp @@ -373,7 +373,7 @@ bool HwTools::ledBlink(uint8_t color, uint8_t blink) { if(!ledOn(color)) return false; delay(75); ledOff(color); - delay(75); + if(i != blink) delay(75); } return true; } diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 0e767cbc..818248c3 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -1,5 +1,5 @@ + +
+
+
+
+ Below are some stuff we need to know +
+
+
+ Enable one-click upgrade? (implies data collection)
+ Read more
+
+
+
+ +
+
+
+
+ + diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index c15dbb2b..18e0bfcc 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -3,6 +3,7 @@ import { getSysinfo, gitHubReleaseStore, sysinfoStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; import DownloadIcon from './DownloadIcon.svelte'; + import { Link } from 'svelte-navigator'; export let sysinfo; @@ -60,7 +61,10 @@ MAC: {sysinfo.mac}
- + + Change consents + +
{#if sysinfo.meter} diff --git a/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte b/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte index 859a4ab7..cbe48724 100644 --- a/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte +++ b/lib/SvelteUi/app/src/lib/TariffPeakChart.svelte @@ -59,7 +59,7 @@ if(tariffData && tariffData.c) { yTicks.push({ - label: tariffData.c.toFixed(1), + label: tariffData.c.toFixed(0), color: 'orange', value: tariffData.c, }); @@ -70,7 +70,7 @@ config = { title: "Tariff peaks", - padding: { top: 20, right: 15, bottom: 20, left: 35 }, + padding: { top: 20, right: 35, bottom: 20, left: 35 }, y: { min: min, max: max, diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index 33f8d8d0..185de3dd 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -3,6 +3,7 @@ import BoardTypeSelectOptions from './BoardTypeSelectOptions.svelte'; import UartSelectOptions from './UartSelectOptions.svelte'; import Mask from './Mask.svelte' + import { navigate } from 'svelte-navigator'; export let sysinfo = {} @@ -28,6 +29,7 @@ s.booting = res.reboot; return s; }); + navigate("/"); } diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index ac82b70a..fd169481 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -41,6 +41,9 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/configuration"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/status"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/consent"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/vendor"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + server.on(F("/setup"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/mqtt-ca"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/mqtt-cert"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/mqtt-key"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); @@ -184,7 +187,7 @@ void AmsWebServer::sysinfoJson() { #else chipId = ESP.getChipId(); #endif - String chipIdStr = String(chipId, HEX);; + String chipIdStr = String(chipId, HEX); doc[PSTR("chipId")] = chipIdStr; doc[PSTR("mac")] = WiFi.macAddress(); @@ -1033,6 +1036,11 @@ void AmsWebServer::handleSave() { config->setSystemConfig(sys); performRestart = true; + } else if(server.hasArg(F("sf")) && !server.arg(F("sf")).isEmpty()) { + SystemConfig sys; + config->getSystemConfig(sys); + sys.dataCollectionConsent = server.hasArg(F("sf")) && (server.arg(F("sf")) == F("true") || server.arg(F("sf")) == F("1")) ? 1 : 2; + config->setSystemConfig(sys); } if(server.hasArg(F("m")) && server.arg(F("m")) == F("true")) { @@ -1612,7 +1620,7 @@ void AmsWebServer::tariffJson() { JsonArray peaks = doc.createNestedArray(PSTR("p")); for(uint8_t x = 0;x < min((uint8_t) 5, eac->hours); x++) { JsonObject p = peaks.createNestedObject(); - EnergyAccountingPeak peak = ea->getPeak(x); + EnergyAccountingPeak peak = ea->getPeak(x+1); p["d"] = peak.day; p["v"] = peak.value / 100.0; } From 63a8d79b9591978a1e9e7ab54ce6ffa4245ac139 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 29 Nov 2022 20:50:36 +0100 Subject: [PATCH 19/66] Making it work on 8266 --- lib/SvelteUi/src/AmsWebServer.cpp | 246 +++++++++++++++--------------- src/AmsToMqttBridge.ino | 4 + 2 files changed, 127 insertions(+), 123 deletions(-) diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index fd169481..eb1745c0 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -170,15 +170,15 @@ void AmsWebServer::sysinfoJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /sysinfo.json over http...\n"); DynamicJsonDocument doc(512); - doc[PSTR("version")] = VERSION; + doc[F("version")] = VERSION; #if defined(CONFIG_IDF_TARGET_ESP32S2) - doc[PSTR("chip")] = "esp32s2"; + doc[F("chip")] = "esp32s2"; #elif defined(CONFIG_IDF_TARGET_ESP32C3) - doc[PSTR("chip")] = "esp32c3"; + doc[F("chip")] = "esp32c3"; #elif defined(ESP32) - doc[PSTR("chip")] = "esp32"; + doc[F("chip")] = "esp32"; #elif defined(ESP8266) - doc[PSTR("chip")] = "esp8266"; + doc[F("chip")] = "esp8266"; #endif uint32_t chipId; @@ -188,37 +188,37 @@ void AmsWebServer::sysinfoJson() { chipId = ESP.getChipId(); #endif String chipIdStr = String(chipId, HEX); - doc[PSTR("chipId")] = chipIdStr; - doc[PSTR("mac")] = WiFi.macAddress(); + doc[F("chipId")] = chipIdStr; + doc[F("mac")] = WiFi.macAddress(); SystemConfig sys; config->getSystemConfig(sys); - doc[PSTR("board")] = sys.boardType; - doc[PSTR("vndcfg")] = sys.vendorConfigured; - doc[PSTR("usrcfg")] = sys.userConfigured; - doc[PSTR("fwconsent")] = sys.dataCollectionConsent; - doc[PSTR("country")] = sys.country; + doc[F("board")] = sys.boardType; + doc[F("vndcfg")] = sys.vendorConfigured; + doc[F("usrcfg")] = sys.userConfigured; + doc[F("fwconsent")] = sys.dataCollectionConsent; + doc[F("country")] = sys.country; if(sys.userConfigured) { WiFiConfig wifiConfig; config->getWiFiConfig(wifiConfig); - doc[PSTR("hostname")] = wifiConfig.hostname; + doc[F("hostname")] = wifiConfig.hostname; } else { - doc[PSTR("hostname")] = "ams-"+chipIdStr; + doc[F("hostname")] = "ams-"+chipIdStr; } - doc[PSTR("booting")] = performRestart; - doc[PSTR("upgrading")] = rebootForUpgrade; + doc[F("booting")] = performRestart; + doc[F("upgrading")] = rebootForUpgrade; - doc[PSTR("net")][PSTR("ip")] = WiFi.localIP().toString(); - doc[PSTR("net")][PSTR("mask")] = WiFi.subnetMask().toString(); - doc[PSTR("net")][PSTR("gw")] = WiFi.gatewayIP().toString(); - doc[PSTR("net")][PSTR("dns1")] = WiFi.dnsIP(0).toString(); - doc[PSTR("net")][PSTR("dns2")] = WiFi.dnsIP(1).toString(); + doc[F("net")][F("ip")] = WiFi.localIP().toString(); + doc[F("net")][F("mask")] = WiFi.subnetMask().toString(); + doc[F("net")][F("gw")] = WiFi.gatewayIP().toString(); + doc[F("net")][F("dns1")] = WiFi.dnsIP(0).toString(); + doc[F("net")][F("dns2")] = WiFi.dnsIP(1).toString(); - doc[PSTR("meter")][PSTR("mfg")] = meterState->getMeterType(); - doc[PSTR("meter")][PSTR("model")] = meterState->getMeterModel(); - doc[PSTR("meter")][PSTR("id")] = meterState->getMeterId(); + doc[F("meter")][F("mfg")] = meterState->getMeterType(); + doc[F("meter")][F("model")] = meterState->getMeterModel(); + doc[F("meter")][F("id")] = meterState->getMeterId(); serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -673,7 +673,7 @@ void AmsWebServer::configurationJson() { return; DynamicJsonDocument doc(2048); - doc[PSTR("version")] = VERSION; + doc[F("version")] = VERSION; NtpConfig ntpConfig; config->getNtpConfig(ntpConfig); @@ -682,11 +682,11 @@ void AmsWebServer::configurationJson() { WebConfig webConfig; config->getWebConfig(webConfig); - doc[PSTR("g")][PSTR("t")] = ntpConfig.timezone; - doc[PSTR("g")][PSTR("h")] = wifiConfig.hostname; - doc[PSTR("g")][PSTR("s")] = webConfig.security; - doc[PSTR("g")][PSTR("u")] = webConfig.username; - doc[PSTR("g")][PSTR("p")] = strlen(webConfig.password) > 0 ? "***" : ""; + doc[F("g")][F("t")] = ntpConfig.timezone; + doc[F("g")][F("h")] = wifiConfig.hostname; + doc[F("g")][F("s")] = webConfig.security; + doc[F("g")][F("u")] = webConfig.username; + doc[F("g")][F("p")] = strlen(webConfig.password) > 0 ? "***" : ""; bool encen = false; for(uint8_t i = 0; i < 16; i++) { @@ -696,161 +696,161 @@ void AmsWebServer::configurationJson() { } config->getMeterConfig(*meterConfig); - doc[PSTR("m")][PSTR("b")] = meterConfig->baud; - doc[PSTR("m")][PSTR("p")] = meterConfig->parity; - doc[PSTR("m")][PSTR("i")] = meterConfig->invert; - doc[PSTR("m")][PSTR("d")] = meterConfig->distributionSystem; - doc[PSTR("m")][PSTR("f")] = meterConfig->mainFuse; - doc[PSTR("m")][PSTR("r")] = meterConfig->productionCapacity; - doc[PSTR("m")][PSTR("e")][PSTR("e")] = encen; - doc[PSTR("m")][PSTR("e")][PSTR("k")] = toHex(meterConfig->encryptionKey, 16); - doc[PSTR("m")][PSTR("e")][PSTR("a")] = toHex(meterConfig->authenticationKey, 16); - doc[PSTR("m")][PSTR("m")][PSTR("e")] = meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1; - doc[PSTR("m")][PSTR("m")][PSTR("w")] = meterConfig->wattageMultiplier / 1000.0; - doc[PSTR("m")][PSTR("m")][PSTR("v")] = meterConfig->voltageMultiplier / 1000.0; - doc[PSTR("m")][PSTR("m")][PSTR("a")] = meterConfig->amperageMultiplier / 1000.0; - doc[PSTR("m")][PSTR("m")][PSTR("c")] = meterConfig->accumulatedMultiplier / 1000.0; + doc[F("m")][F("b")] = meterConfig->baud; + doc[F("m")][F("p")] = meterConfig->parity; + doc[F("m")][F("i")] = meterConfig->invert; + doc[F("m")][F("d")] = meterConfig->distributionSystem; + doc[F("m")][F("f")] = meterConfig->mainFuse; + doc[F("m")][F("r")] = meterConfig->productionCapacity; + doc[F("m")][F("e")][F("e")] = encen; + doc[F("m")][F("e")][F("k")] = toHex(meterConfig->encryptionKey, 16); + doc[F("m")][F("e")][F("a")] = toHex(meterConfig->authenticationKey, 16); + doc[F("m")][F("m")][F("e")] = meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1; + doc[F("m")][F("m")][F("w")] = meterConfig->wattageMultiplier / 1000.0; + doc[F("m")][F("m")][F("v")] = meterConfig->voltageMultiplier / 1000.0; + doc[F("m")][F("m")][F("a")] = meterConfig->amperageMultiplier / 1000.0; + doc[F("m")][F("m")][F("c")] = meterConfig->accumulatedMultiplier / 1000.0; EnergyAccountingConfig eac; config->getEnergyAccountingConfig(eac); - doc[PSTR("t")][PSTR("t")][0] = eac.thresholds[0]; - doc[PSTR("t")][PSTR("t")][1] = eac.thresholds[1]; - doc[PSTR("t")][PSTR("t")][2] = eac.thresholds[2]; - doc[PSTR("t")][PSTR("t")][3] = eac.thresholds[3]; - doc[PSTR("t")][PSTR("t")][4] = eac.thresholds[4]; - doc[PSTR("t")][PSTR("t")][5] = eac.thresholds[5]; - doc[PSTR("t")][PSTR("t")][6] = eac.thresholds[6]; - doc[PSTR("t")][PSTR("t")][7] = eac.thresholds[7]; - doc[PSTR("t")][PSTR("t")][8] = eac.thresholds[8]; - doc[PSTR("t")][PSTR("t")][9] = eac.thresholds[9]; - doc[PSTR("t")][PSTR("h")] = eac.hours; + doc[F("t")][F("t")][0] = eac.thresholds[0]; + doc[F("t")][F("t")][1] = eac.thresholds[1]; + doc[F("t")][F("t")][2] = eac.thresholds[2]; + doc[F("t")][F("t")][3] = eac.thresholds[3]; + doc[F("t")][F("t")][4] = eac.thresholds[4]; + doc[F("t")][F("t")][5] = eac.thresholds[5]; + doc[F("t")][F("t")][6] = eac.thresholds[6]; + doc[F("t")][F("t")][7] = eac.thresholds[7]; + doc[F("t")][F("t")][8] = eac.thresholds[8]; + doc[F("t")][F("t")][9] = eac.thresholds[9]; + doc[F("t")][F("h")] = eac.hours; - doc[PSTR("w")][PSTR("s")] = wifiConfig.ssid; - doc[PSTR("w")][PSTR("p")] = strlen(wifiConfig.psk) > 0 ? "***" : ""; - doc[PSTR("w")][PSTR("w")] = wifiConfig.power / 10.0; - doc[PSTR("w")][PSTR("z")] = wifiConfig.sleep; + doc[F("w")][F("s")] = wifiConfig.ssid; + doc[F("w")][F("p")] = strlen(wifiConfig.psk) > 0 ? "***" : ""; + doc[F("w")][F("w")] = wifiConfig.power / 10.0; + doc[F("w")][F("z")] = wifiConfig.sleep; - doc[PSTR("n")][PSTR("m")] = strlen(wifiConfig.ip) > 0 ? "static" : "dhcp"; - doc[PSTR("n")][PSTR("i")] = wifiConfig.ip; - doc[PSTR("n")][PSTR("s")] = wifiConfig.subnet; - doc[PSTR("n")][PSTR("g")] = wifiConfig.gateway; - doc[PSTR("n")][PSTR("d1")] = wifiConfig.dns1; - doc[PSTR("n")][PSTR("d2")] = wifiConfig.dns2; - doc[PSTR("n")][PSTR("d")] = wifiConfig.mdns; - doc[PSTR("n")][PSTR("n1")] = ntpConfig.server; - doc[PSTR("n")][PSTR("h")] = ntpConfig.dhcp; + doc[F("n")][F("m")] = strlen(wifiConfig.ip) > 0 ? "static" : "dhcp"; + doc[F("n")][F("i")] = wifiConfig.ip; + doc[F("n")][F("s")] = wifiConfig.subnet; + doc[F("n")][F("g")] = wifiConfig.gateway; + doc[F("n")][F("d1")] = wifiConfig.dns1; + doc[F("n")][F("d2")] = wifiConfig.dns2; + doc[F("n")][F("d")] = wifiConfig.mdns; + doc[F("n")][F("n1")] = ntpConfig.server; + doc[F("n")][F("h")] = ntpConfig.dhcp; MqttConfig mqttConfig; config->getMqttConfig(mqttConfig); - doc[PSTR("q")][PSTR("h")] = mqttConfig.host; - doc[PSTR("q")][PSTR("p")] = mqttConfig.port; - doc[PSTR("q")][PSTR("u")] = mqttConfig.username; - doc[PSTR("q")][PSTR("a")] = strlen(mqttConfig.password) > 0 ? "***" : ""; - doc[PSTR("q")][PSTR("c")] = mqttConfig.clientId; - doc[PSTR("q")][PSTR("b")] = mqttConfig.publishTopic; - doc[PSTR("q")][PSTR("m")] = mqttConfig.payloadFormat; - doc[PSTR("q")][PSTR("s")][PSTR("e")] = mqttConfig.ssl; + doc[F("q")][F("h")] = mqttConfig.host; + doc[F("q")][F("p")] = mqttConfig.port; + doc[F("q")][F("u")] = mqttConfig.username; + doc[F("q")][F("a")] = strlen(mqttConfig.password) > 0 ? "***" : ""; + doc[F("q")][F("c")] = mqttConfig.clientId; + doc[F("q")][F("b")] = mqttConfig.publishTopic; + doc[F("q")][F("m")] = mqttConfig.payloadFormat; + doc[F("q")][F("s")][F("e")] = mqttConfig.ssl; if(LittleFS.begin()) { - doc[PSTR("q")][PSTR("s")][PSTR("c")] = LittleFS.exists(FILE_MQTT_CA); - doc[PSTR("q")][PSTR("s")][PSTR("r")] = LittleFS.exists(FILE_MQTT_CERT); - doc[PSTR("q")][PSTR("s")][PSTR("k")] = LittleFS.exists(FILE_MQTT_KEY); + doc[F("q")][F("s")][F("c")] = LittleFS.exists(FILE_MQTT_CA); + doc[F("q")][F("s")][F("r")] = LittleFS.exists(FILE_MQTT_CERT); + doc[F("q")][F("s")][F("k")] = LittleFS.exists(FILE_MQTT_KEY); LittleFS.end(); } else { - doc[PSTR("q")][PSTR("s")][PSTR("c")] = false; - doc[PSTR("q")][PSTR("s")][PSTR("r")] = false; - doc[PSTR("q")][PSTR("s")][PSTR("k")] = false; + doc[F("q")][F("s")][F("c")] = false; + doc[F("q")][F("s")][F("r")] = false; + doc[F("q")][F("s")][F("k")] = false; } EntsoeConfig entsoe; config->getEntsoeConfig(entsoe); - doc[PSTR("p")][PSTR("e")] = strlen(entsoe.token) > 0; - doc[PSTR("p")][PSTR("t")] = entsoe.token; - doc[PSTR("p")][PSTR("r")] = entsoe.area; - doc[PSTR("p")][PSTR("c")] = entsoe.currency; - doc[PSTR("p")][PSTR("m")] = entsoe.multiplier / 1000.0; + doc[F("p")][F("e")] = strlen(entsoe.token) > 0; + doc[F("p")][F("t")] = entsoe.token; + doc[F("p")][F("r")] = entsoe.area; + doc[F("p")][F("c")] = entsoe.currency; + doc[F("p")][F("m")] = entsoe.multiplier / 1000.0; DebugConfig debugConfig; config->getDebugConfig(debugConfig); - doc[PSTR("d")][PSTR("s")] = debugConfig.serial; - doc[PSTR("d")][PSTR("t")] = debugConfig.telnet; - doc[PSTR("d")][PSTR("l")] = debugConfig.level; + doc[F("d")][F("s")] = debugConfig.serial; + doc[F("d")][F("t")] = debugConfig.telnet; + doc[F("d")][F("l")] = debugConfig.level; GpioConfig gpioConfig; config->getGpioConfig(gpioConfig); if(gpioConfig.hanPin == 0xff) - doc[PSTR("i")][PSTR("h")] = nullptr; + doc[F("i")][F("h")] = nullptr; else - doc[PSTR("i")][PSTR("h")] = gpioConfig.hanPin; + doc[F("i")][F("h")] = gpioConfig.hanPin; if(gpioConfig.apPin == 0xff) - doc[PSTR("i")][PSTR("a")] = nullptr; + doc[F("i")][F("a")] = nullptr; else - doc[PSTR("i")][PSTR("a")] = gpioConfig.apPin; + doc[F("i")][F("a")] = gpioConfig.apPin; if(gpioConfig.ledPin == 0xff) - doc[PSTR("i")][PSTR("l")][PSTR("p")] = nullptr; + doc[F("i")][F("l")][F("p")] = nullptr; else - doc[PSTR("i")][PSTR("l")][PSTR("p")] = gpioConfig.ledPin; + doc[F("i")][F("l")][F("p")] = gpioConfig.ledPin; - doc[PSTR("i")][PSTR("l")][PSTR("i")] = gpioConfig.ledInverted; + doc[F("i")][F("l")][F("i")] = gpioConfig.ledInverted; if(gpioConfig.ledPinRed == 0xff) - doc[PSTR("i")][PSTR("r")][PSTR("r")] = nullptr; + doc[F("i")][F("r")][F("r")] = nullptr; else - doc[PSTR("i")][PSTR("r")][PSTR("r")] = gpioConfig.ledPinRed; + doc[F("i")][F("r")][F("r")] = gpioConfig.ledPinRed; if(gpioConfig.ledPinGreen == 0xff) - doc[PSTR("i")][PSTR("r")][PSTR("g")] = nullptr; + doc[F("i")][F("r")][F("g")] = nullptr; else - doc[PSTR("i")][PSTR("r")][PSTR("g")] = gpioConfig.ledPinGreen; + doc[F("i")][F("r")][F("g")] = gpioConfig.ledPinGreen; if(gpioConfig.ledPinBlue == 0xff) - doc[PSTR("i")][PSTR("r")][PSTR("b")] = nullptr; + doc[F("i")][F("r")][F("b")] = nullptr; else - doc[PSTR("i")][PSTR("r")][PSTR("b")] = gpioConfig.ledPinBlue; + doc[F("i")][F("r")][F("b")] = gpioConfig.ledPinBlue; - doc[PSTR("i")][PSTR("r")][PSTR("i")] = gpioConfig.ledRgbInverted; + doc[F("i")][F("r")][F("i")] = gpioConfig.ledRgbInverted; if(gpioConfig.tempSensorPin == 0xff) - doc[PSTR("i")][PSTR("t")][PSTR("d")] = nullptr; + doc[F("i")][F("t")][F("d")] = nullptr; else - doc[PSTR("i")][PSTR("t")][PSTR("d")] = gpioConfig.tempSensorPin; + doc[F("i")][F("t")][F("d")] = gpioConfig.tempSensorPin; if(gpioConfig.tempAnalogSensorPin == 0xff) - doc[PSTR("i")][PSTR("t")][PSTR("a")] = nullptr; + doc[F("i")][F("t")][F("a")] = nullptr; else - doc[PSTR("i")][PSTR("t")][PSTR("a")] = gpioConfig.tempAnalogSensorPin; + doc[F("i")][F("t")][F("a")] = gpioConfig.tempAnalogSensorPin; if(gpioConfig.vccPin == 0xff) - doc[PSTR("i")][PSTR("v")][PSTR("p")] = nullptr; + doc[F("i")][F("v")][F("p")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("p")] = gpioConfig.vccPin; + doc[F("i")][F("v")][F("p")] = gpioConfig.vccPin; if(gpioConfig.vccOffset == 0) - doc[PSTR("i")][PSTR("v")][PSTR("o")] = nullptr; + doc[F("i")][F("v")][F("o")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("o")] = gpioConfig.vccOffset / 100.0; + doc[F("i")][F("v")][F("o")] = gpioConfig.vccOffset / 100.0; if(gpioConfig.vccMultiplier == 0) - doc[PSTR("i")][PSTR("v")][PSTR("m")] = nullptr; + doc[F("i")][F("v")][F("m")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("m")] = gpioConfig.vccMultiplier / 1000.0; + doc[F("i")][F("v")][F("m")] = gpioConfig.vccMultiplier / 1000.0; if(gpioConfig.vccResistorVcc == 0) - doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("v")] = nullptr; + doc[F("i")][F("v")][F("d")][F("v")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("v")] = gpioConfig.vccResistorVcc; + doc[F("i")][F("v")][F("d")][F("v")] = gpioConfig.vccResistorVcc; if(gpioConfig.vccResistorGnd == 0) - doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("g")] = nullptr; + doc[F("i")][F("v")][F("d")][F("g")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("d")][PSTR("g")] = gpioConfig.vccResistorGnd; + doc[F("i")][F("v")][F("d")][F("g")] = gpioConfig.vccResistorGnd; if(gpioConfig.vccBootLimit == 0) - doc[PSTR("i")][PSTR("v")][PSTR("b")] = nullptr; + doc[F("i")][F("v")][F("b")] = nullptr; else - doc[PSTR("i")][PSTR("v")][PSTR("b")] = gpioConfig.vccBootLimit / 10.0; + doc[F("i")][F("v")][F("b")] = gpioConfig.vccBootLimit / 10.0; serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -1314,7 +1314,7 @@ void AmsWebServer::reboot() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /reboot over http...\n"); DynamicJsonDocument doc(128); - doc[PSTR("reboot")] = true; + doc[F("reboot")] = true; serializeJson(doc, buf, BufferSize); server.send(200, MIME_JSON, buf); @@ -1613,11 +1613,11 @@ void AmsWebServer::tariffJson() { EnergyAccountingData data = ea->getData(); DynamicJsonDocument doc(512); - JsonArray thresholds = doc.createNestedArray(PSTR("t")); + JsonArray thresholds = doc.createNestedArray(F("t")); for(uint8_t x = 0;x < 10; x++) { thresholds.add(eac->thresholds[x]); } - JsonArray peaks = doc.createNestedArray(PSTR("p")); + JsonArray peaks = doc.createNestedArray(F("p")); for(uint8_t x = 0;x < min((uint8_t) 5, eac->hours); x++) { JsonObject p = peaks.createNestedObject(); EnergyAccountingPeak peak = ea->getPeak(x+1); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 8c112d51..d738c585 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -766,6 +766,10 @@ void swapWifiMode() { } dnsServer->setErrorReplyCode(DNSReplyCode::NoError); dnsServer->start(53, PSTR("*"), WiFi.softAPIP()); + #if defined(DEBUG_MODE) + Debug.setSerialEnabled(true); + Debug.begin("192.168.4.1", 23, RemoteDebug::VERBOSE); + #endif } else { if(Debug.isActive(RemoteDebug::INFO)) debugI("Swapping to STA mode"); if(dnsServer != NULL) { From c7b8090634b481078af78997851889236da7c32d Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 29 Nov 2022 21:02:23 +0100 Subject: [PATCH 20/66] Some minor changes --- lib/SvelteUi/app/src/lib/SetupPanel.svelte | 4 ---- lib/SvelteUi/app/src/lib/VendorPanel.svelte | 2 +- lib/SvelteUi/src/AmsWebServer.cpp | 3 +-- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte index 087a71f6..dde0ed40 100644 --- a/lib/SvelteUi/app/src/lib/SetupPanel.svelte +++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte @@ -108,10 +108,6 @@
{/if} -
-
- Read more -
diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index 185de3dd..dac12b65 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -29,7 +29,7 @@ s.booting = res.reboot; return s; }); - navigate("/"); + navigate("/setup"); } diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index eb1745c0..0fd3efce 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -1031,8 +1031,7 @@ void AmsWebServer::handleSave() { config->setMeterConfig(*meterConfig); sys.userConfigured = success; - //TODO sys.country - sys.dataCollectionConsent = server.hasArg(F("sf")) && server.arg(F("sf")) == F("true") ? 1 : 2; + sys.dataCollectionConsent = 0; config->setSystemConfig(sys); performRestart = true; From cda3b80b350d01e2e994890fd7a20b38d8a035a2 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 29 Nov 2022 21:24:58 +0100 Subject: [PATCH 21/66] Some changes --- lib/SvelteUi/app/src/App.svelte | 5 ++--- lib/SvelteUi/src/AmsWebServer.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 818248c3..f07b05a0 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -1,6 +1,5 @@
Upload {title}

Select a suitable file and click upload

-
+ uploading=true}>
@@ -16,3 +19,4 @@
+ diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index c6265dd1..bb41bf27 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -2,7 +2,7 @@ import { Link } from "svelte-navigator"; import { sysinfoStore, getGitHubReleases, gitHubReleaseStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; - import { boardtype } from './Helpers.js'; + import { boardtype, hanError, mqttError } from './Helpers.js'; import GitHubLogo from './../assets/github.svg'; import Uptime from "./Uptime.svelte"; import Badge from './Badge.svelte'; @@ -13,7 +13,7 @@ import DownloadIcon from "./DownloadIcon.svelte"; export let data = {} - export let sysinfo = {} + let sysinfo = {} let nextVersion = {}; @@ -28,11 +28,16 @@ } } } + sysinfoStore.subscribe(update => { + sysinfo = update; + if(update.fwconsent === 1) { + getGitHubReleases(); + } + }); gitHubReleaseStore.subscribe(releases => { nextVersion = getNextVersion(sysinfo.version, releases); }); - getGitHubReleases();
@@ -47,13 +52,19 @@ {/if}
Free mem: {data.m ? (data.m/1000).toFixed(1) : '-'}kb
-
+
2.0 ? data.v.toFixed(2)+"V" : "ESP"} color={sysinfo.booting ? 'yellow' : data.em === 1 ? 'green' : data.em === 2 ? 'yellow' : data.em === 3 ? 'red' : 'gray'}/>
-
+ {#if data.he < 0} +
{ 'HAN error: ' + hanError(data.he) }
+ {/if} + {#if data.me < 0} +
{ 'MQTT error: ' + mqttError(data.me) }
+ {/if} +
GitHub repo
diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index 14ce27c6..2cb3ea50 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -91,3 +91,33 @@ export function boardtype(c, b) { return "Generic ESP8266"; } } + +export function hanError(err) { + switch(err) { + case -1: return "Parse error"; + case -2: return "Incomplete data received"; + case -3: return "Payload boundry flag missing"; + case -4: return "Header checksum error"; + case -5: return "Footer checksum error"; + case -9: return "Unknown data received, check meter config"; + case -41: return "Frame length not equal"; + case -51: return "Authentication failed"; + case -52: return "Decryption failed"; + case -53: return "Encryption key invalid"; + } + if(err < 0) return "Unspecified error "+err; + return ""; +} + +export function mqttError(err) { + switch(err) { + case -3: return "Connection failed"; + case -4: return "Network timeout"; + case -10: return "Connection denied"; + case -11: return "Failed to subscribe"; + case -13: return "Connection lost"; + } + + if(err < 0) return "Unspecified error "+err; + return ""; +} \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index 18e0bfcc..5cc83797 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -4,6 +4,7 @@ import { upgrade, getNextVersion } from './UpgradeHelper'; import DownloadIcon from './DownloadIcon.svelte'; import { Link } from 'svelte-navigator'; + import Mask from './Mask.svelte'; export let sysinfo; @@ -45,6 +46,8 @@ } let fileinput; + let files = []; + let uploading = false; getSysinfo(); @@ -125,15 +128,16 @@
{/if}
-
- - {#if fileinput && fileinput.files.length == 0} + uploading=true}> + + {#if files.length == 0} - {:else if fileinput} - {fileinput.files[0].name} + {:else} + {files[0].name} {/if}
+ diff --git a/lib/SvelteUi/app/vite.config.js b/lib/SvelteUi/app/vite.config.js index dbfba4be..af80afb9 100644 --- a/lib/SvelteUi/app/vite.config.js +++ b/lib/SvelteUi/app/vite.config.js @@ -17,18 +17,17 @@ export default defineConfig({ plugins: [svelte()], server: { proxy: { - "/data.json": "http://192.168.233.244", - "/energyprice.json": "http://192.168.233.244", - "/dayplot.json": "http://192.168.233.244", - "/monthplot.json": "http://192.168.233.244", - "/temperature.json": "http://192.168.233.244", - "/sysinfo.json": "http://192.168.233.244", - "/configuration.json": "http://192.168.233.244", - "/tariff.json": "http://192.168.233.244", - "/save": "http://192.168.233.244", - "/reboot": "http://192.168.233.244", - "/firmware": "http://192.168.233.244", - "/upgrade": "http://192.168.233.244" + "/data.json": "http://192.168.233.229", + "/energyprice.json": "http://192.168.233.229", + "/dayplot.json": "http://192.168.233.229", + "/monthplot.json": "http://192.168.233.229", + "/temperature.json": "http://192.168.233.229", + "/sysinfo.json": "http://192.168.233.229", + "/configuration.json": "http://192.168.233.229", + "/tariff.json": "http://192.168.233.229", + "/save": "http://192.168.233.229", + "/reboot": "http://192.168.233.229", + "/upgrade": "http://192.168.233.229" } } }) diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index 4dc01981..6ad94d36 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -83,7 +83,6 @@ private: void monthplotJson(); void energyPriceJson(); void temperatureJson(); - void wifiScanJson(); void tariffJson(); void configurationJson(); diff --git a/lib/SvelteUi/json/conf_debug.json b/lib/SvelteUi/json/conf_debug.json new file mode 100644 index 00000000..e9ec284b --- /dev/null +++ b/lib/SvelteUi/json/conf_debug.json @@ -0,0 +1,5 @@ +"d": { + "s": %s, + "t": %s, + "l": %d +}, diff --git a/lib/SvelteUi/json/conf_general.json b/lib/SvelteUi/json/conf_general.json new file mode 100644 index 00000000..b1333cef --- /dev/null +++ b/lib/SvelteUi/json/conf_general.json @@ -0,0 +1,7 @@ +"g": { + "t": "%s", + "h": "%s", + "s": %d, + "u": "%s", + "p": "%s" +}, \ No newline at end of file diff --git a/lib/SvelteUi/json/conf_gpio.json b/lib/SvelteUi/json/conf_gpio.json new file mode 100644 index 00000000..4cea40be --- /dev/null +++ b/lib/SvelteUi/json/conf_gpio.json @@ -0,0 +1,28 @@ +"i": { + "h": %s, + "a": %s, + "l": { + "p": %s, + "i": %s + }, + "r": { + "r": %s, + "g": %s, + "b": %s, + "i": %s + }, + "t": { + "d": %s, + "a": %s + }, + "v": { + "p": %s, + "o": %.2f, + "m": %.3f, + "d": { + "v": %d, + "g": %d + }, + "b": %.1f + } +} diff --git a/lib/SvelteUi/json/conf_meter.json b/lib/SvelteUi/json/conf_meter.json new file mode 100644 index 00000000..b31d753f --- /dev/null +++ b/lib/SvelteUi/json/conf_meter.json @@ -0,0 +1,20 @@ +"m": { + "b": %d, + "p": %d, + "i": %s, + "d": %d, + "f": %d, + "r": %d, + "e": { + "e": %s, + "k": "%s", + "a": "%s" + }, + "m": { + "e": %s, + "w": %.3f, + "v": %.3f, + "a": %.3f, + "c": %.3f + } +}, \ No newline at end of file diff --git a/lib/SvelteUi/json/conf_mqtt.json b/lib/SvelteUi/json/conf_mqtt.json new file mode 100644 index 00000000..c0030dbb --- /dev/null +++ b/lib/SvelteUi/json/conf_mqtt.json @@ -0,0 +1,15 @@ +"q": { + "h": "%s", + "p": %d, + "u": "%s", + "a": "%s", + "c": "%s", + "b": "%s", + "m": %d, + "s": { + "e": %s, + "c": %s, + "r": %s, + "k": %s + } +}, diff --git a/lib/SvelteUi/json/conf_net.json b/lib/SvelteUi/json/conf_net.json new file mode 100644 index 00000000..4eaa1141 --- /dev/null +++ b/lib/SvelteUi/json/conf_net.json @@ -0,0 +1,11 @@ +"n": { + "m": "%s", + "i": "%s", + "s": "%s", + "g": "%s", + "d1": "%s", + "d2": "%s", + "d": %s, + "n1": "%s", + "h": %s +}, diff --git a/lib/SvelteUi/json/conf_price.json b/lib/SvelteUi/json/conf_price.json new file mode 100644 index 00000000..124b4697 --- /dev/null +++ b/lib/SvelteUi/json/conf_price.json @@ -0,0 +1,7 @@ +"p": { + "e": %s, + "t": "%s", + "r": "%s", + "c": "%s", + "m": %.3f +}, diff --git a/lib/SvelteUi/json/conf_thresholds.json b/lib/SvelteUi/json/conf_thresholds.json new file mode 100644 index 00000000..fd911368 --- /dev/null +++ b/lib/SvelteUi/json/conf_thresholds.json @@ -0,0 +1,15 @@ +"t": { + "t": [ + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d + ], + "h": %d +}, \ No newline at end of file diff --git a/lib/SvelteUi/json/conf_wifi.json b/lib/SvelteUi/json/conf_wifi.json new file mode 100644 index 00000000..9071e9b7 --- /dev/null +++ b/lib/SvelteUi/json/conf_wifi.json @@ -0,0 +1,6 @@ +"w": { + "s": "%s", + "p": "%s", + "w": %.1f, + "z": %d +}, diff --git a/lib/SvelteUi/json/data.json b/lib/SvelteUi/json/data.json index eefea149..173c115f 100644 --- a/lib/SvelteUi/json/data.json +++ b/lib/SvelteUi/json/data.json @@ -40,19 +40,23 @@ "h" : { "u" : %.2f, "c" : %.2f, - "p" : %.2f + "p" : %.2f, + "i" : %.2f }, "d" : { "u" : %.2f, "c" : %.2f, - "p" : %.2f + "p" : %.2f, + "i" : %.2f }, "m" : { "u" : %.2f, "c" : %.2f, - "p" : %.2f + "p" : %.2f, + "i" : %.2f } }, "pr" : "%s", + "he" : %d, "c" : %lu } \ No newline at end of file diff --git a/lib/SvelteUi/json/peak.json b/lib/SvelteUi/json/peak.json new file mode 100644 index 00000000..7f58d14c --- /dev/null +++ b/lib/SvelteUi/json/peak.json @@ -0,0 +1,4 @@ +{ + "d": %d, + "v": %.2f +} \ No newline at end of file diff --git a/lib/SvelteUi/json/sysinfo.json b/lib/SvelteUi/json/sysinfo.json new file mode 100644 index 00000000..7844d7ee --- /dev/null +++ b/lib/SvelteUi/json/sysinfo.json @@ -0,0 +1,25 @@ +{ + "version": "%s", + "chip": "%s", + "chipId": "%s", + "mac": "%s", + "board": %d, + "vndcfg": %s, + "usrcfg": %s, + "fwconsent": %d, + "hostname": "%s", + "booting": %s, + "upgrading": %s, + "net": { + "ip": "%s", + "mask": "%s", + "gw": "%s", + "dns1": "%s", + "dns2": "%s" + }, + "meter": { + "mfg": %d, + "model": "%s", + "id": "%s" + } +} \ No newline at end of file diff --git a/lib/SvelteUi/json/tariff.json b/lib/SvelteUi/json/tariff.json new file mode 100644 index 00000000..e832ff11 --- /dev/null +++ b/lib/SvelteUi/json/tariff.json @@ -0,0 +1,17 @@ +{ + "t": [ + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d, + %d + ], + "p": [ %s ], + "c": %d, + "m": %.2f +} \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index a691c74a..003423cc 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -3,8 +3,6 @@ #include "base64.h" #include "hexutils.h" -#include - #include "html/index_html.h" #include "html/index_css.h" #include "html/index_js.h" @@ -15,6 +13,18 @@ #include "html/energyprice_json.h" #include "html/tempsensor_json.h" #include "html/response_json.h" +#include "html/sysinfo_json.h" +#include "html/tariff_json.h" +#include "html/peak_json.h" +#include "html/conf_general_json.h" +#include "html/conf_meter_json.h" +#include "html/conf_wifi_json.h" +#include "html/conf_net_json.h" +#include "html/conf_mqtt_json.h" +#include "html/conf_price_json.h" +#include "html/conf_thresholds_json.h" +#include "html/conf_debug_json.h" +#include "html/conf_gpio_json.h" #include "version.h" @@ -60,8 +70,6 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/temperature.json"), HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this)); server.on(F("/tariff.json"), HTTP_GET, std::bind(&AmsWebServer::tariffJson, this)); - server.on(F("/wifiscan.json"), HTTP_GET, std::bind(&AmsWebServer::wifiScanJson, this)); - server.on(F("/configuration.json"), HTTP_GET, std::bind(&AmsWebServer::configurationJson, this)); server.on(F("/save"), HTTP_POST, std::bind(&AmsWebServer::handleSave, this)); server.on(F("/reboot"), HTTP_POST, std::bind(&AmsWebServer::reboot, this)); @@ -169,17 +177,8 @@ void AmsWebServer::faviconIco() { void AmsWebServer::sysinfoJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /sysinfo.json over http...\n"); - DynamicJsonDocument doc(1024); - doc[F("version")] = VERSION; - #if defined(CONFIG_IDF_TARGET_ESP32S2) - doc[F("chip")] = "esp32s2"; - #elif defined(CONFIG_IDF_TARGET_ESP32C3) - doc[F("chip")] = "esp32c3"; - #elif defined(ESP32) - doc[F("chip")] = "esp32"; - #elif defined(ESP8266) - doc[F("chip")] = "esp8266"; - #endif + SystemConfig sys; + config->getSystemConfig(sys); uint32_t chipId; #if defined(ESP32) @@ -188,39 +187,54 @@ void AmsWebServer::sysinfoJson() { chipId = ESP.getChipId(); #endif String chipIdStr = String(chipId, HEX); - doc[F("chipId")] = chipIdStr; - doc[F("mac")] = WiFi.macAddress(); - - SystemConfig sys; - config->getSystemConfig(sys); - doc[F("board")] = sys.boardType; - doc[F("vndcfg")] = sys.vendorConfigured; - doc[F("usrcfg")] = sys.userConfigured; - doc[F("fwconsent")] = sys.dataCollectionConsent; - doc[F("country")] = sys.country; + String hostname; if(sys.userConfigured) { WiFiConfig wifiConfig; config->getWiFiConfig(wifiConfig); - doc[F("hostname")] = wifiConfig.hostname; + hostname = String(wifiConfig.hostname); } else { - doc[F("hostname")] = "ams-"+chipIdStr; + hostname = "ams-"+chipIdStr; } - doc[F("booting")] = performRestart; - doc[F("upgrading")] = rebootForUpgrade; + IPAddress dns1 = WiFi.dnsIP(0); + IPAddress dns2 = WiFi.dnsIP(1); - doc[F("net")][F("ip")] = WiFi.localIP().toString(); - doc[F("net")][F("mask")] = WiFi.subnetMask().toString(); - doc[F("net")][F("gw")] = WiFi.gatewayIP().toString(); - doc[F("net")][F("dns1")] = WiFi.dnsIP(0).toString(); - doc[F("net")][F("dns2")] = WiFi.dnsIP(1).toString(); + snprintf_P(buf, BufferSize, SYSINFO_JSON, + VERSION, + #if defined(CONFIG_IDF_TARGET_ESP32S2) + "esp32s2", + #elif defined(CONFIG_IDF_TARGET_ESP32C3) + "esp32c3", + #elif defined(ESP32) + "esp32", + #elif defined(ESP8266) + "esp8266", + #endif + chipIdStr.c_str(), + WiFi.macAddress().c_str(), + sys.boardType, + sys.vendorConfigured ? "true" : "false", + sys.userConfigured ? "true" : "false", + sys.dataCollectionConsent, + hostname.c_str(), + performRestart ? "true" : "false", + rebootForUpgrade ? "true" : "false", + WiFi.localIP().toString().c_str(), + WiFi.subnetMask().toString().c_str(), + WiFi.gatewayIP().toString().c_str(), + dns1.isSet() ? dns1.toString().c_str() : "", + dns2.isSet() ? dns2.toString().c_str() : "", + meterState->getMeterType(), + meterState->getMeterModel().c_str(), + meterState->getMeterId().c_str() + ); - doc[F("meter")][F("mfg")] = meterState->getMeterType(); - doc[F("meter")][F("model")] = meterState->getMeterModel(); - doc[F("meter")][F("id")] = meterState->getMeterId(); + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - serializeJson(doc, buf, BufferSize); + server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); server.handleClient(); @@ -276,7 +290,9 @@ void AmsWebServer::dataJson() { uint8_t hanStatus; - if(meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) { + if(meterState->getLastError() < 0) { + hanStatus = 3; + } else if((meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) && now < 15000) { hanStatus = 0; } else if(now - meterState->getLastUpdateMillis() < 15000) { hanStatus = 1; @@ -313,7 +329,7 @@ void AmsWebServer::dataJson() { String peaks = ""; for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) { if(!peaks.isEmpty()) peaks += ","; - peaks += String(ea->getPeak(i).value); + peaks += String(ea->getPeak(i).value / 100.0); } snprintf_P(buf, BufferSize, DATA_JSON, @@ -357,13 +373,17 @@ void AmsWebServer::dataJson() { ea->getUseThisHour(), ea->getCostThisHour(), ea->getProducedThisHour(), + ea->getIncomeThisHour(), ea->getUseToday(), ea->getCostToday(), ea->getProducedToday(), + ea->getIncomeToday(), ea->getUseThisMonth(), ea->getCostThisMonth(), ea->getProducedThisMonth(), + ea->getIncomeThisMonth(), eapi == NULL ? "" : eapi->getArea(), + meterState->getLastError(), (uint32_t) time(nullptr) ); @@ -665,28 +685,13 @@ void AmsWebServer::indexJs() { void AmsWebServer::configurationJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /configuration.json over http...\n"); - server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); - server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); - server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - if(!checkSecurity(1)) return; - DynamicJsonDocument doc(2048); - doc[F("version")] = VERSION; - NtpConfig ntpConfig; config->getNtpConfig(ntpConfig); WiFiConfig wifiConfig; config->getWiFiConfig(wifiConfig); - WebConfig webConfig; - config->getWebConfig(webConfig); - - doc[F("g")][F("t")] = ntpConfig.timezone; - doc[F("g")][F("h")] = wifiConfig.hostname; - doc[F("g")][F("s")] = webConfig.security; - doc[F("g")][F("u")] = webConfig.username; - doc[F("g")][F("p")] = strlen(webConfig.password) > 0 ? "***" : ""; bool encen = false; for(uint8_t i = 0; i < 16; i++) { @@ -695,166 +700,143 @@ void AmsWebServer::configurationJson() { } } - config->getMeterConfig(*meterConfig); - doc[F("m")][F("b")] = meterConfig->baud; - doc[F("m")][F("p")] = meterConfig->parity; - doc[F("m")][F("i")] = meterConfig->invert; - doc[F("m")][F("d")] = meterConfig->distributionSystem; - doc[F("m")][F("f")] = meterConfig->mainFuse; - doc[F("m")][F("r")] = meterConfig->productionCapacity; - doc[F("m")][F("e")][F("e")] = encen; - doc[F("m")][F("e")][F("k")] = toHex(meterConfig->encryptionKey, 16); - doc[F("m")][F("e")][F("a")] = toHex(meterConfig->authenticationKey, 16); - doc[F("m")][F("m")][F("e")] = meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1; - doc[F("m")][F("m")][F("w")] = meterConfig->wattageMultiplier / 1000.0; - doc[F("m")][F("m")][F("v")] = meterConfig->voltageMultiplier / 1000.0; - doc[F("m")][F("m")][F("a")] = meterConfig->amperageMultiplier / 1000.0; - doc[F("m")][F("m")][F("c")] = meterConfig->accumulatedMultiplier / 1000.0; - - EnergyAccountingConfig eac; - config->getEnergyAccountingConfig(eac); - doc[F("t")][F("t")][0] = eac.thresholds[0]; - doc[F("t")][F("t")][1] = eac.thresholds[1]; - doc[F("t")][F("t")][2] = eac.thresholds[2]; - doc[F("t")][F("t")][3] = eac.thresholds[3]; - doc[F("t")][F("t")][4] = eac.thresholds[4]; - doc[F("t")][F("t")][5] = eac.thresholds[5]; - doc[F("t")][F("t")][6] = eac.thresholds[6]; - doc[F("t")][F("t")][7] = eac.thresholds[7]; - doc[F("t")][F("t")][8] = eac.thresholds[8]; - doc[F("t")][F("t")][9] = eac.thresholds[9]; - doc[F("t")][F("h")] = eac.hours; - - doc[F("w")][F("s")] = wifiConfig.ssid; - doc[F("w")][F("p")] = strlen(wifiConfig.psk) > 0 ? "***" : ""; - doc[F("w")][F("w")] = wifiConfig.power / 10.0; - doc[F("w")][F("z")] = wifiConfig.sleep; - - doc[F("n")][F("m")] = strlen(wifiConfig.ip) > 0 ? "static" : "dhcp"; - doc[F("n")][F("i")] = wifiConfig.ip; - doc[F("n")][F("s")] = wifiConfig.subnet; - doc[F("n")][F("g")] = wifiConfig.gateway; - doc[F("n")][F("d1")] = wifiConfig.dns1; - doc[F("n")][F("d2")] = wifiConfig.dns2; - doc[F("n")][F("d")] = wifiConfig.mdns; - doc[F("n")][F("n1")] = ntpConfig.server; - doc[F("n")][F("h")] = ntpConfig.dhcp; - + EnergyAccountingConfig* eac = ea->getConfig(); MqttConfig mqttConfig; config->getMqttConfig(mqttConfig); - doc[F("q")][F("h")] = mqttConfig.host; - doc[F("q")][F("p")] = mqttConfig.port; - doc[F("q")][F("u")] = mqttConfig.username; - doc[F("q")][F("a")] = strlen(mqttConfig.password) > 0 ? "***" : ""; - doc[F("q")][F("c")] = mqttConfig.clientId; - doc[F("q")][F("b")] = mqttConfig.publishTopic; - doc[F("q")][F("m")] = mqttConfig.payloadFormat; - doc[F("q")][F("s")][F("e")] = mqttConfig.ssl; - - if(LittleFS.begin()) { - doc[F("q")][F("s")][F("c")] = LittleFS.exists(FILE_MQTT_CA); - doc[F("q")][F("s")][F("r")] = LittleFS.exists(FILE_MQTT_CERT); - doc[F("q")][F("s")][F("k")] = LittleFS.exists(FILE_MQTT_KEY); - LittleFS.end(); - } else { - doc[F("q")][F("s")][F("c")] = false; - doc[F("q")][F("s")][F("r")] = false; - doc[F("q")][F("s")][F("k")] = false; - } EntsoeConfig entsoe; config->getEntsoeConfig(entsoe); - doc[F("p")][F("e")] = strlen(entsoe.token) > 0; - doc[F("p")][F("t")] = entsoe.token; - doc[F("p")][F("r")] = entsoe.area; - doc[F("p")][F("c")] = entsoe.currency; - doc[F("p")][F("m")] = entsoe.multiplier / 1000.0; - DebugConfig debugConfig; config->getDebugConfig(debugConfig); - doc[F("d")][F("s")] = debugConfig.serial; - doc[F("d")][F("t")] = debugConfig.telnet; - doc[F("d")][F("l")] = debugConfig.level; - GpioConfig gpioConfig; - config->getGpioConfig(gpioConfig); - if(gpioConfig.hanPin == 0xff) - doc[F("i")][F("h")] = nullptr; - else - doc[F("i")][F("h")] = gpioConfig.hanPin; - - if(gpioConfig.apPin == 0xff) - doc[F("i")][F("a")] = nullptr; - else - doc[F("i")][F("a")] = gpioConfig.apPin; - - if(gpioConfig.ledPin == 0xff) - doc[F("i")][F("l")][F("p")] = nullptr; - else - doc[F("i")][F("l")][F("p")] = gpioConfig.ledPin; - - doc[F("i")][F("l")][F("i")] = gpioConfig.ledInverted; - - if(gpioConfig.ledPinRed == 0xff) - doc[F("i")][F("r")][F("r")] = nullptr; - else - doc[F("i")][F("r")][F("r")] = gpioConfig.ledPinRed; + bool qsc = false; + bool qsr = false; + bool qsk = false; - if(gpioConfig.ledPinGreen == 0xff) - doc[F("i")][F("r")][F("g")] = nullptr; - else - doc[F("i")][F("r")][F("g")] = gpioConfig.ledPinGreen; + if(LittleFS.begin()) { + qsc = LittleFS.exists(FILE_MQTT_CA); + qsr = LittleFS.exists(FILE_MQTT_CERT); + qsk = LittleFS.exists(FILE_MQTT_KEY); + LittleFS.end(); + } - if(gpioConfig.ledPinBlue == 0xff) - doc[F("i")][F("r")][F("b")] = nullptr; - else - doc[F("i")][F("r")][F("b")] = gpioConfig.ledPinBlue; + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - doc[F("i")][F("r")][F("i")] = gpioConfig.ledRgbInverted; + server.setContentLength(CONTENT_LENGTH_UNKNOWN); + server.send_P(200, MIME_JSON, PSTR("{\"version\":\"")); + server.sendContent_P(VERSION); + server.sendContent_P(PSTR("\",")); + snprintf_P(buf, BufferSize, CONF_GENERAL_JSON, + ntpConfig.timezone, + wifiConfig.hostname, + webConfig.security, + webConfig.username, + strlen(webConfig.password) > 0 ? "***" : "" + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_METER_JSON, + meterConfig->baud, + meterConfig->parity, + meterConfig->invert ? "true" : "false", + meterConfig->distributionSystem, + meterConfig->mainFuse, + meterConfig->productionCapacity, + encen ? "true" : "false", + toHex(meterConfig->encryptionKey, 16).c_str(), + toHex(meterConfig->authenticationKey, 16).c_str(), + meterConfig->wattageMultiplier > 1 || meterConfig->voltageMultiplier > 1 || meterConfig->amperageMultiplier > 1 || meterConfig->accumulatedMultiplier > 1 ? "true" : "false", + meterConfig->wattageMultiplier / 1000.0, + meterConfig->voltageMultiplier / 1000.0, + meterConfig->amperageMultiplier / 1000.0, + meterConfig->accumulatedMultiplier / 1000.0 + ); + server.sendContent(buf); - if(gpioConfig.tempSensorPin == 0xff) - doc[F("i")][F("t")][F("d")] = nullptr; - else - doc[F("i")][F("t")][F("d")] = gpioConfig.tempSensorPin; - - if(gpioConfig.tempAnalogSensorPin == 0xff) - doc[F("i")][F("t")][F("a")] = nullptr; - else - doc[F("i")][F("t")][F("a")] = gpioConfig.tempAnalogSensorPin; - - if(gpioConfig.vccPin == 0xff) - doc[F("i")][F("v")][F("p")] = nullptr; - else - doc[F("i")][F("v")][F("p")] = gpioConfig.vccPin; - - if(gpioConfig.vccOffset == 0) - doc[F("i")][F("v")][F("o")] = nullptr; - else - doc[F("i")][F("v")][F("o")] = gpioConfig.vccOffset / 100.0; - - if(gpioConfig.vccMultiplier == 0) - doc[F("i")][F("v")][F("m")] = nullptr; - else - doc[F("i")][F("v")][F("m")] = gpioConfig.vccMultiplier / 1000.0; - - if(gpioConfig.vccResistorVcc == 0) - doc[F("i")][F("v")][F("d")][F("v")] = nullptr; - else - doc[F("i")][F("v")][F("d")][F("v")] = gpioConfig.vccResistorVcc; - - if(gpioConfig.vccResistorGnd == 0) - doc[F("i")][F("v")][F("d")][F("g")] = nullptr; - else - doc[F("i")][F("v")][F("d")][F("g")] = gpioConfig.vccResistorGnd; - - if(gpioConfig.vccBootLimit == 0) - doc[F("i")][F("v")][F("b")] = nullptr; - else - doc[F("i")][F("v")][F("b")] = gpioConfig.vccBootLimit / 10.0; - - serializeJson(doc, buf, BufferSize); - server.send(200, MIME_JSON, buf); + snprintf_P(buf, BufferSize, CONF_THRESHOLDS_JSON, + eac->thresholds[0], + eac->thresholds[1], + eac->thresholds[2], + eac->thresholds[3], + eac->thresholds[4], + eac->thresholds[5], + eac->thresholds[6], + eac->thresholds[7], + eac->thresholds[8], + eac->thresholds[9], + eac->hours + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_WIFI_JSON, + wifiConfig.ssid, + strlen(wifiConfig.psk) > 0 ? "***" : "", + wifiConfig.power / 10.0, + wifiConfig.sleep + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_NET_JSON, + strlen(wifiConfig.ip) > 0 ? "static" : "dhcp", + wifiConfig.ip, + wifiConfig.subnet, + wifiConfig.gateway, + wifiConfig.dns1, + wifiConfig.dns2, + wifiConfig.mdns ? "true" : "false", + ntpConfig.server, + ntpConfig.dhcp ? "true" : "false" + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_MQTT_JSON, + mqttConfig.host, + mqttConfig.port, + mqttConfig.username, + strlen(mqttConfig.password) > 0 ? "***" : "", + mqttConfig.clientId, + mqttConfig.publishTopic, + mqttConfig.payloadFormat, + mqttConfig.ssl ? "true" : "false", + qsc ? "true" : "false", + qsr ? "true" : "false", + qsk ? "true" : "false" + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_PRICE_JSON, + strlen(entsoe.token) > 0 ? "true" : "false", + entsoe.token, + entsoe.area, + entsoe.currency, + entsoe.multiplier / 1000.0 + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_DEBUG_JSON, + debugConfig.serial ? "true" : "false", + debugConfig.telnet ? "true" : "false", + debugConfig.level + ); + server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_GPIO_JSON, + gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(), + gpioConfig->apPin == 0xff ? "null" : String(gpioConfig->apPin, 10).c_str(), + gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(), + gpioConfig->ledInverted ? "true" : "false", + gpioConfig->ledPinRed == 0xff ? "null" : String(gpioConfig->ledPinRed, 10).c_str(), + gpioConfig->ledPinGreen == 0xff ? "null" : String(gpioConfig->ledPinGreen, 10).c_str(), + gpioConfig->ledPinBlue == 0xff ? "null" : String(gpioConfig->ledPinBlue, 10).c_str(), + gpioConfig->ledRgbInverted ? "true" : "false", + gpioConfig->tempSensorPin == 0xff ? "null" : String(gpioConfig->tempSensorPin, 10).c_str(), + gpioConfig->tempAnalogSensorPin == 0xff ? "null" : String(gpioConfig->tempAnalogSensorPin, 10).c_str(), + gpioConfig->vccPin == 0xff ? "null" : String(gpioConfig->vccPin, 10).c_str(), + gpioConfig->vccOffset / 100.0, + gpioConfig->vccMultiplier / 1000.0, + gpioConfig->vccResistorVcc, + gpioConfig->vccResistorGnd, + gpioConfig->vccBootLimit / 10.0 + ); + server.sendContent(buf); + server.sendContent("}"); } + void AmsWebServer::handleSave() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Handling save method from http")); if(!checkSecurity(1)) @@ -1300,23 +1282,10 @@ void AmsWebServer::handleSave() { } } -void AmsWebServer::wifiScanJson() { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /wifiscan.json over http...\n"); - - DynamicJsonDocument doc(512); - - serializeJson(doc, buf, BufferSize); - server.send(200, MIME_JSON, buf); -} - void AmsWebServer::reboot() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /reboot over http...\n"); - DynamicJsonDocument doc(128); - doc[F("reboot")] = true; - - serializeJson(doc, buf, BufferSize); - server.send(200, MIME_JSON, buf); + server.send(200, MIME_JSON, "{\"reboot\":true}"); server.handleClient(); delay(250); @@ -1601,32 +1570,43 @@ void AmsWebServer::mqttKeyUpload() { void AmsWebServer::tariffJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /tariff.json over http...\n"); - server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); - server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); - server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - if(!checkSecurity(1)) return; EnergyAccountingConfig* eac = ea->getConfig(); - EnergyAccountingData data = ea->getData(); - DynamicJsonDocument doc(512); - JsonArray thresholds = doc.createNestedArray(F("t")); - for(uint8_t x = 0;x < 10; x++) { - thresholds.add(eac->thresholds[x]); - } - JsonArray peaks = doc.createNestedArray(F("p")); + String peaks; for(uint8_t x = 0;x < min((uint8_t) 5, eac->hours); x++) { - JsonObject p = peaks.createNestedObject(); EnergyAccountingPeak peak = ea->getPeak(x+1); - p["d"] = peak.day; - p["v"] = peak.value / 100.0; + int len = snprintf_P(buf, BufferSize, PEAK_JSON, + peak.day, + peak.value / 100.0 + ); + buf[len] = '\0'; + if(!peaks.isEmpty()) peaks += ","; + peaks += String(buf); } - doc["c"] = ea->getCurrentThreshold(); - doc["m"] = ea->getMonthMax(); - serializeJson(doc, buf, BufferSize); + snprintf_P(buf, BufferSize, TARIFF_JSON, + eac->thresholds[0], + eac->thresholds[1], + eac->thresholds[2], + eac->thresholds[3], + eac->thresholds[4], + eac->thresholds[5], + eac->thresholds[6], + eac->thresholds[7], + eac->thresholds[8], + eac->thresholds[9], + peaks.c_str(), + ea->getCurrentThreshold(), + ea->getMonthMax() + ); + + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); + + server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); - } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index c11e0b3e..9f61cd4f 100755 --- a/platformio.ini +++ b/platformio.ini @@ -2,7 +2,7 @@ extra_configs = platformio-user.ini [common] -lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, ArduinoJson, SvelteUi +lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi lib_ignore = OneWire extra_scripts = pre:scripts/addversion.py diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index d738c585..0a3e9480 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -826,6 +826,7 @@ bool readHanPort() { if(pos == DATA_PARSE_INCOMPLETE) { return false; } else if(pos == DATA_PARSE_UNKNOWN_DATA) { + meterState.setLastError(pos); debugV("Unknown data payload:"); len = len + hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len); debugPrint(hanBuffer, 0, len); @@ -837,6 +838,7 @@ bool readHanPort() { len = 0; return false; } else if(pos < 0) { + meterState.setLastError(pos); printHanReadError(pos); len += hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len); if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { @@ -852,6 +854,7 @@ bool readHanPort() { for(int i = pos+ctx.length; i 0.0) { - ead.peaks[0] = { 1, (uint16_t) (val*100) }; - } - } else if(i == 3) { - double val = String(pch).toDouble(); - ead.costYesterday = val * 10; - } else if(i == 4) { - double val = String(pch).toDouble(); - ead.costThisMonth = val; - } else if(i == 5) { - double val = String(pch).toDouble(); - ead.costLastMonth = val; - } else if(i >= 6 && i < 18) { - uint8_t hour = i-6; - if(hour%2 == 0) { + if(ead.version < 5) { + if(i == 0) { long val = String(pch).toInt(); - ead.peaks[hour/2].day = val; - } else { + ead.version = val; + } else if(i == 1) { + long val = String(pch).toInt(); + ead.month = val; + } else if(i == 2) { double val = String(pch).toDouble(); - ead.peaks[hour/2].value = val * 100; + if(val > 0.0) { + ead.peaks[0] = { 1, (uint16_t) (val*100) }; + } + } else if(i == 3) { + double val = String(pch).toDouble(); + ead.costYesterday = val * 10; + } else if(i == 4) { + double val = String(pch).toDouble(); + ead.costThisMonth = val; + } else if(i == 5) { + double val = String(pch).toDouble(); + ead.costLastMonth = val; + } else if(i >= 6 && i < 18) { + uint8_t hour = i-6; + if(hour%2 == 0) { + long val = String(pch).toInt(); + ead.peaks[hour/2].day = val; + } else { + double val = String(pch).toDouble(); + ead.peaks[hour/2].value = val * 100; + } + } + } else { + if(i == 1) { + long val = String(pch).toInt(); + ead.month = val; + } else if(i == 2) { + double val = String(pch).toDouble(); + if(val > 0.0) { + ead.peaks[0] = { 1, (uint16_t) (val*100) }; + } + } else if(i == 3) { + double val = String(pch).toDouble(); + ead.costYesterday = val * 10; + } else if(i == 4) { + double val = String(pch).toDouble(); + ead.costThisMonth = val; + } else if(i == 5) { + double val = String(pch).toDouble(); + ead.costLastMonth = val; + } else if(i == 6) { + double val = String(pch).toDouble(); + ead.incomeYesterday= val * 10; + } else if(i == 7) { + double val = String(pch).toDouble(); + ead.incomeThisMonth = val; + } else if(i == 8) { + double val = String(pch).toDouble(); + ead.incomeLastMonth = val; + } else if(i >= 9 && i < 21) { + uint8_t hour = i-9; + if(hour%2 == 0) { + long val = String(pch).toInt(); + ead.peaks[hour/2].day = val; + } else { + double val = String(pch).toDouble(); + ead.peaks[hour/2].value = val * 100; + } } } pch = strtok (NULL, " "); From 0927cab8e2902803ef384bbdcc06068bc01cb19b Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 2 Dec 2022 19:24:53 +0100 Subject: [PATCH 23/66] Some changes for fetching prices from amshub --- lib/AmsConfiguration/include/AmsConfiguration.h | 1 + lib/AmsConfiguration/src/AmsConfiguration.cpp | 5 +++++ .../entsoe => lib/EntsoePriceApi/include}/PricesContainer.h | 0 lib/EntsoePriceApi/src/EntsoeApi.cpp | 2 ++ lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte | 6 ++---- lib/SvelteUi/src/AmsWebServer.cpp | 3 ++- 6 files changed, 12 insertions(+), 5 deletions(-) rename {src/entsoe => lib/EntsoePriceApi/include}/PricesContainer.h (100%) diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index 4919104b..c124139f 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -190,6 +190,7 @@ struct EntsoeConfig { char area[17]; char currency[4]; uint32_t multiplier; + bool enabled; }; // 62 struct EnergyAccountingConfig { diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 052f87a5..60216c3b 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -868,6 +868,11 @@ bool AmsConfiguration::relocateConfig96() { strcpy(ntp.server, ntp96.server); EEPROM.put(CONFIG_NTP_START, ntp); + EntsoeConfig entsoe; + EEPROM.get(CONFIG_ENTSOE_START, entsoe); + entsoe.enabled = strlen(entsoe.token) > 0; + EEPROM.put(CONFIG_ENTSOE_START, entsoe); + EEPROM.put(EEPROM_CONFIG_ADDRESS, 100); bool ret = EEPROM.commit(); EEPROM.end(); diff --git a/src/entsoe/PricesContainer.h b/lib/EntsoePriceApi/include/PricesContainer.h similarity index 100% rename from src/entsoe/PricesContainer.h rename to lib/EntsoePriceApi/include/PricesContainer.h diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 3f6cc60b..d338edb7 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -131,6 +131,8 @@ bool EntsoeApi::loop() { return false; } #endif + if(!config->enabled) + return false; if(strlen(config->area) == 0) return false; if(strlen(config->currency) == 0) diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 0a531001..fd921ec0 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -192,14 +192,12 @@
- {#if sysinfo.chip != 'esp8266'}
- - {#if configuration.p.e} + + {#if configuration.p.e && sysinfo.chip != 'esp8266'}
{/if}
- {/if}
Security
Enable price fetch from remote server + {#if configuration.p.e && sysinfo.chip != 'esp8266'} -
+
{/if}
@@ -443,7 +443,7 @@ - +
diff --git a/lib/SvelteUi/app/src/lib/Dashboard.svelte b/lib/SvelteUi/app/src/lib/Dashboard.svelte index 254f8ac4..bff56aff 100644 --- a/lib/SvelteUi/app/src/lib/Dashboard.svelte +++ b/lib/SvelteUi/app/src/lib/Dashboard.svelte @@ -68,12 +68,12 @@
- {#if data && data.ea} + {#if data && data.pr && (data.pr.startsWith("10YNO") || data.pr == '10Y1001A1001A48H')}
- +
{/if} - {#if prices.currency} + {#if (typeof data.p == "number") && !Number.isNaN(data.p)}
diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index 6ad94d36..f184d57d 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -38,6 +38,7 @@ public: void setTimezone(Timezone* tz); void setMqttEnabled(bool); void setEntsoeApi(EntsoeApi* eapi); + void setPriceRegion(String); private: RemoteDebug* debugger; @@ -59,6 +60,7 @@ private: bool performRestart = false; bool performUpgrade = false; bool rebootForUpgrade = false; + String priceRegion; static const uint16_t BufferSize = 2048; char* buf; @@ -89,6 +91,7 @@ private: void handleSave(); void reboot(); void upgrade(); + void firmwareHtml(); void firmwarePost(); void firmwareUpload(); void isAliveCheck(); diff --git a/lib/SvelteUi/json/firmware.html b/lib/SvelteUi/json/firmware.html new file mode 100644 index 00000000..b4e32ece --- /dev/null +++ b/lib/SvelteUi/json/firmware.html @@ -0,0 +1,6 @@ + +
+ + +
+ \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 82ae67f4..5e5a90f6 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -25,6 +25,7 @@ #include "html/conf_thresholds_json.h" #include "html/conf_debug_json.h" #include "html/conf_gpio_json.h" +#include "html/firmware_html.h" #include "version.h" @@ -74,6 +75,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/save"), HTTP_POST, std::bind(&AmsWebServer::handleSave, this)); server.on(F("/reboot"), HTTP_POST, std::bind(&AmsWebServer::reboot, this)); server.on(F("/upgrade"), HTTP_POST, std::bind(&AmsWebServer::upgrade, this)); + server.on(F("/firmware"), HTTP_GET, std::bind(&AmsWebServer::firmwareHtml, this)); server.on(F("/firmware"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::firmwareUpload, this)); server.on(F("/is-alive"), HTTP_GET, std::bind(&AmsWebServer::isAliveCheck, this)); @@ -223,8 +225,13 @@ void AmsWebServer::sysinfoJson() { WiFi.localIP().toString().c_str(), WiFi.subnetMask().toString().c_str(), WiFi.gatewayIP().toString().c_str(), + #if defined(ESP8266) dns1.isSet() ? dns1.toString().c_str() : "", dns2.isSet() ? dns2.toString().c_str() : "", + #else + dns1.toString().c_str(), + dns2.toString().c_str(), + #endif meterState->getMeterType(), meterState->getMeterModel().c_str(), meterState->getMeterId().c_str() @@ -323,7 +330,7 @@ void AmsWebServer::dataJson() { } float price = ENTSOE_NO_VALUE; - if(eapi != NULL && strlen(eapi->getToken()) > 0) + if(eapi != NULL) price = eapi->getValueForHour(0); String peaks = ""; @@ -382,7 +389,7 @@ void AmsWebServer::dataJson() { ea->getCostThisMonth(), ea->getProducedThisMonth(), ea->getIncomeThisMonth(), - eapi == NULL ? "" : eapi->getArea(), + priceRegion.c_str(), meterState->getLastError(), (uint32_t) time(nullptr) ); @@ -1219,10 +1226,13 @@ void AmsWebServer::handleSave() { if(server.hasArg(F("p")) && server.arg(F("p")) == F("true")) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received price API config")); + + priceRegion = server.arg(F("pr")); + EntsoeConfig entsoe; entsoe.enabled = server.hasArg(F("pe")) && server.arg(F("pe")) == F("true"); strcpy(entsoe.token, server.arg(F("pt")).c_str()); - strcpy(entsoe.area, server.arg(F("pr")).c_str()); + strcpy(entsoe.area, priceRegion.c_str()); strcpy(entsoe.currency, server.arg(F("pc")).c_str()); entsoe.multiplier = server.arg(F("pm")).toFloat() * 1000; config->setEntsoeConfig(entsoe); @@ -1368,6 +1378,19 @@ void AmsWebServer::upgrade() { } } } +void AmsWebServer::firmwareHtml() { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Serving /firmware.html over http...")); + + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); + + if(!checkSecurity(1)) + return; + + server.setContentLength(FIRMWARE_HTML_LEN); + server.send_P(200, MIME_HTML, FIRMWARE_HTML); +} void AmsWebServer::firmwarePost() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Handling firmware post...")); @@ -1610,4 +1633,8 @@ void AmsWebServer::tariffJson() { server.setContentLength(strlen(buf)); server.send(200, MIME_JSON, buf); +} + +void AmsWebServer::setPriceRegion(String priceRegion) { + this->priceRegion = priceRegion; } \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 83339e4d..017622fe 100755 --- a/platformio.ini +++ b/platformio.ini @@ -2,7 +2,7 @@ extra_configs = platformio-user.ini [common] -lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi +lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi lib_ignore = OneWire extra_scripts = pre:scripts/addversion.py @@ -25,8 +25,6 @@ lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP826 lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} -# Sticking to v2.0.3 because of #298 - [env:esp32] platform = https://github.com/tasmota/platform-espressif32/releases/download/v2.0.5.3/platform-espressif32-2.0.5.3.zip framework = arduino diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 94901139..c72e1a56 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -71,7 +71,7 @@ ADC_MODE(ADC_VCC); #include "IEC6205675.h" #include "LNG.h" -#include "ams/DataParsers.h" +#include "DataParsers.h" #include "Timezones.h" uint8_t commonBuffer[BUF_SIZE_COMMON]; @@ -201,11 +201,12 @@ void setup() { hw.ledBlink(LED_BLUE, 1); EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) { + if(config.getEntsoeConfig(entsoe) && entsoe.enabled && strlen(entsoe.area) > 0) { eapi = new EntsoeApi(&Debug); eapi->setup(entsoe); ws.setEntsoeApi(eapi); } + ws.setPriceRegion(entsoe.area); bool shared = false; config.getMeterConfig(meterConfig); Serial.flush(); @@ -520,7 +521,7 @@ void loop() { if(config.isEntsoeChanged()) { EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe) && strlen(entsoe.area) > 0) { + if(config.getEntsoeConfig(entsoe) && entsoe.enabled && strlen(entsoe.area) > 0) { if(eapi == NULL) { eapi = new EntsoeApi(&Debug); ea.setEapi(eapi); @@ -532,6 +533,7 @@ void loop() { eapi = NULL; ws.setEntsoeApi(NULL); } + ws.setPriceRegion(entsoe.area); config.ackEntsoeChange(); } } catch(const std::exception& e) { diff --git a/src/IEC6205621.cpp b/src/IEC6205621.cpp index d7146600..6343801f 100644 --- a/src/IEC6205621.cpp +++ b/src/IEC6205621.cpp @@ -1,5 +1,5 @@ #include "IEC6205621.h" -#include "ams/crc.h" +#include "crc.h" IEC6205621::IEC6205621(const char* p) { if(strlen(p) < 16) diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index 6b4dd3ba..b3f32c22 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -1,7 +1,7 @@ #include "IEC6205675.h" #include "lwip/def.h" #include "Timezone.h" -#include "ams/ntohll.h" +#include "ntohll.h" IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx) { double val; diff --git a/src/IEC6205675.h b/src/IEC6205675.h index 75cf0134..9b5f9093 100644 --- a/src/IEC6205675.h +++ b/src/IEC6205675.h @@ -3,8 +3,8 @@ #include "AmsData.h" #include "AmsConfiguration.h" -#include "ams/DataParser.h" -#include "ams/Cosem.h" +#include "DataParser.h" +#include "Cosem.h" #define NOVALUE 0xFFFFFFFF diff --git a/src/LNG.cpp b/src/LNG.cpp index cde094e7..e7d818d3 100644 --- a/src/LNG.cpp +++ b/src/LNG.cpp @@ -1,6 +1,6 @@ #include "LNG.h" #include "lwip/def.h" -#include "ams/ntohll.h" +#include "ntohll.h" LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) { LngHeader* h = (LngHeader*) payload; diff --git a/src/LNG.h b/src/LNG.h index 0cf4e6df..0b994a18 100644 --- a/src/LNG.h +++ b/src/LNG.h @@ -3,8 +3,8 @@ #include "AmsData.h" #include "AmsConfiguration.h" -#include "ams/DataParser.h" -#include "ams/Cosem.h" +#include "DataParser.h" +#include "Cosem.h" #include "RemoteDebug.h" struct LngHeader { From b48a0f13fe1bf1c06b6194c242aef03c8d89e709 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sun, 4 Dec 2022 14:12:35 +0100 Subject: [PATCH 25/66] More v2.2 --- lib/AmsConfiguration/src/AmsConfiguration.cpp | 31 +- lib/SvelteUi/app/src/app.postcss | 9 +- lib/SvelteUi/app/src/lib/Dashboard.svelte | 4 +- lib/SvelteUi/app/src/lib/PowerGauge.svelte | 9 +- lib/SvelteUi/app/src/lib/StatusPage.svelte | 58 ++- lib/SvelteUi/app/vite.config.js | 1 + lib/SvelteUi/include/AmsWebServer.h | 2 + lib/SvelteUi/scripts/generate_includes.py | 4 +- lib/SvelteUi/src/AmsWebServer.cpp | 374 +++++++++++++++++- src/AmsToMqttBridge.ino | 45 ++- 10 files changed, 488 insertions(+), 49 deletions(-) diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 60216c3b..f9064ad8 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -841,9 +841,38 @@ bool AmsConfiguration::relocateConfig95() { } bool AmsConfiguration::relocateConfig96() { - SystemConfig sys; EEPROM.begin(EEPROM_SIZE); + SystemConfig sys; EEPROM.get(CONFIG_SYSTEM_START, sys); + + #if defined(ESP8266) + MeterConfig meter; + EEPROM.get(CONFIG_METER_START, meter); + GpioConfig gpio; + EEPROM.get(CONFIG_GPIO_START, gpio); + + switch(sys.boardType) { + case 3: // Pow UART0 -- Now Pow-K UART0 + case 4: // Pow GPIO12 -- Now Pow-U UART0 + case 5: // Pow-K+ -- Now also Pow-K GPIO12 + case 7: // Pow-U+ -- Now also Pow-U GPIO12 + if(meter.baud == 2400 && meter.parity == 3) { // 3 == 8N1, assuming Pow-K + if(gpio.hanPin == 3) { // UART0 + sys.boardType = 3; + } else if(gpio.hanPin == 12) { + sys.boardType = 5; + } + } else { // Assuming Pow-U + if(gpio.hanPin == 3) { // UART0 + sys.boardType = 4; + } else if(gpio.hanPin == 12) { + sys.boardType = 7; + } + } + break; + } + #endif + sys.vendorConfigured = true; sys.userConfigured = true; sys.dataCollectionConsent = 0; diff --git a/lib/SvelteUi/app/src/app.postcss b/lib/SvelteUi/app/src/app.postcss index 5196ac17..a3e3dcf9 100644 --- a/lib/SvelteUi/app/src/app.postcss +++ b/lib/SvelteUi/app/src/app.postcss @@ -63,7 +63,7 @@ } .pl-ov { position: absolute; - top: 35%; + top: 28%; left: 25%; width: 50%; text-align: center; @@ -75,6 +75,13 @@ font-size: 1.0rem; color: grey; } +.pl-sub { + font-size: 1.0rem; +} +.pl-snt { + font-size: 0.7rem; + color: grey; +} .pl-lab { font-size: 1.0rem; } diff --git a/lib/SvelteUi/app/src/lib/Dashboard.svelte b/lib/SvelteUi/app/src/lib/Dashboard.svelte index bff56aff..a27a8752 100644 --- a/lib/SvelteUi/app/src/lib/Dashboard.svelte +++ b/lib/SvelteUi/app/src/lib/Dashboard.svelte @@ -35,7 +35,7 @@
- +
{data.mt ? metertype(data.mt) : '-'}
{data.ic ? data.ic.toFixed(1) : '-'} kWh
@@ -74,7 +74,7 @@
{/if} {#if (typeof data.p == "number") && !Number.isNaN(data.p)} -
+
{/if} diff --git a/lib/SvelteUi/app/src/lib/PowerGauge.svelte b/lib/SvelteUi/app/src/lib/PowerGauge.svelte index a04151b9..65cc757f 100644 --- a/lib/SvelteUi/app/src/lib/PowerGauge.svelte +++ b/lib/SvelteUi/app/src/lib/PowerGauge.svelte @@ -6,14 +6,21 @@ export let max; export let unit; export let label; + export let sub = ""; + export let subunit = "";
+ {label} +
{val} {unit} + {#if sub}
- {label} + {sub} + {subunit}/kWh + {/if}
diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index 5cc83797..bf56595c 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -45,13 +45,18 @@ } } - let fileinput; - let files = []; - let uploading = false; + let firmwareFileInput; + let firmwareFiles = []; + let firmwareUploading = false; + + let configFileInput; + let configFiles = []; + let configUploading = false; + getSysinfo(); -
+
Device information
@@ -65,7 +70,7 @@
- Change consents + Update consents
@@ -128,16 +133,47 @@
{/if}
-
uploading=true}> - - {#if files.length == 0} - + firmwareUploading=true}> + + {#if firmwareFiles.length == 0} + {:else} - {files[0].name} + {firmwareFiles[0].name} {/if}
+
+ Configuration +
+
+ + + + + + + + + + +
+ {#if firmwareFiles.length == 0} + + {/if} +
+
configUploading=true}> + + {#if firmwareFiles.length == 0} + + {:else} + {firmwareFiles[0].name} + + {/if} +
+ +
- + + diff --git a/lib/SvelteUi/app/vite.config.js b/lib/SvelteUi/app/vite.config.js index af80afb9..9bcb4a69 100644 --- a/lib/SvelteUi/app/vite.config.js +++ b/lib/SvelteUi/app/vite.config.js @@ -27,6 +27,7 @@ export default defineConfig({ "/tariff.json": "http://192.168.233.229", "/save": "http://192.168.233.229", "/reboot": "http://192.168.233.229", + "/configfile": "http://192.168.233.229", "/upgrade": "http://192.168.233.229" } } diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index f184d57d..b7e708ca 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -101,6 +101,8 @@ private: void mqttKeyUpload(); HTTPUpload& uploadFile(const char* path); + void configFileDownload(); + void configFileUpload(); void factoryResetPost(); void notFound(); diff --git a/lib/SvelteUi/scripts/generate_includes.py b/lib/SvelteUi/scripts/generate_includes.py index 0cbc873f..6bbd8e75 100644 --- a/lib/SvelteUi/scripts/generate_includes.py +++ b/lib/SvelteUi/scripts/generate_includes.py @@ -54,7 +54,9 @@ for webroot in ["lib/SvelteUi/app/dist", "lib/SvelteUi/json"]: varname = basename.upper() with open(srcfile, encoding="utf-8") as f: - content = f.read().replace("${version}", version) + content = f.read() + content = content.replace("index.js", "index-"+version+".js") + content = content.replace("index.css", "index-"+version+".css") try: if filename.endswith(".html"): diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 5e5a90f6..cb848c12 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -48,8 +48,13 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter this->ds = ds; this->ea = ea; - // TODO + server.on(F("/"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); + snprintf_P(buf, 32, PSTR("/index-%s.js"), VERSION); + server.on(buf, HTTP_GET, std::bind(&AmsWebServer::indexJs, this)); + snprintf_P(buf, 32, PSTR("/index-%s.css"), VERSION); + server.on(buf, HTTP_GET, std::bind(&AmsWebServer::indexCss, this)); + server.on(F("/configuration"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/status"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/consent"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); @@ -59,8 +64,6 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/mqtt-cert"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/mqtt-key"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); - server.on(F("/index.css"), HTTP_GET, std::bind(&AmsWebServer::indexCss, this)); - server.on(F("/index.js"), HTTP_GET, std::bind(&AmsWebServer::indexJs, this)); server.on(F("/github.svg"), HTTP_GET, std::bind(&AmsWebServer::githubSvg, this)); server.on(F("/favicon.ico"), HTTP_GET, std::bind(&AmsWebServer::faviconIco, this)); server.on(F("/sysinfo.json"), HTTP_GET, std::bind(&AmsWebServer::sysinfoJson, this)); @@ -87,6 +90,9 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/mqtt-cert"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttCertUpload, this)); server.on(F("/mqtt-key"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttKeyUpload, this)); + server.on(F("/configfile"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::configFileUpload, this)); + server.on(F("/configfile.cfg"),HTTP_GET, std::bind(&AmsWebServer::configFileDownload, this)); + server.onNotFound(std::bind(&AmsWebServer::notFound, this)); server.begin(); // Web server start @@ -664,13 +670,10 @@ void AmsWebServer::indexHtml() { void AmsWebServer::indexCss() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /index.css over http...\n"); - server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); - server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); - server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - if(!checkSecurity(2)) return; + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_1HR); server.setContentLength(INDEX_CSS_LEN); server.send_P(200, MIME_CSS, INDEX_CSS); } @@ -678,13 +681,10 @@ void AmsWebServer::indexCss() { void AmsWebServer::indexJs() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /index.js over http...\n"); - server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); - server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); - server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - if(!checkSecurity(2)) return; + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_1HR); server.setContentLength(INDEX_JS_LEN); server.send_P(200, MIME_JS, INDEX_JS); } @@ -1637,4 +1637,354 @@ void AmsWebServer::tariffJson() { void AmsWebServer::setPriceRegion(String priceRegion) { this->priceRegion = priceRegion; -} \ No newline at end of file +} + +void AmsWebServer::configFileDownload() { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /configfile.cfg over http...\n"); + + if(!checkSecurity(1)) + return; + + bool includeSecrets = server.hasArg(F("ic")) && server.arg(F("ic")) == F("true"); + bool includeWifi = server.hasArg(F("iw")) && server.arg(F("iw")) == F("true"); + bool includeMqtt = server.hasArg(F("im")) && server.arg(F("im")) == F("true"); + bool includeWeb = server.hasArg(F("ie")) && server.arg(F("ie")) == F("true"); + bool includeMeter = server.hasArg(F("it")) && server.arg(F("it")) == F("true"); + bool includeGpio = server.hasArg(F("ig")) && server.arg(F("ig")) == F("true"); + bool includeDomo = server.hasArg(F("id")) && server.arg(F("id")) == F("true"); + bool includeNtp = server.hasArg(F("in")) && server.arg(F("in")) == F("true"); + bool includeEntsoe = server.hasArg(F("is")) && server.arg(F("is")) == F("true"); + bool includeThresholds = server.hasArg(F("ih")) && server.arg(F("ih")) == F("true"); + + SystemConfig sys; + config->getSystemConfig(sys); + + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); + server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); + server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); + server.sendHeader(F("Content-Disposition"), F("attachment; filename=configfile.cfg")); + server.setContentLength(CONTENT_LENGTH_UNKNOWN); + + server.send_P(200, MIME_PLAIN, PSTR("amsconfig\n")); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("version %s\n"), VERSION)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("boardType %d\n"), sys.boardType)); + + if(includeWifi) { + WiFiConfig wifi; + config->getWiFiConfig(wifi); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("hostname %s\n"), wifi.hostname)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ssid %s\n"), wifi.ssid)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("psk %s\n"), wifi.psk)); + if(strlen(wifi.ip) > 0) { + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ip %s\n"), wifi.ip)); + if(strlen(wifi.gateway) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gateway %s\n"), wifi.gateway)); + if(strlen(wifi.subnet) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("subnet %s\n"), wifi.subnet)); + if(strlen(wifi.dns1) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dns1 %s\n"), wifi.dns1)); + if(strlen(wifi.dns2) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dns2 %s\n"), wifi.dns2)); + } + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mdns %d\n"), wifi.mdns ? 1 : 0)); + } + + if(includeMqtt) { + MqttConfig mqtt; + config->getMqttConfig(mqtt); + if(strlen(mqtt.host) > 0) { + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttHost %s\n"), mqtt.host)); + if(mqtt.port > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPort %d\n"), mqtt.port)); + if(strlen(mqtt.clientId) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttClientId %s\n"), mqtt.clientId)); + if(strlen(mqtt.publishTopic) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPublishTopic %s\n"), mqtt.publishTopic)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttUsername %s\n"), mqtt.username)); + if(includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPassword %s\n"), mqtt.password)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttPayloadFormat %d\n"), mqtt.payloadFormat)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("mqttSsl %d\n"), mqtt.ssl ? 1 : 0)); + } + } + + if(includeWeb && includeSecrets) { + WebConfig web; + config->getWebConfig(web); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webSecurity %d\n"), web.security)); + if(web.security > 0) { + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webUsername %s\n"), web.username)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("webPassword %s\n"), web.password)); + } + } + + if(includeMeter) { + MeterConfig meter; + config->getMeterConfig(meter); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterBaud %d\n"), meter.baud)); + char parity[4] = ""; + switch(meter.parity) { + case 2: + strcpy_P(parity, PSTR("7N1")); + break; + case 3: + strcpy_P(parity, PSTR("8N1")); + break; + case 10: + strcpy_P(parity, PSTR("7E1")); + break; + case 11: + strcpy_P(parity, PSTR("8E1")); + break; + } + if(strlen(parity) > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterParity %s\n"), parity)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterInvert %d\n"), meter.invert ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterDistributionSystem %d\n"), meter.distributionSystem)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterMainFuse %d\n"), meter.mainFuse)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterProductionCapacity %d\n"), meter.productionCapacity)); + if(includeSecrets) { + if(meter.encryptionKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterEncryptionKey %s\n"), toHex(meter.encryptionKey, 16).c_str())); + if(meter.authenticationKey[0] != 0x00) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("meterAuthenticationKey %s\n"), toHex(meter.authenticationKey, 16).c_str())); + } + } + + if(includeGpio) { + GpioConfig gpio; + config->getGpioConfig(gpio); + if(gpio.hanPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioHanPin %d\n"), gpio.hanPin)); + if(gpio.apPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioApPin %d\n"), gpio.apPin)); + if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPin %d\n"), gpio.ledPin)); + if(gpio.ledPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedInverted %d\n"), gpio.ledInverted ? 1 : 0)); + if(gpio.ledPinRed != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinRed %d\n"), gpio.ledPinRed)); + if(gpio.ledPinGreen != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinGreen %d\n"), gpio.ledPinGreen)); + if(gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedPinBlue %d\n"), gpio.ledPinBlue)); + if(gpio.ledPinRed != 0xFF || gpio.ledPinGreen != 0xFF || gpio.ledPinBlue != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioLedRgbInverted %d\n"), gpio.ledRgbInverted ? 1 : 0)); + if(gpio.tempSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioTempSensorPin %d\n"), gpio.tempSensorPin)); + if(gpio.tempAnalogSensorPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioTempAnalogSensorPin %d\n"), gpio.tempAnalogSensorPin)); + if(gpio.vccPin != 0xFF) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccPin %d\n"), gpio.vccPin)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccOffset %.2f\n"), gpio.vccOffset / 100.0)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccMultiplier %.3f\n"), gpio.vccMultiplier / 1000.0)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccBootLimit %.1f\n"), gpio.vccBootLimit / 10.0)); + if(gpio.vccPin != 0xFF && gpio.vccResistorGnd != 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccResistorGnd %d\n"), gpio.vccResistorGnd)); + if(gpio.vccPin != 0xFF && gpio.vccResistorVcc != 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("gpioVccResistorVcc %d\n"), gpio.vccResistorVcc)); + } + + if(includeDomo) { + DomoticzConfig domo; + config->getDomoticzConfig(domo); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzElidx %d\n"), domo.elidx)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl1idx %d\n"), domo.vl1idx)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl2idx %d\n"), domo.vl2idx)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzVl3idx %d\n"), domo.vl3idx)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("domoticzCl1idx %d\n"), domo.cl1idx)); + } + + if(includeNtp) { + NtpConfig ntp; + config->getNtpConfig(ntp); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpEnable %d\n"), ntp.enable ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpDhcp %d\n"), ntp.dhcp ? 1 : 0)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpTimezone %s\n"), ntp.timezone)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("ntpServer %s\n"), ntp.server)); + } + + if(includeEntsoe) { + EntsoeConfig entsoe; + config->getEntsoeConfig(entsoe); + if(strlen(entsoe.token) == 36 && includeSecrets) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("entsoeToken %s\n"), entsoe.token)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("entsoeArea %s\n"), entsoe.area)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("entsoeCurrency %s\n"), entsoe.currency)); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("entsoeMultiplier %.3f\n"), entsoe.multiplier / 1000.0)); + } + + if(includeThresholds) { + EnergyAccountingConfig eac; + config->getEnergyAccountingConfig(eac); + + if(eac.thresholds[9] > 0) server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("thresholds %d %d %d %d %d %d %d %d %d %d %d\n"), + eac.thresholds[0], + eac.thresholds[1], + eac.thresholds[2], + eac.thresholds[3], + eac.thresholds[4], + eac.thresholds[5], + eac.thresholds[6], + eac.thresholds[7], + eac.thresholds[8], + eac.thresholds[9], + eac.hours + )); + } + + + if(ds != NULL) { + DayDataPoints day = ds->getDayData(); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + day.version, + (int64_t) day.lastMeterReadTime, + day.activeImport, + ds->getHourImport(0), + ds->getHourImport(1), + ds->getHourImport(2), + ds->getHourImport(3), + ds->getHourImport(4), + ds->getHourImport(5), + ds->getHourImport(6), + ds->getHourImport(7), + ds->getHourImport(8), + ds->getHourImport(9), + ds->getHourImport(10), + ds->getHourImport(11), + ds->getHourImport(12), + ds->getHourImport(13), + ds->getHourImport(14), + ds->getHourImport(15), + ds->getHourImport(16), + ds->getHourImport(17), + ds->getHourImport(18), + ds->getHourImport(19), + ds->getHourImport(20), + ds->getHourImport(21), + ds->getHourImport(22), + ds->getHourImport(23) + )); + if(day.activeExport > 0) { + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR(" %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), + day.activeExport, + ds->getHourExport(0), + ds->getHourExport(1), + ds->getHourExport(2), + ds->getHourExport(3), + ds->getHourExport(4), + ds->getHourExport(5), + ds->getHourExport(6), + ds->getHourExport(7), + ds->getHourExport(8), + ds->getHourExport(9), + ds->getHourExport(10), + ds->getHourExport(11), + ds->getHourExport(12), + ds->getHourExport(13), + ds->getHourExport(14), + ds->getHourExport(15), + ds->getHourExport(16), + ds->getHourExport(17), + ds->getHourExport(18), + ds->getHourExport(19), + ds->getHourExport(20), + ds->getHourExport(21), + ds->getHourExport(22), + ds->getHourExport(23) + )); + } else { + server.sendContent(F("\n")); + } + + MonthDataPoints month = ds->getMonthData(); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + month.version, + (int64_t) month.lastMeterReadTime, + month.activeImport, + ds->getDayImport(1), + ds->getDayImport(2), + ds->getDayImport(3), + ds->getDayImport(4), + ds->getDayImport(5), + ds->getDayImport(6), + ds->getDayImport(7), + ds->getDayImport(8), + ds->getDayImport(9), + ds->getDayImport(10), + ds->getDayImport(11), + ds->getDayImport(12), + ds->getDayImport(13), + ds->getDayImport(14), + ds->getDayImport(15), + ds->getDayImport(16), + ds->getDayImport(17), + ds->getDayImport(18), + ds->getDayImport(19), + ds->getDayImport(20), + ds->getDayImport(21), + ds->getDayImport(22), + ds->getDayImport(23), + ds->getDayImport(24), + ds->getDayImport(25), + ds->getDayImport(26), + ds->getDayImport(27), + ds->getDayImport(28), + ds->getDayImport(29), + ds->getDayImport(30), + ds->getDayImport(31) + )); + if(month.activeExport > 0) { + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR(" %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"), + month.activeExport, + ds->getDayExport(1), + ds->getDayExport(2), + ds->getDayExport(3), + ds->getDayExport(4), + ds->getDayExport(5), + ds->getDayExport(6), + ds->getDayExport(7), + ds->getDayExport(8), + ds->getDayExport(9), + ds->getDayExport(10), + ds->getDayExport(11), + ds->getDayExport(12), + ds->getDayExport(13), + ds->getDayExport(14), + ds->getDayExport(15), + ds->getDayExport(16), + ds->getDayExport(17), + ds->getDayExport(18), + ds->getDayExport(19), + ds->getDayExport(20), + ds->getDayExport(21), + ds->getDayExport(22), + ds->getDayExport(23), + ds->getDayExport(24), + ds->getDayExport(25), + ds->getDayExport(26), + ds->getDayExport(27), + ds->getDayExport(28), + ds->getDayExport(29), + ds->getDayExport(30), + ds->getDayExport(31) + )); + } else { + server.sendContent(F("\n")); + } + } + + if(ea != NULL) { + EnergyAccountingConfig eac; + config->getEnergyAccountingConfig(eac); + EnergyAccountingData ead = ea->getData(); + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %.2f %.2f %.2f %d %.2f %d %.2f %d %.2f %d %.2f %d %.2f"), + ead.version, + ead.month, + ead.costYesterday / 10.0, + ead.costThisMonth / 1.0, + ead.costLastMonth / 1.0, + ead.incomeYesterday / 10.0, + ead.incomeThisMonth / 1.0, + ead.incomeLastMonth / 1.0, + ead.peaks[0].day, + ead.peaks[0].value / 100.0, + ead.peaks[1].day, + ead.peaks[1].value / 100.0, + ead.peaks[2].day, + ead.peaks[2].value / 100.0, + ead.peaks[3].day, + ead.peaks[3].value / 100.0, + ead.peaks[4].day, + ead.peaks[4].value / 100.0 + )); + server.sendContent("\n"); + } +} + +void AmsWebServer::configFileUpload() { + if(!checkSecurity(1)) + return; + + HTTPUpload& upload = uploadFile(FILE_CFG); + if(upload.status == UPLOAD_FILE_END) { + performRestart = true; + server.sendHeader("Location","/"); + server.send(303); + } +} diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index c72e1a56..23b645db 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -1715,6 +1715,7 @@ void configFileParse() { 0, 0, // Peak 4 0, 0 // Peak 5 }; + uint8_t peak = 0; char * pch = strtok (buf+17," "); while (pch != NULL) { if(ead.version < 5) { @@ -1740,13 +1741,17 @@ void configFileParse() { ead.costLastMonth = val; } else if(i >= 6 && i < 18) { uint8_t hour = i-6; - if(hour%2 == 0) { + { long val = String(pch).toInt(); - ead.peaks[hour/2].day = val; - } else { + ead.peaks[peak].day = val; + } + pch = strtok (NULL, " "); + i++; + { double val = String(pch).toDouble(); - ead.peaks[hour/2].value = val * 100; + ead.peaks[peak].value = val * 100; } + peak++; } } else { if(i == 1) { @@ -1754,41 +1759,41 @@ void configFileParse() { ead.month = val; } else if(i == 2) { double val = String(pch).toDouble(); - if(val > 0.0) { - ead.peaks[0] = { 1, (uint16_t) (val*100) }; - } + ead.costYesterday = val * 10; } else if(i == 3) { double val = String(pch).toDouble(); - ead.costYesterday = val * 10; + ead.costThisMonth = val; } else if(i == 4) { double val = String(pch).toDouble(); - ead.costThisMonth = val; + ead.costLastMonth = val; } else if(i == 5) { double val = String(pch).toDouble(); - ead.costLastMonth = val; + ead.incomeYesterday= val * 10; } else if(i == 6) { double val = String(pch).toDouble(); - ead.incomeYesterday= val * 10; + ead.incomeThisMonth = val; } else if(i == 7) { - double val = String(pch).toDouble(); - ead.incomeThisMonth = val; - } else if(i == 8) { double val = String(pch).toDouble(); ead.incomeLastMonth = val; - } else if(i >= 9 && i < 21) { - uint8_t hour = i-9; - if(hour%2 == 0) { + } else if(i >= 8 && i < 20) { + uint8_t hour = i-8; + { long val = String(pch).toInt(); - ead.peaks[hour/2].day = val; - } else { + ead.peaks[peak].day = val; + } + pch = strtok (NULL, " "); + i++; + { double val = String(pch).toDouble(); - ead.peaks[hour/2].value = val * 100; + ead.peaks[peak].value = val * 100; } + peak++; } } pch = strtok (NULL, " "); i++; } + ead.version = 5; ea.setData(ead); sEa = true; } From 8a809ec128410858d7db1598ad37b7e68ce3ded3 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sun, 4 Dec 2022 14:32:47 +0100 Subject: [PATCH 26/66] Bugfix from testing --- lib/AmsConfiguration/src/AmsConfiguration.cpp | 1 + lib/SvelteUi/app/src/lib/DataStores.js | 24 +++++++++---------- lib/SvelteUi/app/src/lib/StatusPage.svelte | 8 +++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index f9064ad8..3b7e18a0 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -484,6 +484,7 @@ bool AmsConfiguration::setEntsoeConfig(EntsoeConfig& config) { entsoeChanged |= strcmp(config.area, existing.area) != 0; entsoeChanged |= strcmp(config.currency, existing.currency) != 0; entsoeChanged |= config.multiplier != existing.multiplier; + entsoeChanged |= config.enabled != existing.enabled; } else { entsoeChanged = true; } diff --git a/lib/SvelteUi/app/src/lib/DataStores.js b/lib/SvelteUi/app/src/lib/DataStores.js index 215ce85a..2f271189 100644 --- a/lib/SvelteUi/app/src/lib/DataStores.js +++ b/lib/SvelteUi/app/src/lib/DataStores.js @@ -23,7 +23,6 @@ let sysinfo = { upgrading: false }; export const sysinfoStore = writable(sysinfo); - export async function getSysinfo() { const response = await fetchWithTimeout("/sysinfo.json"); sysinfo = (await response.json()) @@ -32,6 +31,7 @@ export async function getSysinfo() { let tries = 0; let lastTemp = -127; +let lastPrice = null; let data = {}; export const dataStore = readable(data, (set) => { let timeout; @@ -44,6 +44,10 @@ export const dataStore = readable(data, (set) => { lastTemp = data.t; getTemperatures(); } + if(lastPrice != data.p) { + lastPrice = data.p; + getPrices(); + } if(sysinfo.upgrading) { window.location.reload(); } else if(sysinfo.booting) { @@ -74,18 +78,12 @@ export const dataStore = readable(data, (set) => { }); let prices = {}; -export const pricesStore = readable(prices, (set) => { - async function getPrices(){ - const response = await fetchWithTimeout("/energyprice.json"); - prices = (await response.json()) - set(prices); - - let date = new Date(); - setTimeout(getPrices, (61-date.getMinutes())*60000) - } - getPrices(); - return function stop() {} -}); +export const pricesStore = writable(prices); +export async function getPrices(){ + const response = await fetchWithTimeout("/energyprice.json"); + prices = (await response.json()) + pricesStore.set(prices); +} let dayPlot = {}; export const dayPlotStore = readable(dayPlot, (set) => { diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index bf56595c..66441c55 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -159,16 +159,16 @@
- {#if firmwareFiles.length == 0} + {#if configFiles.length == 0} {/if}
configUploading=true}> - - {#if firmwareFiles.length == 0} + + {#if configFiles.length == 0} {:else} - {firmwareFiles[0].name} + {configFiles[0].name} {/if}
From 2218ac4e8a0daebe1c6cb2eab09fc662c747dca8 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 7 Dec 2022 11:32:55 +0100 Subject: [PATCH 27/66] Fixed graph clearing problem --- lib/AmsDataStorage/src/AmsDataStorage.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/AmsDataStorage/src/AmsDataStorage.cpp b/lib/AmsDataStorage/src/AmsDataStorage.cpp index 75bf4b56..091eef04 100644 --- a/lib/AmsDataStorage/src/AmsDataStorage.cpp +++ b/lib/AmsDataStorage/src/AmsDataStorage.cpp @@ -67,7 +67,7 @@ bool AmsDataStorage::update(AmsData* data) { } tmElements_t last; breakTime(day.lastMeterReadTime, last); - for(int i = last.Hour; i <= utc.Hour; i++) { + for(int i = last.Hour; i < utc.Hour; i++) { if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) Clearing hour: %d\n", i); } @@ -90,7 +90,7 @@ bool AmsDataStorage::update(AmsData* data) { } tmElements_t last; breakTime(tz->toLocal(month.lastMeterReadTime), last); - for(int i = last.Day; i <= ltz.Day; i++) { + for(int i = last.Day; i < ltz.Day; i++) { if(debugger->isActive(RemoteDebug::VERBOSE)) { debugger->printf("(AmsDataStorage) Clearing day: %d\n", i); } From 2ff7044c853757487cb783852f0c19bb2b31cee7 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 7 Dec 2022 20:13:30 +0100 Subject: [PATCH 28/66] Fixed incorrect value for peaks in MQTT --- lib/ClassicUi/src/AmsWebServer.cpp | 2 +- lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp | 2 +- lib/RawMqttHandler/src/RawMqttHandler.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ClassicUi/src/AmsWebServer.cpp b/lib/ClassicUi/src/AmsWebServer.cpp index 6e0de991..f7835a73 100644 --- a/lib/ClassicUi/src/AmsWebServer.cpp +++ b/lib/ClassicUi/src/AmsWebServer.cpp @@ -735,7 +735,7 @@ void AmsWebServer::dataJson() { if(peakCount > 5) peakCount = 5; for(uint8_t i = 1; i <= peakCount; i++) { if(!peaks.isEmpty()) peaks += ","; - peaks += String(ea->getPeak(i)); + peaks += String(ea->getPeak(i).value / 100.0); } snprintf_P(buf, BufferSize, DATA_JSON, diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 39d42823..71253a6c 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -86,7 +86,7 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En if(peakCount > 5) peakCount = 5; for(uint8_t i = 1; i <= peakCount; i++) { if(!peaks.isEmpty()) peaks += ","; - peaks += String(ea->getPeak(i).value, 2); + peaks += String(ea->getPeak(i).value / 100.0, 2); } snprintf_P(json, BufferSize, REALTIME_JSON, ea->getMonthMax(), diff --git a/lib/RawMqttHandler/src/RawMqttHandler.cpp b/lib/RawMqttHandler/src/RawMqttHandler.cpp index cf4a4007..1767e3d9 100644 --- a/lib/RawMqttHandler/src/RawMqttHandler.cpp +++ b/lib/RawMqttHandler/src/RawMqttHandler.cpp @@ -95,7 +95,7 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin uint8_t peakCount = ea->getConfig()->hours; if(peakCount > 5) peakCount = 5; for(uint8_t i = 1; i <= peakCount; i++) { - mqtt->publish(topic + "/realtime/import/peak/" + String(i, 10), String(ea->getPeak(i).value, 10), true, 0); + mqtt->publish(topic + "/realtime/import/peak/" + String(i, 10), String(ea->getPeak(i).value / 100.0, 10), true, 0); } mqtt->publish(topic + "/realtime/import/threshold", String(ea->getCurrentThreshold(), 10), true, 0); mqtt->publish(topic + "/realtime/import/monthmax", String(ea->getMonthMax(), 3), true, 0); From 6c3ddc57b54f964c4b419ecf9e203d57bf9de1c6 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Thu, 8 Dec 2022 13:44:21 +0100 Subject: [PATCH 29/66] Removed "auto multiplier" for Kamstrup --- src/IEC6205675.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index ccad1be7..ef690518 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -351,13 +351,6 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo l2PowerFactor /= 100; if(l3PowerFactor != 0) l3PowerFactor /= 100; - - int watt = abs((l1voltage * l1current) + (l2voltage * l2current) + (l3voltage * l3current)); - if(watt / (activeImportPower + activeExportPower + reactiveImportPower + reactiveExportPower) > 2) { - l1current = l1current != 0 ? l1current / 10 : 0; - l2current = l2current != 0 ? l2current / 10 : 0; - l3current = l3current != 0 ? l3current / 10 : 0; - } } else if(meterType == AmsTypeSagemcom) { CosemData* meterTs = getCosemDataAt(1, ((char *) (d))); if(meterTs != NULL) { From b2de6472cf4c07d480cb342f735866c4ca601f0e Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 9 Dec 2022 18:24:43 +0100 Subject: [PATCH 30/66] Some experiments with captive portal --- lib/SvelteUi/include/AmsWebServer.h | 1 + lib/SvelteUi/src/AmsWebServer.cpp | 15 +++++++++++++-- src/AmsToMqttBridge.ino | 13 +++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index b7e708ca..fb747065 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -106,6 +106,7 @@ private: void factoryResetPost(); void notFound(); + void redirectToMain(); void robotstxt(); }; diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index cb848c12..a17573cb 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -48,7 +48,6 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter this->ds = ds; this->ea = ea; - server.on(F("/"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); snprintf_P(buf, 32, PSTR("/index-%s.js"), VERSION); server.on(buf, HTTP_GET, std::bind(&AmsWebServer::indexJs, this)); @@ -91,7 +90,14 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/mqtt-key"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::mqttKeyUpload, this)); server.on(F("/configfile"), HTTP_POST, std::bind(&AmsWebServer::firmwarePost, this), std::bind(&AmsWebServer::configFileUpload, this)); - server.on(F("/configfile.cfg"),HTTP_GET, std::bind(&AmsWebServer::configFileDownload, this)); + server.on(F("/configfile.cfg"), HTTP_GET, std::bind(&AmsWebServer::configFileDownload, this)); + + /* These trigger captive portal. Only problem is that after you have "signed in", the portal is closed and the user has no idea how to reach the device + server.on(F("/generate_204"), HTTP_GET, std::bind(&AmsWebServer::redirectToMain, this)); // Android captive portal check: http://connectivitycheck.gstatic.com/generate_204 + server.on(F("/ncsi.txt"), HTTP_GET, std::bind(&AmsWebServer::redirectToMain, this)); // Microsoft connectivity check: http://www.msftncsi.com/ncsi.txt + server.on(F("/fwlink"), HTTP_GET, std::bind(&AmsWebServer::redirectToMain, this)); // Microsoft connectivity check + server.on(F("/library/test/success.html"), HTTP_GET, std::bind(&AmsWebServer::redirectToMain, this)); // Apple connectivity check: http://www.apple.com/library/test/success.html + */ server.onNotFound(std::bind(&AmsWebServer::notFound, this)); @@ -1988,3 +1994,8 @@ void AmsWebServer::configFileUpload() { server.send(303); } } + +void AmsWebServer::redirectToMain() { + server.sendHeader("Location","/"); + server.send(302); +} \ No newline at end of file diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 23b645db..8b180345 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -755,6 +755,19 @@ void swapWifiMode() { if (mode != WIFI_AP || !config.hasConfig()) { if(Debug.isActive(RemoteDebug::INFO)) debugI("Swapping to AP mode"); + + //wifi_softap_set_dhcps_offer_option(OFFER_ROUTER, 0); // Disable default gw + + /* Example code to set captive portal option in DHCP + auto& server = WiFi.softAPDhcpServer(); + server.onSendOptions([](const DhcpServer& server, auto& options) { + // Captive Portal URI + const IPAddress gateway = netif_ip4_addr(server.getNetif()); + const String captive = F("http://") + gateway.toString(); + options.add(114, captive.c_str(), captive.length()); + }); + */ + WiFi.softAP(PSTR("AMS2MQTT")); WiFi.mode(WIFI_AP); From bc4d61098c8f9ca1b68c53fb48ea92a9afcb0e40 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 9 Dec 2022 19:10:24 +0100 Subject: [PATCH 31/66] Some error handling --- lib/EntsoePriceApi/include/EntsoeApi.h | 4 +++ lib/EntsoePriceApi/src/EntsoeApi.cpp | 30 +++++++++++++++---- lib/SvelteUi/app/src/lib/Header.svelte | 9 ++++-- lib/SvelteUi/app/src/lib/Helpers.js | 20 +++++++++++++ lib/SvelteUi/app/src/lib/VendorPanel.svelte | 5 +++- lib/SvelteUi/json/data.json | 1 + lib/SvelteUi/src/AmsWebServer.cpp | 5 +++- src/AmsToMqttBridge.ino | 32 ++++++++++++--------- 8 files changed, 82 insertions(+), 24 deletions(-) diff --git a/lib/EntsoePriceApi/include/EntsoeApi.h b/lib/EntsoePriceApi/include/EntsoeApi.h index 43f3811c..7ff12fba 100644 --- a/lib/EntsoePriceApi/include/EntsoeApi.h +++ b/lib/EntsoePriceApi/include/EntsoeApi.h @@ -29,6 +29,8 @@ public: float getValueForHour(int8_t); float getValueForHour(time_t, int8_t); + int16_t getLastError(); + private: RemoteDebug* debugger; EntsoeConfig* config = NULL; @@ -54,6 +56,8 @@ private: float currencyMultiplier = 0; + int16_t lastError = 0; + PricesContainer* fetchPrices(time_t); bool retrieve(const char* url, Stream* doc); float getCurrencyMultiplier(const char* from, const char* to); diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 32af0385..3efe4d5f 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -164,8 +164,13 @@ bool EntsoeApi::loop() { return true; } else { if(today == NULL && (lastTodayFetch == 0 || now - lastTodayFetch > 60000)) { - lastTodayFetch = now; - today = fetchPrices(t); + try { + lastTodayFetch = now; + today = fetchPrices(t); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + today = NULL; + } return today != NULL; } @@ -175,9 +180,14 @@ bool EntsoeApi::loop() { && midnightMillis - now < tomorrowFetchMillis && (lastTomorrowFetch == 0 || now - lastTomorrowFetch > 900000) ) { - breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight - lastTomorrowFetch = now; - tomorrow = fetchPrices(t+SECS_PER_DAY); + try { + breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight + lastTomorrowFetch = now; + tomorrow = fetchPrices(t+SECS_PER_DAY); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + tomorrow = NULL; + } return tomorrow != NULL; } } @@ -207,8 +217,10 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { printD("Receiving data"); http.writeToStream(doc); http.end(); + lastError = 0; return true; } else { + lastError = status; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); printE(http.errorToString(status)); printD(http.getString()); @@ -326,7 +338,9 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { printD("Receiving data"); data = http.getString(); http.end(); + lastError = 0; } else { + lastError = status; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Communication error, returned status: %d\n", status); printE(http.errorToString(status)); printD(http.getString()); @@ -355,8 +369,10 @@ PricesContainer* EntsoeApi::fetchPrices(time_t t) { for(uint8_t i = 0; i < 24; i++) { ret->points[i] = ntohl(ret->points[i]); } + lastError = 0; return ret; } else { + lastError = gcmRet; if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf("(EntsoeApi) Error code while decrypting prices: %d\n", gcmRet); } } @@ -392,3 +408,7 @@ void EntsoeApi::debugPrint(byte *buffer, int start, int length) { } debugger->println(""); } + +int16_t EntsoeApi::getLastError() { + return lastError; +} \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index bb41bf27..024b4498 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -2,7 +2,7 @@ import { Link } from "svelte-navigator"; import { sysinfoStore, getGitHubReleases, gitHubReleaseStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; - import { boardtype, hanError, mqttError } from './Helpers.js'; + import { boardtype, hanError, mqttError, priceError } from './Helpers.js'; import GitHubLogo from './../assets/github.svg'; import Uptime from "./Uptime.svelte"; import Badge from './Badge.svelte'; @@ -59,10 +59,13 @@
{#if data.he < 0} -
{ 'HAN error: ' + hanError(data.he) }
+
{ 'HAN: ' + hanError(data.he) }
{/if} {#if data.me < 0} -
{ 'MQTT error: ' + mqttError(data.me) }
+
{ 'MQTT: ' + mqttError(data.me) }
+ {/if} + {#if data.ee != 0} +
{ 'PriceAPI: ' + priceError(data.ee) }
{/if}
diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index 2cb3ea50..6712ceae 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -118,6 +118,26 @@ export function mqttError(err) { case -13: return "Connection lost"; } + if(err < 0) return "Unspecified error "+err; + return ""; +} + +export function priceError(err) { + switch(err) { + case 401: + case 403: + return "Unauthorized, check API key"; + case 404: + return "Price unavailable, not found"; + case 500: + return "Internal server error"; + case -2: return "Incomplete data received"; + case -3: return "Invalid data, tag missing"; + case -51: return "Authentication failed"; + case -52: return "Decryption failed"; + case -53: return "Encryption key invalid"; + } + if(err < 0) return "Unspecified error "+err; return ""; } \ No newline at end of file diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index dac12b65..8740f27c 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -29,7 +29,7 @@ s.booting = res.reboot; return s; }); - navigate("/setup"); + navigate(sysinfo.usrcfg ? "/" : "/setup"); } @@ -52,6 +52,9 @@
{/if} +
+ +
diff --git a/lib/SvelteUi/json/data.json b/lib/SvelteUi/json/data.json index 173c115f..6b840e41 100644 --- a/lib/SvelteUi/json/data.json +++ b/lib/SvelteUi/json/data.json @@ -58,5 +58,6 @@ }, "pr" : "%s", "he" : %d, + "ee" : %d, "c" : %lu } \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index a17573cb..a2385992 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -403,6 +403,7 @@ void AmsWebServer::dataJson() { ea->getIncomeThisMonth(), priceRegion.c_str(), meterState->getLastError(), + eapi == NULL ? 0 : eapi->getLastError(), (uint32_t) time(nullptr) ); @@ -859,7 +860,9 @@ void AmsWebServer::handleSave() { if(server.hasArg(F("v")) && server.arg(F("v")) == F("true")) { int boardType = server.arg(F("vb")).toInt(); int hanPin = server.arg(F("vh")).toInt(); - config->clear(); + if(server.hasArg(F("vr")) && server.arg(F("vr")) == F("true")) { + config->clear(); + } #if defined(CONFIG_IDF_TARGET_ESP32S2) switch(boardType) { diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 8b180345..a2d11865 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -572,25 +572,29 @@ void loop() { ea.setup(&ds, eac); config.ackEnergyAccountingChange(); } + try { + if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { + if(now - lastTemperatureRead > 15000) { + unsigned long start = millis(); + hw.updateTemperatures(); + lastTemperatureRead = now; - if(readHanPort() || now - meterState.getLastUpdateMillis() > 30000) { - if(now - lastTemperatureRead > 15000) { - unsigned long start = millis(); - hw.updateTemperatures(); - lastTemperatureRead = now; - - if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { - mqttHandler->publishTemperatures(&config, &hw); + if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { + mqttHandler->publishTemperatures(&config, &hw); + } + debugD("Used %ld ms to update temperature", millis()-start); } - debugD("Used %ld ms to update temperature", millis()-start); - } - if(now - lastSysupdate > 10000) { - if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { - mqttHandler->publishSystem(&hw, eapi, &ea); + if(now - lastSysupdate > 10000) { + if(mqtt != NULL && mqttHandler != NULL && WiFi.getMode() != WIFI_AP && WiFi.status() == WL_CONNECTED && mqtt->connected() && !topic.isEmpty()) { + mqttHandler->publishSystem(&hw, eapi, &ea); + } + lastSysupdate = now; } - lastSysupdate = now; } + } catch(const std::exception& e) { + debugE("Exception in readHanPort (%s)", e.what()); } + delay(1); // Needed for auto modem sleep #if defined(ESP32) esp_task_wdt_reset(); From 27b9058af53740be9c8e542d94f17923e8a9b3c2 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 9 Dec 2022 20:26:31 +0100 Subject: [PATCH 32/66] Some improvements to v2.2 --- .../include/AmsConfiguration.h | 3 +- lib/AmsConfiguration/src/AmsConfiguration.cpp | 3 + .../app/src/lib/ConfigurationPanel.svelte | 5 +- lib/SvelteUi/app/src/lib/DataStores.js | 5 +- lib/SvelteUi/app/src/lib/Header.svelte | 2 +- lib/SvelteUi/json/conf_wifi.json | 3 +- lib/SvelteUi/json/favicon.base64 | 96 +++++++++++++++++++ lib/SvelteUi/src/AmsWebServer.cpp | 29 ++++-- src/AmsToMqttBridge.ino | 14 +-- 9 files changed, 140 insertions(+), 20 deletions(-) create mode 100644 lib/SvelteUi/json/favicon.base64 diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index c124139f..cbbcb8f2 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -61,7 +61,8 @@ struct WiFiConfig { uint8_t power; uint8_t sleep; uint8_t mode; -}; // 212 + bool autoreboot; +}; // 213 struct MqttConfig86 { char host[128]; diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 3b7e18a0..8edc4817 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -54,6 +54,8 @@ bool AmsConfiguration::setWiFiConfig(WiFiConfig& config) { wifiChanged |= strcmp(config.hostname, existing.hostname) != 0; wifiChanged |= config.power != existing.power; wifiChanged |= config.sleep != existing.sleep; + wifiChanged |= config.mode != existing.mode; + wifiChanged |= config.autoreboot != existing.autoreboot; } else { wifiChanged = true; } @@ -883,6 +885,7 @@ bool AmsConfiguration::relocateConfig96() { WiFiConfig wifi; EEPROM.get(CONFIG_WIFI_START, wifi); wifi.mode = 1; // WIFI_STA + wifi.autoreboot = true; EEPROM.put(CONFIG_WIFI_START, wifi); NtpConfig ntp; diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index b7e450b2..1e423e1f 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -23,7 +23,7 @@ e: { e: false, k: '', a: '' }, m: { e: false, w: false, v: false, a: false, c: false } }, - w: { s: '', p: '', w: 0.0, z: 255 }, + w: { s: '', p: '', w: 0.0, z: 255, a: true }, n: { m: '', i: '', s: '', g: '', d1: '', d2: '', d: false, n1: '', n2: '', h: false }, @@ -335,6 +335,9 @@
+
+ +
Network diff --git a/lib/SvelteUi/app/src/lib/DataStores.js b/lib/SvelteUi/app/src/lib/DataStores.js index 2f271189..7970faa6 100644 --- a/lib/SvelteUi/app/src/lib/DataStores.js +++ b/lib/SvelteUi/app/src/lib/DataStores.js @@ -20,11 +20,12 @@ let sysinfo = { usrcfg: null, fwconsent: null, booting: false, - upgrading: false + upgrading: false, + security: 0 }; export const sysinfoStore = writable(sysinfo); export async function getSysinfo() { - const response = await fetchWithTimeout("/sysinfo.json"); + const response = await fetchWithTimeout("/sysinfo.json?t=" + Math.floor(Date.now() / 1000)); sysinfo = (await response.json()) sysinfoStore.set(sysinfo); }; diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index 024b4498..fd3d2f53 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -64,7 +64,7 @@ {#if data.me < 0}
{ 'MQTT: ' + mqttError(data.me) }
{/if} - {#if data.ee != 0} + {#if data.ee > 0 || data.ee < 0}
{ 'PriceAPI: ' + priceError(data.ee) }
{/if}
diff --git a/lib/SvelteUi/json/conf_wifi.json b/lib/SvelteUi/json/conf_wifi.json index 9071e9b7..3433a640 100644 --- a/lib/SvelteUi/json/conf_wifi.json +++ b/lib/SvelteUi/json/conf_wifi.json @@ -2,5 +2,6 @@ "s": "%s", "p": "%s", "w": %.1f, - "z": %d + "z": %d, + "a": %s }, diff --git a/lib/SvelteUi/json/favicon.base64 b/lib/SvelteUi/json/favicon.base64 new file mode 100644 index 00000000..c9f90807 --- /dev/null +++ b/lib/SvelteUi/json/favicon.base64 @@ -0,0 +1,96 @@ +AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////////////////////+/v7/2dG4/4tuIP+E +ZxT/x7mU//7+/v///////////////////////////////////////////////////////v78/4hs +Hv/b07v/6+fa/4VoF//w7eT//v7+//////////////////////////////////////////////// +//39+/+BZBL/7+zh//r69/+JbSD/6eXY//7+/v////////////////////////////////////// +///////////+/v7/wbOL/4dqGf+LcCL/qpVd//7+/v/+/v7////////////////////////////+ +/v7//v7+//7+/v/+/v7//v7+//7+/v/t6d7/6OLT//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v/+/v7/+Pfy/7ysgP/x7ub//v7+//7+/v/39vL/wrOL/+vn2//+/v7//v7+ +//7+/v/+/v7//v7+//Dt5P/PxKT/9fTu//n49f+mklf/f2AL/5Z9Nv+ZgDz/gmMP/5mBPP/v6+H/ +/v7+//7+/v/+/v7//v7+//7+/v+WfTj/va2B/6KMUP/+/v7//v7+/+/r4f/Uyq3/0cap/+jj1P/+ +/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/lXw3/8Cxhv+DZhT/1cuv//39/f/+/v7///////7+ +/v/+/v7//v7+/+LbyP+eh0f/6eXX/////v/+/v7//////+7r4P/Lv53/yLuX/4hsHP+PdCj/taJx +/8i7lv/JvZn/uql6/5d+OP+CZBD/vKyA//v7+f/k3sz/p5JY/9HHqP/49/T//v7+///////6+vf/ +1Muv/7Sib/+jjU//oYtM/6+cZ//NwaD/9vTu//7+/v/+/v7/nIVF/+Haxf+QdSv/iGwc/7Ceaf/y +7+f//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/49/P/v7CF/4FiDv+Xfzr/ootO/+zo +3P+kj1P/gGIN/6mVW//Qxab/6uXY//f28f/49/P/7ure/9bMsf+yn2v/hWcV/5h/O//h2sb/9PLr +//39/f/+/v7//v7+/+nk1v+6qnz/l345/4BiDf98XAP/fFwD/35fCP+Sdy7/sqBt/+DYxP/+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/9/Xw//X07v/8/Pv//v7+//7+/v/+ +/v7//v7+//7+/v/+/v7//v7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAA/v7+//7+/v///////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v// +/////v7+//7+/v/+/v7//v7+//7+/v///////v7+//////////////////////////////////// +//////////////7+/v/+/v3//f38//z9/P/+/v3//v7+//////////////////////////////// +///////////////////////////////////////+/v7///////////////////////////////// +//////////////////7///7+/v/+/v7/7+zi/6yYYf+GaBf/gGIM/5mBPf/Yz7T//v7+//7+/v// +/////////////////////////////////////////////////////////////////////v7+//7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//f7+/+7r4P+JbR//fFsC/31cBP99XQX/fFsD +/3xcBf/JvZr//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ +/v7+//7+/v/+/v7//v7+///////+/v7//v7+//7+/v///////v7+//7+/v/+/v7/qJRb/3xbA/+a +gT7/6OTV//Ty6/+9roL/e1wE/4FjEf/08en//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v///////v7+//////////////////////////////////////////////7/ +//v79/+BZBT/fF0H/+vn2//+/v7//v7+//3+/f+bhEP/fFsD/9DGqf/+/v7//v7+//////////// +/////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+ +/v7//v7+//7+/v/+/v7/+fjz/3xeCv9+Xwz/+fjx//7+/v/+/v7//v7+/6mWX/98WwP/yb2b//7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ +//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/fz/kHcw/3tbA//Hu5f//f79//3+/f/v6+D/ +hWgY/3tbBP/h28n//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ +/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/Ow6L/e1wE/31d +B/+ljlL/sJ1o/4dqGf97XAL/nYZH//7+/P/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7///// +//7+/v/+/v7///////7+/v/+/v7///////////////////////////////////////////////// +/v7+//39/f/AsYj/f2AK/3tbA/97XAP/e1wD/5uEQ//z8Oj//v7+//////////////////////// +/////v7+/////////////////////////////////////////////v7+//////////////////// +///////////////////+/////v7+//7+/v/u6+D/yr6c/8S3kP/e18H//f38//7+/v///v7///// +//////////////////////////////////////////////////////////////////7+/v/+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ +/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/w7OP/+ffz//7+/v/+/v7//v7+ +//7+/v/+/v7//v7+//7+/v/+/v7//v79/+zo3f/8/Pv//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v////////////7+/v/////////////////+/v7/5eDP/35fCf+L +biL/z8Sk//r69//+/v7//v7+//7+/v/+/v7//P79/+Xfz/+ijE//e1wE/7amdv/9/v7//v7+//// +//////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+ +//7+/v/r59r/hGYV/3tbA/98WwP/hmoZ/6eSV/+6qnv/va2C/7Ceaf+TejH/fFwF/3xbA/98XAT/ +wbOL//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//Pz7/8i7l/+c +hEP/o41Q/9vUvf/9/f3//f79//7+/v/u6+H/rZpj/4BgC/97XAP/fFsC/3xcA/98WwL/fFsD/3xb +A/97XAT/lnw2/9jPtf/+/v3//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ +//7+/v+/sYj/e1wD/4psHf+CZRH/fl4K/+Daxv/+/v7//v7+//7+/v/+/v3/8vDn/8zBn/+xnmr/ +ooxO/6CISf+plVz/wLKI/+Pezf/9/fz//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////+ +/v7//v7+//7+/v/+/v7//v7+/4pvIv+SejP/+/r3/+zp3P99Xgn/rZtm//7+/v////////7///7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v///////v7+///////+/v7//v7+ +///////////////////////+/v7/////////////////iW0f/5V8N//7/Pn/8Ozi/31fC/+YgT7/ ++fj0//7+/f/+/v7//v7+///////////////////////////////////////////////////////+ +/v7//f79/9fOtf+qlmD/6+fZ//7+/v////////////////////////////////+7rID/fFsE/41z +J/+GaRf/e1sD/3tcAv+Ncib/z8Wl//z7+f/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ +//7+/v/+/v7//v79/+fh0f+lkFP/fFwE/3xbA/+9roT//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ +/v7+//z8+v/Cs4v/lX03/5yEQ/+1pHL/gGIO/3xcA/97XAP/i28i/7moef/g2MP/+Pfz//7+/v/+ +/v7//v7+//7+/v/8/Pv/6+bZ/8m8mP+dhUP/fF0G/3xbA/98XAP/ooxQ//Pw6f/+/v7//v7+//z8 ++v/Z0bj/zcKi/+/s4v/+/v7//v7+//7+/v/9/v7//f7+//3+/v/t6d7/rJlh/35fCf98WwP/e1sD +/3xcA/9/YAr/jXEj/5d+N/+YgDr/kXct/4NlEv97XAT/fFwD/3xbA/97WwP/lHs1/9bNsv/9/fz/ +/v7+//7+/v/5+PT/m4RE/3tbBP97WwP/gGIO/9fOtf/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ +/v7/7+zi/8CxiP+Wfjj/fl8I/3tbA/98WwP/e1wC/3tbA/98WwP/fFsD/3xcA/+LbiH/r5xn/97W +wP/8/fv//v7+//7+/v/+/v7//v7+/8e8mf97XAP/uKd4/9nQt/+JbSD/i3Aj//X07v/w7eT//v7+ +//7+/v/+/v7//v7+//7+/v/+/v7//v7+//3+/f/19O7/4NnE/87EpP/GuJT/xLeQ/8q+nP/Z0Lb/ +7erf//z8+//+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/tKNz/3lbBf/28+n//f7+/66cZ/97 +XAP/jXIm/39gCv+9r4T/+fn2//3+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v39/93Vvv+McSb/e1wD +/6SPVP/CtYz/gmUS/5R6NP+Zgj7/elsD/3xbA/+Ncyn/0MWn//v7+f/9/v7//v7+//7+/v////// +///////////////////////////////////////////////////////+/v/9/v7//v7+/+fi0v+l +kFb/fF0F/3tbAv+AYAv/fFwF/3tbA/+LbyL/5eDP//r69v+7rID/f2EL/3xbA/98XAP/jHEk/7+x +h//t6d3//v7+//7+/v/+/v7//v7+//////////////////////////////////7+/v/9/v7/+Pfz +/9LIqv+giUn/fV0F/3tbA/97WwP/nYdG/+vm2f/w7OL/5N/O//v6+P/+/v7//v7+//7+/v/t6N3/ +q5hg/35fCP98WwP/fFwD/3xcBP+SeC//sqBt/83Anv/g2MT/7end//Px6v/08uv/8O3j/+Xgzv/W +yq7/va2C/5+ISP+BYw7/e1sD/3tbA/98WwP/lHs0/9XMsf/9/f3//v7+//7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v/+/v7/7uvg/7uqff+McCL/fFsD/3tbA/98XAP/e1wD/3tcA/98XAP/fF0E +/3xdBf98XAT/e1sD/3tbA/97WwP/e1wD/3xcAv+BYg3/qJJY/9vTu//9/fz//v7+//7+/v/+/v7/ +/v7+//7+/v///////v7+///////////////////////+/v7//v79//z9/P/k3s3/wrOK/6WPU/+N +cib/fl4I/3xcA/97WwP/e1wC/3tcAv98XAP/hmkY/5qCP/+2pHT/1syy//f28f/+/v7///////// +/////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ +//7+/v/+/v7//f79//7+/f/7+/r/8u/n/+zo2v/r5tn/7uvi//j38//9/f3//v7+//7+/v/+/v7/ +/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ +/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ +/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ +/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAA diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index a2385992..4f79c38e 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -185,6 +185,7 @@ void AmsWebServer::githubSvg() { void AmsWebServer::faviconIco() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /favicon.ico over http...\n"); + notFound(); //TODO } @@ -271,12 +272,22 @@ void AmsWebServer::sysinfoJson() { ESP.restart(); #endif performRestart = false; + } else { + time_t now = time(nullptr); + if(now < BUILD_EPOCH && server.hasArg(F("t"))) { + time_t clientTime = server.arg(F("t")).toInt(); + if(clientTime > BUILD_EPOCH) { + timeval tv { clientTime, 0}; + settimeofday(&tv, nullptr); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("Internal clock synchronized with client\n"); + } + } } } void AmsWebServer::dataJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /data.json over http...\n"); - uint64_t now = millis64(); + uint64_t millis = millis64(); if(!checkSecurity(2)) return; @@ -311,11 +322,11 @@ void AmsWebServer::dataJson() { uint8_t hanStatus; if(meterState->getLastError() < 0) { hanStatus = 3; - } else if((meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) && now < 15000) { + } else if((meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) && millis < 15000) { hanStatus = 0; - } else if(now - meterState->getLastUpdateMillis() < 15000) { + } else if(millis - meterState->getLastUpdateMillis() < 15000) { hanStatus = 1; - } else if(now - meterState->getLastUpdateMillis() < 30000) { + } else if(millis - meterState->getLastUpdateMillis() < 30000) { hanStatus = 2; } else { hanStatus = 3; @@ -351,6 +362,8 @@ void AmsWebServer::dataJson() { peaks += String(ea->getPeak(i).value / 100.0); } + time_t now = time(nullptr); + snprintf_P(buf, BufferSize, DATA_JSON, maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr, meterConfig->productionCapacity, @@ -376,7 +389,7 @@ void AmsWebServer::dataJson() { vcc, rssi, hw->getTemperature(), - (uint32_t) (now / 1000), + (uint32_t) (millis / 1000), ESP.getFreeHeap(), espStatus, hanStatus, @@ -404,7 +417,7 @@ void AmsWebServer::dataJson() { priceRegion.c_str(), meterState->getLastError(), eapi == NULL ? 0 : eapi->getLastError(), - (uint32_t) time(nullptr) + (uint32_t) now ); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); @@ -786,7 +799,8 @@ void AmsWebServer::configurationJson() { wifiConfig.ssid, strlen(wifiConfig.psk) > 0 ? "***" : "", wifiConfig.power / 10.0, - wifiConfig.sleep + wifiConfig.sleep, + wifiConfig.autoreboot ? "true" : "false" ); server.sendContent(buf); snprintf_P(buf, BufferSize, CONF_NET_JSON, @@ -1081,6 +1095,7 @@ void AmsWebServer::handleSave() { } wifi.power = server.arg(F("ww")).toFloat() * 10; wifi.sleep = server.arg(F("wz")).toInt(); + wifi.autoreboot = server.hasArg(F("wa")) && server.arg(F("wa")) == F("true"); config->setWiFiConfig(wifi); if(server.hasArg(F("nm")) && server.arg(F("nm")) == "static") { diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index a2d11865..3cd38730 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -1016,8 +1016,14 @@ void WiFi_connect() { lastWifiRetry = millis(); if (WiFi.status() != WL_CONNECTED) { + WiFiConfig wifi; + if(!config.getWiFiConfig(wifi) || strlen(wifi.ssid) == 0) { + swapWifiMode(); + return; + } + if(WiFi.getMode() != WIFI_OFF) { - if(wifiReconnectCount > 3) { + if(wifiReconnectCount > 3 && wifi.autoreboot) { ESP.restart(); return; } @@ -1056,12 +1062,6 @@ void WiFi_connect() { } wifiTimeout = WIFI_CONNECTION_TIMEOUT; - WiFiConfig wifi; - if(!config.getWiFiConfig(wifi) || strlen(wifi.ssid) == 0) { - swapWifiMode(); - return; - } - if (Debug.isActive(RemoteDebug::INFO)) debugI("Connecting to WiFi network: %s", wifi.ssid); wifiReconnectCount++; From 312972f77d814af8f1a6f5b5ac5b4cad9b3f8743 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 9 Dec 2022 20:26:48 +0100 Subject: [PATCH 33/66] Some improvements to v2.2 --- lib/SvelteUi/json/favicon.base64 | 96 -------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 lib/SvelteUi/json/favicon.base64 diff --git a/lib/SvelteUi/json/favicon.base64 b/lib/SvelteUi/json/favicon.base64 deleted file mode 100644 index c9f90807..00000000 --- a/lib/SvelteUi/json/favicon.base64 +++ /dev/null @@ -1,96 +0,0 @@ -AAABAAIAEBAAAAEAIABoBAAAJgAAACAgAAABACAAqBAAAI4EAAAoAAAAEAAAACAAAAABACAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAA/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////////////////////+/v7/2dG4/4tuIP+E -ZxT/x7mU//7+/v///////////////////////////////////////////////////////v78/4hs -Hv/b07v/6+fa/4VoF//w7eT//v7+//////////////////////////////////////////////// -//39+/+BZBL/7+zh//r69/+JbSD/6eXY//7+/v////////////////////////////////////// -///////////+/v7/wbOL/4dqGf+LcCL/qpVd//7+/v/+/v7////////////////////////////+ -/v7//v7+//7+/v/+/v7//v7+//7+/v/t6d7/6OLT//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v/+/v7/+Pfy/7ysgP/x7ub//v7+//7+/v/39vL/wrOL/+vn2//+/v7//v7+ -//7+/v/+/v7//v7+//Dt5P/PxKT/9fTu//n49f+mklf/f2AL/5Z9Nv+ZgDz/gmMP/5mBPP/v6+H/ -/v7+//7+/v/+/v7//v7+//7+/v+WfTj/va2B/6KMUP/+/v7//v7+/+/r4f/Uyq3/0cap/+jj1P/+ -/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/lXw3/8Cxhv+DZhT/1cuv//39/f/+/v7///////7+ -/v/+/v7//v7+/+LbyP+eh0f/6eXX/////v/+/v7//////+7r4P/Lv53/yLuX/4hsHP+PdCj/taJx -/8i7lv/JvZn/uql6/5d+OP+CZBD/vKyA//v7+f/k3sz/p5JY/9HHqP/49/T//v7+///////6+vf/ -1Muv/7Sib/+jjU//oYtM/6+cZ//NwaD/9vTu//7+/v/+/v7/nIVF/+Haxf+QdSv/iGwc/7Ceaf/y -7+f//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/49/P/v7CF/4FiDv+Xfzr/ootO/+zo -3P+kj1P/gGIN/6mVW//Qxab/6uXY//f28f/49/P/7ure/9bMsf+yn2v/hWcV/5h/O//h2sb/9PLr -//39/f/+/v7//v7+/+nk1v+6qnz/l345/4BiDf98XAP/fFwD/35fCP+Sdy7/sqBt/+DYxP/+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/f3/9/Xw//X07v/8/Pv//v7+//7+/v/+ -/v7//v7+//7+/v/+/v7//v7+/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAA/v7+//7+/v///////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v// -/////v7+//7+/v/+/v7//v7+//7+/v///////v7+//////////////////////////////////// -//////////////7+/v/+/v3//f38//z9/P/+/v3//v7+//////////////////////////////// -///////////////////////////////////////+/v7///////////////////////////////// -//////////////////7///7+/v/+/v7/7+zi/6yYYf+GaBf/gGIM/5mBPf/Yz7T//v7+//7+/v// -/////////////////////////////////////////////////////////////////////v7+//7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//f7+/+7r4P+JbR//fFsC/31cBP99XQX/fFsD -/3xcBf/JvZr//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ -/v7+//7+/v/+/v7//v7+///////+/v7//v7+//7+/v///////v7+//7+/v/+/v7/qJRb/3xbA/+a -gT7/6OTV//Ty6/+9roL/e1wE/4FjEf/08en//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v///////v7+//////////////////////////////////////////////7/ -//v79/+BZBT/fF0H/+vn2//+/v7//v7+//3+/f+bhEP/fFsD/9DGqf/+/v7//v7+//////////// -/////////////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+ -/v7//v7+//7+/v/+/v7/+fjz/3xeCv9+Xwz/+fjx//7+/v/+/v7//v7+/6mWX/98WwP/yb2b//7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ -//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/9/fz/kHcw/3tbA//Hu5f//f79//3+/f/v6+D/ -hWgY/3tbBP/h28n//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ -/v7//v7+//7+/v/+/v7///////7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/Ow6L/e1wE/31d -B/+ljlL/sJ1o/4dqGf97XAL/nYZH//7+/P/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7///// -//7+/v/+/v7///////7+/v/+/v7///////////////////////////////////////////////// -/v7+//39/f/AsYj/f2AK/3tbA/97XAP/e1wD/5uEQ//z8Oj//v7+//////////////////////// -/////v7+/////////////////////////////////////////////v7+//////////////////// -///////////////////+/////v7+//7+/v/u6+D/yr6c/8S3kP/e18H//f38//7+/v///v7///// -//////////////////////////////////////////////////////////////////7+/v/+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ -/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/w7OP/+ffz//7+/v/+/v7//v7+ -//7+/v/+/v7//v7+//7+/v/+/v7//v79/+zo3f/8/Pv//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v////////////7+/v/////////////////+/v7/5eDP/35fCf+L -biL/z8Sk//r69//+/v7//v7+//7+/v/+/v7//P79/+Xfz/+ijE//e1wE/7amdv/9/v7//v7+//// -//////////////////////////////////////////////7+/v/+/v7//v7+//7+/v/+/v7//v7+ -//7+/v/r59r/hGYV/3tbA/98WwP/hmoZ/6eSV/+6qnv/va2C/7Ceaf+TejH/fFwF/3xbA/98XAT/ -wbOL//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//Pz7/8i7l/+c -hEP/o41Q/9vUvf/9/f3//f79//7+/v/u6+H/rZpj/4BgC/97XAP/fFsC/3xcA/98WwL/fFsD/3xb -A/97XAT/lnw2/9jPtf/+/v3//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ -//7+/v+/sYj/e1wD/4psHf+CZRH/fl4K/+Daxv/+/v7//v7+//7+/v/+/v3/8vDn/8zBn/+xnmr/ -ooxO/6CISf+plVz/wLKI/+Pezf/9/fz//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+///////+ -/v7//v7+//7+/v/+/v7//v7+/4pvIv+SejP/+/r3/+zp3P99Xgn/rZtm//7+/v////////7///7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v///////v7+///////+/v7//v7+ -///////////////////////+/v7/////////////////iW0f/5V8N//7/Pn/8Ozi/31fC/+YgT7/ -+fj0//7+/f/+/v7//v7+///////////////////////////////////////////////////////+ -/v7//f79/9fOtf+qlmD/6+fZ//7+/v////////////////////////////////+7rID/fFsE/41z -J/+GaRf/e1sD/3tcAv+Ncib/z8Wl//z7+f/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ -//7+/v/+/v7//v79/+fh0f+lkFP/fFwE/3xbA/+9roT//v7+//7+/v/+/v7//v7+//7+/v/+/v7/ -/v7+//z8+v/Cs4v/lX03/5yEQ/+1pHL/gGIO/3xcA/97XAP/i28i/7moef/g2MP/+Pfz//7+/v/+ -/v7//v7+//7+/v/8/Pv/6+bZ/8m8mP+dhUP/fF0G/3xbA/98XAP/ooxQ//Pw6f/+/v7//v7+//z8 -+v/Z0bj/zcKi/+/s4v/+/v7//v7+//7+/v/9/v7//f7+//3+/v/t6d7/rJlh/35fCf98WwP/e1sD -/3xcA/9/YAr/jXEj/5d+N/+YgDr/kXct/4NlEv97XAT/fFwD/3xbA/97WwP/lHs1/9bNsv/9/fz/ -/v7+//7+/v/5+PT/m4RE/3tbBP97WwP/gGIO/9fOtf/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ -/v7/7+zi/8CxiP+Wfjj/fl8I/3tbA/98WwP/e1wC/3tbA/98WwP/fFsD/3xcA/+LbiH/r5xn/97W -wP/8/fv//v7+//7+/v/+/v7//v7+/8e8mf97XAP/uKd4/9nQt/+JbSD/i3Aj//X07v/w7eT//v7+ -//7+/v/+/v7//v7+//7+/v/+/v7//v7+//3+/f/19O7/4NnE/87EpP/GuJT/xLeQ/8q+nP/Z0Lb/ -7erf//z8+//+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7/tKNz/3lbBf/28+n//f7+/66cZ/97 -XAP/jXIm/39gCv+9r4T/+fn2//3+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v39/93Vvv+McSb/e1wD -/6SPVP/CtYz/gmUS/5R6NP+Zgj7/elsD/3xbA/+Ncyn/0MWn//v7+f/9/v7//v7+//7+/v////// -///////////////////////////////////////////////////////+/v/9/v7//v7+/+fi0v+l -kFb/fF0F/3tbAv+AYAv/fFwF/3tbA/+LbyL/5eDP//r69v+7rID/f2EL/3xbA/98XAP/jHEk/7+x -h//t6d3//v7+//7+/v/+/v7//v7+//////////////////////////////////7+/v/9/v7/+Pfz -/9LIqv+giUn/fV0F/3tbA/97WwP/nYdG/+vm2f/w7OL/5N/O//v6+P/+/v7//v7+//7+/v/t6N3/ -q5hg/35fCP98WwP/fFwD/3xcBP+SeC//sqBt/83Anv/g2MT/7end//Px6v/08uv/8O3j/+Xgzv/W -yq7/va2C/5+ISP+BYw7/e1sD/3tbA/98WwP/lHs0/9XMsf/9/f3//v7+//7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v/+/v7/7uvg/7uqff+McCL/fFsD/3tbA/98XAP/e1wD/3tcA/98XAP/fF0E -/3xdBf98XAT/e1sD/3tbA/97WwP/e1wD/3xcAv+BYg3/qJJY/9vTu//9/fz//v7+//7+/v/+/v7/ -/v7+//7+/v///////v7+///////////////////////+/v7//v79//z9/P/k3s3/wrOK/6WPU/+N -cib/fl4I/3xcA/97WwP/e1wC/3tcAv98XAP/hmkY/5qCP/+2pHT/1syy//f28f/+/v7///////// -/////////////////////////////////////////v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ -//7+/v/+/v7//f79//7+/f/7+/r/8u/n/+zo2v/r5tn/7uvi//j38//9/f3//v7+//7+/v/+/v7/ -/v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+ -/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+ -/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+ -/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAA From c4eaf8184b760485b7643aad365d01fa3ac4c492 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 10 Dec 2022 09:27:18 +0100 Subject: [PATCH 34/66] Check if authenticated to show upgrade links and config up/download --- lib/SvelteUi/app/src/App.svelte | 2 +- lib/SvelteUi/app/src/lib/Header.svelte | 6 +++- lib/SvelteUi/app/src/lib/StatusPage.svelte | 32 ++++++++++++---------- lib/SvelteUi/include/AmsWebServer.h | 2 +- lib/SvelteUi/json/data.json | 3 +- lib/SvelteUi/json/sysinfo.json | 3 +- lib/SvelteUi/src/AmsWebServer.cpp | 12 ++++---- 7 files changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 19b4d9c9..785b1688 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -39,7 +39,7 @@ - + diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index fd3d2f53..85466def 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -87,7 +87,11 @@
{#if sysinfo.fwconsent === 1 && nextVersion}
- + {#if sysinfo.security == 0 || data.a} + + {:else} + New version: {nextVersion.tag_name} + {/if}
{/if}
diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index 66441c55..6091a676 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -6,6 +6,7 @@ import { Link } from 'svelte-navigator'; import Mask from './Mask.svelte'; + export let data; export let sysinfo; let nextVersion = {}; @@ -112,26 +113,27 @@ Installed version: {sysinfo.version}
{#if nextVersion} -
- Latest version: - {nextVersion.tag_name} - {#if sysinfo.fwconsent === 1 && nextVersion && nextVersion.tag_name} -
- +
+ Latest version: + {nextVersion.tag_name} + {#if (sysinfo.security == 0 || data.a) && sysinfo.fwconsent === 1 && nextVersion && nextVersion.tag_name} +
+ +
+ {/if} +
+ {#if sysinfo.fwconsent === 2} +
+
You have disabled one-click firmware upgrade, link to self-upgrade is disabled
{/if} -
- {#if sysinfo.fwconsent === 2} -
-
You have disabled one-click firmware upgrade, link to self-upgrade is disabled
-
{/if} - {/if} - {#if sysinfo.board == 2 || sysinfo.board == 4 || sysinfo.board == 7 } + {#if (sysinfo.security == 0 || data.a) && (sysinfo.board == 2 || sysinfo.board == 4 || sysinfo.board == 7) }
{boardtype(sysinfo.chip, sysinfo.board)} must be connected to an external power supply during firmware upgrade. Failure to do so may cause power-down during upload resulting in non-functioning unit.
{/if} + {#if sysinfo.security == 0 || data.a}
firmwareUploading=true}> @@ -143,7 +145,9 @@ {/if}
+ {/if}
+ {#if sysinfo.security == 0 || data.a}
Configuration
@@ -172,8 +176,8 @@ {/if}
-
+ {/if}
diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index fb747065..1a49ecfb 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -71,7 +71,7 @@ private: WebServer server; #endif - bool checkSecurity(byte level); + bool checkSecurity(byte level, bool send401 = true); void indexHtml(); void indexJs(); diff --git a/lib/SvelteUi/json/data.json b/lib/SvelteUi/json/data.json index 6b840e41..00d89d87 100644 --- a/lib/SvelteUi/json/data.json +++ b/lib/SvelteUi/json/data.json @@ -59,5 +59,6 @@ "pr" : "%s", "he" : %d, "ee" : %d, - "c" : %lu + "c" : %lu, + "a" : %s } \ No newline at end of file diff --git a/lib/SvelteUi/json/sysinfo.json b/lib/SvelteUi/json/sysinfo.json index 7844d7ee..77c61290 100644 --- a/lib/SvelteUi/json/sysinfo.json +++ b/lib/SvelteUi/json/sysinfo.json @@ -21,5 +21,6 @@ "mfg": %d, "model": "%s", "id": "%s" - } + }, + "security": %d } \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 4f79c38e..81b73f37 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -141,7 +141,7 @@ void AmsWebServer::loop() { } } -bool AmsWebServer::checkSecurity(byte level) { +bool AmsWebServer::checkSecurity(byte level, bool send401) { bool access = WiFi.getMode() == WIFI_AP || webConfig.security < level; if(!access && webConfig.security >= level && server.hasHeader("Authorization")) { String expectedAuth = String(webConfig.username) + ":" + String(webConfig.password); @@ -161,7 +161,7 @@ bool AmsWebServer::checkSecurity(byte level) { access = providedPwd.equals(expectedBase64); } - if(!access) { + if(!access && send401) { server.sendHeader(HEADER_AUTHENTICATE, AUTHENTICATE_BASIC); server.setContentLength(0); server.send(401, MIME_HTML, ""); @@ -247,7 +247,8 @@ void AmsWebServer::sysinfoJson() { #endif meterState->getMeterType(), meterState->getMeterModel().c_str(), - meterState->getMeterId().c_str() + meterState->getMeterId().c_str(), + webConfig.security ); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); @@ -417,7 +418,8 @@ void AmsWebServer::dataJson() { priceRegion.c_str(), meterState->getLastError(), eapi == NULL ? 0 : eapi->getLastError(), - (uint32_t) now + (uint32_t) now, + checkSecurity(1, false) ? "true" : "false" ); server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); @@ -1618,7 +1620,7 @@ void AmsWebServer::mqttKeyUpload() { void AmsWebServer::tariffJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /tariff.json over http...\n"); - if(!checkSecurity(1)) + if(!checkSecurity(2)) return; EnergyAccountingConfig* eac = ea->getConfig(); From 7ea4fe881cc192dca5cb33827cadaac00eac3f04 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 13 Dec 2022 21:05:42 +0100 Subject: [PATCH 35/66] HAN serial autodetect --- lib/AmsConfiguration/src/AmsConfiguration.cpp | 4 +- .../app/src/lib/ConfigurationPanel.svelte | 4 +- lib/SvelteUi/app/src/lib/Helpers.js | 3 ++ lib/SvelteUi/include/AmsWebServer.h | 2 +- lib/SvelteUi/src/AmsWebServer.cpp | 31 +++++-------- src/AmsToMqttBridge.ino | 46 ++++++++++++++++++- 6 files changed, 65 insertions(+), 25 deletions(-) diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 8edc4817..50b07ea1 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -218,8 +218,8 @@ bool AmsConfiguration::setMeterConfig(MeterConfig& config) { } void AmsConfiguration::clearMeter(MeterConfig& config) { - config.baud = 2400; - config.parity = 11; // 8E1 + config.baud = 0; + config.parity = 0; config.invert = false; config.distributionSystem = 0; config.mainFuse = 0; diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 1e423e1f..73971c5e 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -225,6 +225,7 @@ Serial configuration
- + diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index 6712ceae..eb313ce5 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -104,6 +104,9 @@ export function hanError(err) { case -51: return "Authentication failed"; case -52: return "Decryption failed"; case -53: return "Encryption key invalid"; + case 90: return "No HAN data received last 30s"; + case 98: return "Exception in code, debugging necessary"; + case 99: return "Autodetection failed"; } if(err < 0) return "Unspecified error "+err; return ""; diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index 1a49ecfb..b5714da5 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -60,7 +60,7 @@ private: bool performRestart = false; bool performUpgrade = false; bool rebootForUpgrade = false; - String priceRegion; + String priceRegion = ""; static const uint16_t BufferSize = 2048; char* buf; diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 81b73f37..ad410dba 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -273,16 +273,6 @@ void AmsWebServer::sysinfoJson() { ESP.restart(); #endif performRestart = false; - } else { - time_t now = time(nullptr); - if(now < BUILD_EPOCH && server.hasArg(F("t"))) { - time_t clientTime = server.arg(F("t")).toInt(); - if(clientTime > BUILD_EPOCH) { - timeval tv { clientTime, 0}; - settimeofday(&tv, nullptr); - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("Internal clock synchronized with client\n"); - } - } } } @@ -290,7 +280,7 @@ void AmsWebServer::dataJson() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /data.json over http...\n"); uint64_t millis = millis64(); - if(!checkSecurity(2)) + if(!checkSecurity(2, true)) return; float vcc = hw->getVcc(); @@ -1322,6 +1312,9 @@ void AmsWebServer::handleSave() { void AmsWebServer::reboot() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /reboot over http...\n"); + if(!checkSecurity(1)) + return; + server.send(200, MIME_JSON, "{\"reboot\":true}"); server.handleClient(); @@ -1407,13 +1400,13 @@ void AmsWebServer::upgrade() { void AmsWebServer::firmwareHtml() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Serving /firmware.html over http...")); + if(!checkSecurity(1)) + return; + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_CONTROL_NO_CACHE); server.sendHeader(HEADER_PRAGMA, PRAGMA_NO_CACHE); server.sendHeader(HEADER_EXPIRES, EXPIRES_OFF); - if(!checkSecurity(1)) - return; - server.setContentLength(FIRMWARE_HTML_LEN); server.send_P(200, MIME_HTML, FIRMWARE_HTML); } @@ -1979,15 +1972,15 @@ void AmsWebServer::configFileDownload() { EnergyAccountingConfig eac; config->getEnergyAccountingConfig(eac); EnergyAccountingData ead = ea->getData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %.2f %.2f %.2f %d %.2f %d %.2f %d %.2f %d %.2f %d %.2f"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("energyaccounting %d %d %.2f %d %d %.2f %d %d %d %.2f %d %.2f %d %.2f %d %.2f %d %.2f"), ead.version, ead.month, ead.costYesterday / 10.0, - ead.costThisMonth / 1.0, - ead.costLastMonth / 1.0, + ead.costThisMonth, + ead.costLastMonth, ead.incomeYesterday / 10.0, - ead.incomeThisMonth / 1.0, - ead.incomeLastMonth / 1.0, + ead.incomeThisMonth, + ead.incomeLastMonth, ead.peaks[0].day, ead.peaks[0].value / 100.0, ead.peaks[1].day, diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 3cd38730..74f40306 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -233,9 +233,9 @@ void setup() { break; } #if defined(ESP32) - Serial.begin(meterConfig.baud, serialConfig, -1, -1, meterConfig.invert); + Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud: , serialConfig, -1, -1, meterConfig.invert); #else - Serial.begin(meterConfig.baud, serialConfig, SERIAL_FULL, 1, meterConfig.invert); + Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud, serialConfig, SERIAL_FULL, 1, meterConfig.invert); #endif } @@ -404,6 +404,13 @@ unsigned long lastSysupdate = 0; unsigned long lastErrorBlink = 0; int lastError = 0; +bool meterAutodetect = false; +unsigned long meterAutodetectLastChange = 0; +uint8_t meterAutoIndex = 0; +uint32_t bauds[] = { 2400, 2400, 115200, 115200 }; +uint8_t parities[] = { 11, 3, 3, 3 }; +bool inverts[] = { false, false, false, true }; + void loop() { Debug.handle(); unsigned long now = millis(); @@ -593,6 +600,31 @@ void loop() { } } catch(const std::exception& e) { debugE("Exception in readHanPort (%s)", e.what()); + meterState.setLastError(98); + } + try { + if(meterState.getLastError() > 0) { + if(now - meterAutodetectLastChange > 15000 && (meterConfig.baud == 0 || meterConfig.parity == 0)) { + meterAutodetect = true; + meterAutoIndex++; // Default is to try the first one in setup() + debugI("Meter serial autodetect, swapping to: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false"); + if(meterAutoIndex >= 4) meterAutoIndex = 0; + setupHanPort(gpioConfig.hanPin, bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex]); + meterAutodetectLastChange = now; + } + } else if(meterAutodetect) { + meterAutoIndex--; // Last one worked, so lets use that + debugI("Meter serial autodetected, saving: %d, %d, %s", bauds[meterAutoIndex], parities[meterAutoIndex], inverts[meterAutoIndex] ? "true" : "false"); + meterAutodetect = false; + meterConfig.baud = bauds[meterAutoIndex]; + meterConfig.parity = parities[meterAutoIndex]; + meterConfig.invert = inverts[meterAutoIndex]; + config.setMeterConfig(meterConfig); + setupHanPort(gpioConfig.hanPin, meterConfig.baud, meterConfig.parity, meterConfig.invert); + } + } catch(const std::exception& e) { + debugE("Exception in meter autodetect (%s)", e.what()); + meterState.setLastError(99); } delay(1); // Needed for auto modem sleep @@ -606,6 +638,15 @@ void loop() { void setupHanPort(uint8_t pin, uint32_t baud, uint8_t parityOrdinal, bool invert) { if(Debug.isActive(RemoteDebug::INFO)) Debug.printf((char*) F("(setupHanPort) Setting up HAN on pin %d with baud %d and parity %d\n"), pin, baud, parityOrdinal); + if(baud == 0) { + baud = bauds[meterAutoIndex]; + parityOrdinal = parities[meterAutoIndex]; + invert = inverts[meterAutoIndex]; + } + if(parityOrdinal == 0) { + parityOrdinal = 3; // 8N1 + } + HardwareSerial *hwSerial = NULL; if(pin == 3 || pin == 113) { hwSerial = &Serial; @@ -723,6 +764,7 @@ void errorBlink() { if(lastErrorBlink - meterState.getLastUpdateMillis() > 30000) { debugW("No HAN data received last 30s, single blink"); hw.ledBlink(LED_RED, 1); // If no message received from AMS in 30 sec, blink once + if(meterState.getLastError() == 0) meterState.setLastError(90); return; } break; From 28a9d6746b5e7d4e69d8dd2ad7fc87262d8357ba Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 14 Dec 2022 18:15:46 +0100 Subject: [PATCH 36/66] Fixed discover when setting different hostname in setup --- lib/SvelteUi/app/src/App.svelte | 2 +- lib/SvelteUi/app/src/lib/Header.svelte | 2 +- lib/SvelteUi/app/src/lib/SetupPanel.svelte | 10 ++++++---- lib/SvelteUi/src/AmsWebServer.cpp | 4 ++-- src/AmsToMqttBridge.ino | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 785b1688..63d4d19f 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -64,6 +64,6 @@ {#if sysinfo.upgrading} {:else if sysinfo.booting} - + {/if}
diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index 85466def..1a701c58 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -58,7 +58,7 @@
- {#if data.he < 0} + {#if data.he < 0 || data.he > 0}
{ 'HAN: ' + hanError(data.he) }
{/if} {#if data.me < 0} diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte index dde0ed40..16984e66 100644 --- a/lib/SvelteUi/app/src/lib/SetupPanel.svelte +++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte @@ -41,11 +41,12 @@ async function handleSubmit(e) { loadingOrSaving = true; - const formData = new FormData(e.target) - const data = new URLSearchParams() + const formData = new FormData(e.target); + let hostname = sysinfo.hostname; + const data = new URLSearchParams(); for (let field of formData) { - const [key, value] = field - data.append(key, value) + const [key, value] = field; + if(key == 'sh') hostname = value; } const response = await fetch('/save', { @@ -56,6 +57,7 @@ loadingOrSaving = false; sysinfoStore.update(s => { + s.hostname = hostname; s.usrcfg = res.success; s.booting = res.reboot; setTimeout(scanForDevice, 5000); diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index ad410dba..47a17e18 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -311,9 +311,9 @@ void AmsWebServer::dataJson() { uint8_t hanStatus; - if(meterState->getLastError() < 0) { + if(meterState->getLastError() != 0) { hanStatus = 3; - } else if((meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) && millis < 15000) { + } else if((meterConfig->baud == 0 || meterState->getLastUpdateMillis() == 0) && millis < 30000) { hanStatus = 0; } else if(millis - meterState->getLastUpdateMillis() < 15000) { hanStatus = 1; diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 74f40306..dcbc65fb 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -233,7 +233,7 @@ void setup() { break; } #if defined(ESP32) - Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud: , serialConfig, -1, -1, meterConfig.invert); + Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud, serialConfig, -1, -1, meterConfig.invert); #else Serial.begin(meterConfig.baud == 0 ? 2400 : meterConfig.baud, serialConfig, SERIAL_FULL, 1, meterConfig.invert); #endif From 4e97554514c9aa0a6a7a547dc76a9fd2042240ec Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 14 Dec 2022 19:37:32 +0100 Subject: [PATCH 37/66] Some changes during testing --- lib/AmsDataStorage/src/AmsDataStorage.cpp | 26 ++++---- lib/ClassicUi/src/AmsWebServer.cpp | 8 +-- lib/EnergyAccounting/src/EnergyAccounting.cpp | 4 +- lib/EntsoePriceApi/src/EntsoeApi.cpp | 2 +- lib/SvelteUi/app/src/App.svelte | 2 +- .../app/src/lib/ConfigurationPanel.svelte | 2 +- lib/SvelteUi/src/AmsWebServer.cpp | 8 +-- src/AmsToMqttBridge.ino | 64 ++++++++++--------- 8 files changed, 60 insertions(+), 56 deletions(-) diff --git a/lib/AmsDataStorage/src/AmsDataStorage.cpp b/lib/AmsDataStorage/src/AmsDataStorage.cpp index 091eef04..5031f2e1 100644 --- a/lib/AmsDataStorage/src/AmsDataStorage.cpp +++ b/lib/AmsDataStorage/src/AmsDataStorage.cpp @@ -21,7 +21,7 @@ bool AmsDataStorage::update(AmsData* data) { } time_t now = time(nullptr); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Time is: %lld\n", (int64_t) now); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Time is: %lu\n", (int32_t) now); if(tz == NULL) { if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Timezone is missing\n"); return false; @@ -30,18 +30,18 @@ bool AmsDataStorage::update(AmsData* data) { if(data->getMeterTimestamp() > BUILD_EPOCH) { now = data->getMeterTimestamp(); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Using meter timestamp, which is: %lld\n", (int64_t) now); + debugger->printf("(AmsDataStorage) Using meter timestamp, which is: %lu\n", (int32_t) now); } } else if(data->getPackageTimestamp() > BUILD_EPOCH) { now = data->getPackageTimestamp(); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Using package timestamp, which is: %lld\n", (int64_t) now); + debugger->printf("(AmsDataStorage) Using package timestamp, which is: %lu\n", (int32_t) now); } } } if(now < BUILD_EPOCH) { if(debugger->isActive(RemoteDebug::VERBOSE)) { - debugger->printf("(AmsDataStorage) Invalid time: %lld\n", (int64_t) now); + debugger->printf("(AmsDataStorage) Invalid time: %lu\n", (int32_t) now); } return false; } @@ -63,7 +63,7 @@ bool AmsDataStorage::update(AmsData* data) { return true; } else { if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last day update: %lld\n", (int64_t) day.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last day update: %lu\n", (int32_t) day.lastMeterReadTime); } tmElements_t last; breakTime(day.lastMeterReadTime, last); @@ -86,7 +86,7 @@ bool AmsDataStorage::update(AmsData* data) { month.lastMeterReadTime = now; } else { if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last month update: %lld\n", (int64_t) month.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last month update: %lu\n", (int32_t) month.lastMeterReadTime); } tmElements_t last; breakTime(tz->toLocal(month.lastMeterReadTime), last); @@ -156,7 +156,7 @@ bool AmsDataStorage::update(AmsData* data) { setHourExport(last.Hour, exp); if(debugger->isActive(RemoteDebug::INFO)) { - debugger->printf("(AmsDataStorage) Estimated usage for hour %u: %.1f - %.1f (%lld)\n", last.Hour, imp, exp, (int64_t) cur); + debugger->printf("(AmsDataStorage) Estimated usage for hour %u: %.1f - %.1f (%lu)\n", last.Hour, imp, exp, (int32_t) cur); } day.activeImport += imp; @@ -199,7 +199,7 @@ bool AmsDataStorage::update(AmsData* data) { breakTime(tz->toLocal(month.lastMeterReadTime), last); month.lastMeterReadTime = month.lastMeterReadTime - (last.Hour * 3600) - (last.Minute * 60) - last.Second; if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last month read after resetting to midnight: %lld\n", (int64_t) month.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last month read after resetting to midnight: %lu\n", (int32_t) month.lastMeterReadTime); } float hrs = (now - month.lastMeterReadTime) / 3600.0; @@ -224,7 +224,7 @@ bool AmsDataStorage::update(AmsData* data) { setDayExport(last.Day, exp); if(debugger->isActive(RemoteDebug::INFO)) { - debugger->printf("(AmsDataStorage) Estimated usage for day %u: %.1f - %.1f (%lld)\n", last.Day, imp, exp, (int64_t) cur); + debugger->printf("(AmsDataStorage) Estimated usage for day %u: %.1f - %.1f (%lu)\n", last.Day, imp, exp, (int32_t) cur); } month.activeImport += imp; @@ -383,11 +383,11 @@ bool AmsDataStorage::isDayHappy() { tmElements_t tm, last; if(now < day.lastMeterReadTime) { - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Day %lld < %lld\n", (int64_t) now, (int64_t) day.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Day %lu < %lu\n", (int32_t) now, (int32_t) day.lastMeterReadTime); return false; } if(now-day.lastMeterReadTime > 3600) { - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Day %lld - %lld > 3600\n", (int64_t) now, (int64_t) day.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Day %lu - %lu > 3600\n", (int32_t) now, (int32_t) day.lastMeterReadTime); return false; } breakTime(tz->toLocal(now), tm); @@ -411,11 +411,11 @@ bool AmsDataStorage::isMonthHappy() { tmElements_t tm, last; if(now < month.lastMeterReadTime) { - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Month %lld < %lld\n", (int64_t) now, (int64_t) month.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Month %lu < %lu\n", (int32_t) now, (int32_t) month.lastMeterReadTime); return false; } if(now-month.lastMeterReadTime > 86400) { - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Month %lld - %lld > 3600\n", (int64_t) now, (int64_t) month.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Month %lu - %lu > 3600\n", (int32_t) now, (int32_t) month.lastMeterReadTime); return false; } breakTime(tz->toLocal(now), tm); diff --git a/lib/ClassicUi/src/AmsWebServer.cpp b/lib/ClassicUi/src/AmsWebServer.cpp index f7835a73..253f4029 100644 --- a/lib/ClassicUi/src/AmsWebServer.cpp +++ b/lib/ClassicUi/src/AmsWebServer.cpp @@ -2311,9 +2311,9 @@ void AmsWebServer::configFileDownload() { if(ds != NULL) { DayDataPoints day = ds->getDayData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), day.version, - (int64_t) day.lastMeterReadTime, + (int32_t) day.lastMeterReadTime, day.activeImport, ds->getHourImport(0), ds->getHourImport(1), @@ -2373,9 +2373,9 @@ void AmsWebServer::configFileDownload() { } MonthDataPoints month = ds->getMonthData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), month.version, - (int64_t) month.lastMeterReadTime, + (int32_t) month.lastMeterReadTime, month.activeImport, ds->getDayImport(1), ds->getDayImport(2), diff --git a/lib/EnergyAccounting/src/EnergyAccounting.cpp b/lib/EnergyAccounting/src/EnergyAccounting.cpp index 501fa490..50ac23a4 100644 --- a/lib/EnergyAccounting/src/EnergyAccounting.cpp +++ b/lib/EnergyAccounting/src/EnergyAccounting.cpp @@ -42,7 +42,7 @@ bool EnergyAccounting::update(AmsData* amsData) { if(!init) { currentHour = local.Hour; currentDay = local.Day; - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EnergyAccounting) Initializing data at %lld\n", (int64_t) now); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EnergyAccounting) Initializing data at %lu\n", (int32_t) now); if(!load()) { if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Unable to load existing data\n"); data = { 5, local.Month, @@ -65,7 +65,7 @@ bool EnergyAccounting::update(AmsData* amsData) { } if(!initPrice && eapi != NULL && eapi->getValueForHour(0) != ENTSOE_NO_VALUE) { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EnergyAccounting) Initializing prices at %lld\n", (int64_t) now); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EnergyAccounting) Initializing prices at %lu\n", (int32_t) now); calcDayCost(); } diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 3efe4d5f..ce939c9c 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -153,7 +153,7 @@ bool EntsoeApi::loop() { currentDay = tm.Day; return false; } else if(now > midnightMillis && currentDay != tm.Day) { - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Rotating price objects at %lld\n", t); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Rotating price objects at %lu\n", t); if(today != NULL) delete today; if(tomorrow != NULL) { today = tomorrow; diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 63d4d19f..785b1688 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -64,6 +64,6 @@ {#if sysinfo.upgrading} {:else if sysinfo.booting} - + {/if}
diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 73971c5e..7ccfe51d 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -195,7 +195,7 @@
{#if configuration.p.e && sysinfo.chip != 'esp8266'} -
+
{/if}
diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 47a17e18..8631a640 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -1830,9 +1830,9 @@ void AmsWebServer::configFileDownload() { if(ds != NULL) { DayDataPoints day = ds->getDayData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), day.version, - (int64_t) day.lastMeterReadTime, + (int32_t) day.lastMeterReadTime, day.activeImport, ds->getHourImport(0), ds->getHourImport(1), @@ -1892,9 +1892,9 @@ void AmsWebServer::configFileDownload() { } MonthDataPoints month = ds->getMonthData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lld %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), month.version, - (int64_t) month.lastMeterReadTime, + (int32_t) month.lastMeterReadTime, month.activeImport, ds->getDayImport(1), ds->getDayImport(2), diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index dcbc65fb..4fdcff06 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -381,6 +381,7 @@ void setup() { config.ackEnergyAccountingChange(); } ea.setup(&ds, eac); + ea.load(); ea.setEapi(eapi); ws.setup(&config, &gpioConfig, &meterConfig, &meterState, &ds, &ea); @@ -452,9 +453,39 @@ void loop() { wifiReconnectCount = 0; if(!wifiConnected) { wifiConnected = true; - + WiFiConfig wifi; if(config.getWiFiConfig(wifi)) { + #if defined(ESP32) + if(wifi.power >= 195) + WiFi.setTxPower(WIFI_POWER_19_5dBm); + else if(wifi.power >= 190) + WiFi.setTxPower(WIFI_POWER_19dBm); + else if(wifi.power >= 185) + WiFi.setTxPower(WIFI_POWER_18_5dBm); + else if(wifi.power >= 170) + WiFi.setTxPower(WIFI_POWER_17dBm); + else if(wifi.power >= 150) + WiFi.setTxPower(WIFI_POWER_15dBm); + else if(wifi.power >= 130) + WiFi.setTxPower(WIFI_POWER_13dBm); + else if(wifi.power >= 110) + WiFi.setTxPower(WIFI_POWER_11dBm); + else if(wifi.power >= 85) + WiFi.setTxPower(WIFI_POWER_8_5dBm); + else if(wifi.power >= 70) + WiFi.setTxPower(WIFI_POWER_7dBm); + else if(wifi.power >= 50) + WiFi.setTxPower(WIFI_POWER_5dBm); + else if(wifi.power >= 20) + WiFi.setTxPower(WIFI_POWER_2dBm); + else + WiFi.setTxPower(WIFI_POWER_MINUS_1dBm); + #elif defined(ESP8266) + WiFi.setOutputPower(wifi.power / 10.0); + #endif + + WebConfig web; if(config.getWebConfig(web) && web.security > 0) { Debug.setPassword(web.password); @@ -1114,34 +1145,7 @@ void WiFi_connect() { } #endif WiFi.mode(WIFI_STA); - #if defined(ESP32) - if(wifi.power >= 195) - WiFi.setTxPower(WIFI_POWER_19_5dBm); - else if(wifi.power >= 190) - WiFi.setTxPower(WIFI_POWER_19dBm); - else if(wifi.power >= 185) - WiFi.setTxPower(WIFI_POWER_18_5dBm); - else if(wifi.power >= 170) - WiFi.setTxPower(WIFI_POWER_17dBm); - else if(wifi.power >= 150) - WiFi.setTxPower(WIFI_POWER_15dBm); - else if(wifi.power >= 130) - WiFi.setTxPower(WIFI_POWER_13dBm); - else if(wifi.power >= 110) - WiFi.setTxPower(WIFI_POWER_11dBm); - else if(wifi.power >= 85) - WiFi.setTxPower(WIFI_POWER_8_5dBm); - else if(wifi.power >= 70) - WiFi.setTxPower(WIFI_POWER_7dBm); - else if(wifi.power >= 50) - WiFi.setTxPower(WIFI_POWER_5dBm); - else if(wifi.power >= 20) - WiFi.setTxPower(WIFI_POWER_2dBm); - else - WiFi.setTxPower(WIFI_POWER_MINUS_1dBm); - #elif defined(ESP8266) - WiFi.setOutputPower(wifi.power / 10.0); - #endif + if(strlen(wifi.ip) > 0) { IPAddress ip, gw, sn(255,255,255,0), dns1, dns2; ip.fromString(wifi.ip); @@ -1459,7 +1463,7 @@ void MQTT_connect() { #if defined(ESP8266) if(mqttSecureClient) { - debugD("Setting NTP time %lld for secure MQTT connection", epoch); + debugD("Setting NTP time %lu for secure MQTT connection", epoch); mqttSecureClient->setX509Time(epoch); } #endif From d49b7eac097dab9940eb62712807244dfe6056d5 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Mon, 19 Dec 2022 16:49:40 +0100 Subject: [PATCH 38/66] Minor change --- lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 7ccfe51d..01a83724 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -289,7 +289,7 @@ {#if configuration.m.m.e}
- Instant
+ Watt
@@ -301,7 +301,7 @@
- Acc.
+ kWh
From 4972b980ba5c403c1382e514d641c11a1c518a01 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Fri, 6 Jan 2023 14:34:07 +0100 Subject: [PATCH 39/66] Changes for v2.2 --- .../include/AmsConfiguration.h | 20 +- lib/AmsConfiguration/src/AmsConfiguration.cpp | 45 +++- lib/AmsDataStorage/include/AmsDataStorage.h | 33 ++- lib/AmsDataStorage/src/AmsDataStorage.cpp | 205 ++++++++++++++++-- .../include/HomeAssistantStatic.h | 16 +- .../src/HomeAssistantMqttHandler.cpp | 3 + lib/RawMqttHandler/src/RawMqttHandler.cpp | 2 + lib/SvelteUi/app/src/app.postcss | 3 +- lib/SvelteUi/app/src/lib/BarChart.svelte | 9 +- .../app/src/lib/ConfigurationPanel.svelte | 38 +++- .../app/src/lib/ConsentComponent.svelte | 2 +- .../app/src/lib/FileUploadComponent.svelte | 2 +- lib/SvelteUi/app/src/lib/SetupPanel.svelte | 2 +- lib/SvelteUi/app/src/lib/StatusPage.svelte | 6 +- lib/SvelteUi/app/src/lib/VendorPanel.svelte | 2 +- lib/SvelteUi/app/vite.config.js | 14 +- lib/SvelteUi/json/conf_domoticz.json | 7 + lib/SvelteUi/json/conf_gpio.json | 2 +- lib/SvelteUi/json/firmware.html | 2 +- lib/SvelteUi/src/AmsWebServer.cpp | 29 ++- src/AmsToMqttBridge.ino | 81 +++++-- 21 files changed, 426 insertions(+), 97 deletions(-) create mode 100644 lib/SvelteUi/json/conf_domoticz.json diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index cbbcb8f2..c66885ac 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -4,7 +4,7 @@ #include "Arduino.h" #define EEPROM_SIZE 1024*3 -#define EEPROM_CHECK_SUM 100 // Used to check if config is stored. Change if structure changes +#define EEPROM_CHECK_SUM 101 // Used to check if config is stored. Change if structure changes #define EEPROM_CLEARED_INDICATOR 0xFC #define EEPROM_CONFIG_ADDRESS 0 #define EEPROM_TEMP_CONFIG_ADDRESS 2048 @@ -95,6 +95,23 @@ struct WebConfig { }; // 129 struct MeterConfig { + uint32_t baud; + uint8_t parity; + bool invert; + uint8_t distributionSystem; + uint16_t mainFuse; + uint16_t productionCapacity; + uint8_t encryptionKey[16]; + uint8_t authenticationKey[16]; + uint32_t wattageMultiplier; + uint32_t voltageMultiplier; + uint32_t amperageMultiplier; + uint32_t accumulatedMultiplier; + uint8_t source; + uint8_t parser; +}; // 52 + +struct MeterConfig100 { uint32_t baud; uint8_t parity; bool invert; @@ -302,6 +319,7 @@ private: bool relocateConfig94(); // 2.1.0 bool relocateConfig95(); // 2.1.4 bool relocateConfig96(); // 2.1.14 + bool relocateConfig100(); // 2.2-dev void saveToFs(); bool loadFromFs(uint8_t version); diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index 50b07ea1..f88f7ea1 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -230,6 +230,8 @@ void AmsConfiguration::clearMeter(MeterConfig& config) { config.voltageMultiplier = 0; config.amperageMultiplier = 0; config.accumulatedMultiplier = 0; + config.source = 1; // Serial + config.parser = 0; // Auto } bool AmsConfiguration::isMeterChanged() { @@ -694,6 +696,14 @@ bool AmsConfiguration::hasConfig() { configVersion = 0; return false; } + case 100: + configVersion = -1; // Prevent loop + if(relocateConfig100()) { + configVersion = 101; + } else { + configVersion = 0; + return false; + } case EEPROM_CHECK_SUM: return true; default: @@ -848,9 +858,13 @@ bool AmsConfiguration::relocateConfig96() { SystemConfig sys; EEPROM.get(CONFIG_SYSTEM_START, sys); - #if defined(ESP8266) MeterConfig meter; EEPROM.get(CONFIG_METER_START, meter); + meter.source = 1; // Serial + meter.parser = 0; // Auto + EEPROM.put(CONFIG_METER_START, meter); + + #if defined(ESP8266) GpioConfig gpio; EEPROM.get(CONFIG_GPIO_START, gpio); @@ -912,6 +926,35 @@ bool AmsConfiguration::relocateConfig96() { return ret; } +bool AmsConfiguration::relocateConfig100() { + EEPROM.begin(EEPROM_SIZE); + + MeterConfig100 meter100; + EEPROM.get(CONFIG_METER_START, meter100); + MeterConfig meter; + meter.baud = meter100.baud; + meter.parity = meter100.parity; + meter.invert = meter100.invert; + meter.distributionSystem = meter100.distributionSystem; + meter.mainFuse = meter100.mainFuse; + meter.productionCapacity = meter100.productionCapacity; + memcpy(meter.encryptionKey, meter100.encryptionKey, 16); + memcpy(meter.authenticationKey, meter100.authenticationKey, 16); + meter.wattageMultiplier = meter100.wattageMultiplier; + meter.voltageMultiplier = meter100.voltageMultiplier; + meter.amperageMultiplier = meter100.amperageMultiplier; + meter.accumulatedMultiplier = meter100.accumulatedMultiplier; + meter.source = meter100.source; + meter.parser = meter100.parser; + + EEPROM.put(CONFIG_METER_START, meter); + + EEPROM.put(EEPROM_CONFIG_ADDRESS, 101); + bool ret = EEPROM.commit(); + EEPROM.end(); + return ret; +} + bool AmsConfiguration::save() { EEPROM.begin(EEPROM_SIZE); EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CHECK_SUM); diff --git a/lib/AmsDataStorage/include/AmsDataStorage.h b/lib/AmsDataStorage/include/AmsDataStorage.h index f542bc99..46e1bdb9 100644 --- a/lib/AmsDataStorage/include/AmsDataStorage.h +++ b/lib/AmsDataStorage/include/AmsDataStorage.h @@ -12,7 +12,8 @@ struct DayDataPoints { uint32_t activeImport; uint32_t activeExport; uint16_t hExport[24]; -}; // 112 bytes + uint8_t accuracy; +}; // 113 bytes struct MonthDataPoints { uint8_t version; @@ -21,17 +22,18 @@ struct MonthDataPoints { uint32_t activeImport; uint32_t activeExport; uint16_t dExport[31]; -}; // 141 bytes + uint8_t accuracy; +}; // 142 bytes class AmsDataStorage { public: AmsDataStorage(RemoteDebug*); void setTimezone(Timezone*); bool update(AmsData*); - int32_t getHourImport(uint8_t); - int32_t getHourExport(uint8_t); - int32_t getDayImport(uint8_t); - int32_t getDayExport(uint8_t); + uint32_t getHourImport(uint8_t); + uint32_t getHourExport(uint8_t); + uint32_t getDayImport(uint8_t); + uint32_t getDayExport(uint8_t); bool load(); bool save(); @@ -40,6 +42,11 @@ public: MonthDataPoints getMonthData(); bool setMonthData(MonthDataPoints&); + uint8_t getDayAccuracy(); + void setDayAccuracy(uint8_t); + uint8_t getMonthAccuracy(); + void setMonthAccuracy(uint8_t); + bool isHappy(); bool isDayHappy(); bool isMonthHappy(); @@ -50,19 +57,21 @@ private: 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10 }; MonthDataPoints month = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10 }; RemoteDebug* debugger; - void setHourImport(uint8_t, int32_t); - void setHourExport(uint8_t, int32_t); - void setDayImport(uint8_t, int32_t); - void setDayExport(uint8_t, int32_t); + void setHourImport(uint8_t, uint32_t); + void setHourExport(uint8_t, uint32_t); + void setDayImport(uint8_t, uint32_t); + void setDayExport(uint8_t, uint32_t); }; #endif diff --git a/lib/AmsDataStorage/src/AmsDataStorage.cpp b/lib/AmsDataStorage/src/AmsDataStorage.cpp index 5031f2e1..66c012e4 100644 --- a/lib/AmsDataStorage/src/AmsDataStorage.cpp +++ b/lib/AmsDataStorage/src/AmsDataStorage.cpp @@ -5,8 +5,10 @@ #include "version.h" AmsDataStorage::AmsDataStorage(RemoteDebug* debugger) { - day.version = 4; - month.version = 5; + day.version = 5; + day.accuracy = 1; + month.version = 6; + month.accuracy = 1; this->debugger = debugger; } @@ -237,44 +239,160 @@ bool AmsDataStorage::update(AmsData* data) { return ret; } -void AmsDataStorage::setHourImport(uint8_t hour, int32_t val) { +void AmsDataStorage::setHourImport(uint8_t hour, uint32_t val) { if(hour < 0 || hour > 24) return; - day.hImport[hour] = val / 10; + + uint8_t accuracy = day.accuracy; + uint32_t update = val / pow(10, accuracy); + while(update > UINT16_MAX) { + accuracy++; + update = val / pow(10, accuracy); + } + + if(accuracy != day.accuracy) { + setDayAccuracy(accuracy); + } + + day.hImport[hour] = update; + + uint32_t max = 0; + for(uint8_t i = 0; i < 24; i++) { + if(day.hImport[i] > max) + max = day.hImport[i]; + if(day.hExport[i] > max) + max = day.hExport[i]; + } + + while(max < UINT16_MAX/10 && accuracy > 0) { + accuracy--; + max = max*10; + } + + if(accuracy != day.accuracy) { + setDayAccuracy(accuracy); + } } -int32_t AmsDataStorage::getHourImport(uint8_t hour) { +uint32_t AmsDataStorage::getHourImport(uint8_t hour) { if(hour < 0 || hour > 24) return 0; - return day.hImport[hour] * 10; + return day.hImport[hour] * pow(10, day.accuracy); } -void AmsDataStorage::setHourExport(uint8_t hour, int32_t val) { +void AmsDataStorage::setHourExport(uint8_t hour, uint32_t val) { if(hour < 0 || hour > 24) return; - day.hExport[hour] = val / 10; + + uint8_t accuracy = day.accuracy; + uint32_t update = val / pow(10, accuracy); + while(update > UINT16_MAX) { + accuracy++; + update = val / pow(10, accuracy); + } + + if(accuracy != day.accuracy) { + setDayAccuracy(accuracy); + } + + day.hExport[hour] = update; + + uint32_t max = 0; + for(uint8_t i = 0; i < 24; i++) { + if(day.hImport[i] > max) + max = day.hImport[i]; + if(day.hExport[i] > max) + max = day.hExport[i]; + } + + while(max < UINT16_MAX/10 && accuracy > 0) { + accuracy--; + max = max*10; + } + + if(accuracy != day.accuracy) { + setDayAccuracy(accuracy); + } } -int32_t AmsDataStorage::getHourExport(uint8_t hour) { +uint32_t AmsDataStorage::getHourExport(uint8_t hour) { if(hour < 0 || hour > 24) return 0; - return day.hExport[hour] * 10; + return day.hExport[hour] * pow(10, day.accuracy); } -void AmsDataStorage::setDayImport(uint8_t day, int32_t val) { +void AmsDataStorage::setDayImport(uint8_t day, uint32_t val) { if(day < 1 || day > 31) return; - month.dImport[day-1] = val / 10; + + uint8_t accuracy = month.accuracy; + uint32_t update = val / pow(10, accuracy); + while(update > UINT16_MAX) { + accuracy++; + update = val / pow(10, accuracy); + } + + if(accuracy != month.accuracy) { + setMonthAccuracy(accuracy); + } + + month.dImport[day-1] = update; + + uint32_t max = 0; + for(uint8_t i = 0; i < 31; i++) { + if(month.dImport[i] > max) + max = month.dImport[i]; + if(month.dExport[i] > max) + max = month.dExport[i]; + } + + while(max < UINT16_MAX/10 && accuracy > 0) { + accuracy--; + max = max*10; + } + + if(accuracy != month.accuracy) { + setMonthAccuracy(accuracy); + } } -int32_t AmsDataStorage::getDayImport(uint8_t day) { +uint32_t AmsDataStorage::getDayImport(uint8_t day) { if(day < 1 || day > 31) return 0; - return (month.dImport[day-1] * 10); + return (month.dImport[day-1] * pow(10, month.accuracy)); } -void AmsDataStorage::setDayExport(uint8_t day, int32_t val) { +void AmsDataStorage::setDayExport(uint8_t day, uint32_t val) { if(day < 1 || day > 31) return; - month.dExport[day-1] = val / 10; + + uint8_t accuracy = month.accuracy; + uint32_t update = val / pow(10, accuracy); + while(update > UINT16_MAX) { + accuracy++; + update = val / pow(10, accuracy); + } + + if(accuracy != month.accuracy) { + setMonthAccuracy(accuracy); + } + + month.dExport[day-1] = update; + + uint32_t max = 0; + for(uint8_t i = 0; i < 31; i++) { + if(month.dImport[i] > max) + max = month.dImport[i]; + if(month.dExport[i] > max) + max = month.dExport[i]; + } + + while(max < UINT16_MAX/10 && accuracy > 0) { + accuracy--; + max = max*10; + } + + if(accuracy != month.accuracy) { + setMonthAccuracy(accuracy); + } } -int32_t AmsDataStorage::getDayExport(uint8_t day) { +uint32_t AmsDataStorage::getDayExport(uint8_t day) { if(day < 1 || day > 31) return 0; - return (month.dExport[day-1] * 10); + return (month.dExport[day-1] * pow(10, month.accuracy)); } bool AmsDataStorage::load() { @@ -348,31 +466,74 @@ MonthDataPoints AmsDataStorage::getMonthData() { } bool AmsDataStorage::setDayData(DayDataPoints& day) { - if(day.version == 4) { + if(day.version == 5) { this->day = day; return true; + } else if(day.version == 4) { + this->day = day; + this->day.accuracy = 1; + this->day.version = 5; + return true; } else if(day.version == 3) { this->day = day; for(uint8_t i = 0; i < 24; i++) this->day.hExport[i] = 0; - this->day.version = 4; + this->day.accuracy = 1; + this->day.version = 5; return true; } return false; } bool AmsDataStorage::setMonthData(MonthDataPoints& month) { - if(month.version == 5) { + if(month.version == 6) { this->month = month; return true; + } else if(month.version == 5) { + this->month = month; + this->month.accuracy = 1; + this->month.version = 6; + return true; } else if(month.version == 4) { this->month = month; for(uint8_t i = 0; i < 31; i++) this->month.dExport[i] = 0; - this->month.version = 5; + this->month.accuracy = 1; + this->month.version = 6; return true; } return false; } +uint8_t AmsDataStorage::getDayAccuracy() { + return day.accuracy; +} + +void AmsDataStorage::setDayAccuracy(uint8_t accuracy) { + if(day.accuracy != accuracy) { + uint16_t multiplier = pow(10, day.accuracy)/pow(10, accuracy); + for(uint8_t i = 0; i < 24; i++) { + day.hImport[i] = day.hImport[i] * multiplier; + day.hExport[i] = day.hExport[i] * multiplier; + } + day.accuracy = accuracy; + } +} + +uint8_t AmsDataStorage::getMonthAccuracy() { + return month.accuracy; +} + +void AmsDataStorage::setMonthAccuracy(uint8_t accuracy) { + if(month.accuracy != accuracy) { + uint16_t multiplier = pow(10, month.accuracy)/pow(10, accuracy); + for(uint8_t i = 0; i < 31; i++) { + month.dImport[i] = month.dImport[i] * multiplier; + month.dExport[i] = month.dExport[i] * multiplier; + } + month.accuracy = accuracy; + } + month.accuracy = accuracy; +} + bool AmsDataStorage::isHappy() { return isDayHappy() && isMonthHappy(); } diff --git a/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h b/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h index 8f781d6f..baf495d5 100644 --- a/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h +++ b/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h @@ -22,12 +22,12 @@ HomeAssistantSensor HA_SENSORS[HA_SENSOR_COUNT] PROGMEM = { {"L1 active import", "/power", "P1", "W", "power", "\"measurement\""}, {"L2 active import", "/power", "P2", "W", "power", "\"measurement\""}, {"L3 active import", "/power", "P3", "W", "power", "\"measurement\""}, - {"Reactive import", "/power", "Q", "VAr", "reactive_power", "\"measurement\""}, + {"Reactive import", "/power", "Q", "var", "reactive_power", "\"measurement\""}, {"Active export", "/power", "PO", "W", "power", "\"measurement\""}, {"L1 active export", "/power", "PO1", "W", "power", "\"measurement\""}, {"L2 active export", "/power", "PO2", "W", "power", "\"measurement\""}, {"L3 active export", "/power", "PO3", "W", "power", "\"measurement\""}, - {"Reactive export", "/power", "QO", "VAr", "reactive_power", "\"measurement\""}, + {"Reactive export", "/power", "QO", "var", "reactive_power", "\"measurement\""}, {"L1 current", "/power", "I1", "A", "current", "\"measurement\""}, {"L2 current", "/power", "I2", "A", "current", "\"measurement\""}, {"L3 current", "/power", "I3", "A", "current", "\"measurement\""}, @@ -36,12 +36,12 @@ HomeAssistantSensor HA_SENSORS[HA_SENSOR_COUNT] PROGMEM = { {"L3 voltage", "/power", "U3", "V", "voltage", "\"measurement\""}, {"Accumulated active import", "/energy", "tPI", "kWh", "energy", "\"total_increasing\""}, {"Accumulated active export", "/energy", "tPO", "kWh", "energy", "\"total_increasing\""}, - {"Accumulated reactive import","/energy", "tQI", "kVArh","energy", "\"total_increasing\""}, - {"Accumulated reactive export","/energy", "tQO", "kVArh","energy", "\"total_increasing\""}, - {"Power factor", "/power", "PF", "", "power_factor", "\"measurement\""}, - {"L1 power factor", "/power", "PF1", "", "power_factor", "\"measurement\""}, - {"L2 power factor", "/power", "PF2", "", "power_factor", "\"measurement\""}, - {"L3 power factor", "/power", "PF3", "", "power_factor", "\"measurement\""}, + {"Accumulated reactive import","/energy", "tQI", "kvarh","energy", "\"total_increasing\""}, + {"Accumulated reactive export","/energy", "tQO", "kvarh","energy", "\"total_increasing\""}, + {"Power factor", "/power", "PF", "%", "power_factor", "\"measurement\""}, + {"L1 power factor", "/power", "PF1", "%", "power_factor", "\"measurement\""}, + {"L2 power factor", "/power", "PF2", "%", "power_factor", "\"measurement\""}, + {"L3 power factor", "/power", "PF3", "%", "power_factor", "\"measurement\""}, {"Price current hour", "/prices", "prices['0']", "", "monetary", ""}, {"Price next hour", "/prices", "prices['1']", "", "monetary", ""}, {"Price in two hour", "/prices", "prices['2']", "", "monetary", ""}, diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 71253a6c..17066021 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -286,6 +286,9 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, EntsoeApi* eapi, Energ if(peaks >= peakCount) continue; peaks++; } + if(strncmp(sensor.path, "temp", 4) == 0) { + if(hw->getTemperature() < 0) continue; + } snprintf_P(json, BufferSize, HADISCOVER_JSON, sensor.name, topic.c_str(), sensor.topic, diff --git a/lib/RawMqttHandler/src/RawMqttHandler.cpp b/lib/RawMqttHandler/src/RawMqttHandler.cpp index 1767e3d9..ee8ae40c 100644 --- a/lib/RawMqttHandler/src/RawMqttHandler.cpp +++ b/lib/RawMqttHandler/src/RawMqttHandler.cpp @@ -92,6 +92,7 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin } mqtt->publish(topic + "/realtime/import/hour", String(ea->getUseThisHour(), 3)); mqtt->publish(topic + "/realtime/import/day", String(ea->getUseToday(), 2)); + mqtt->publish(topic + "/realtime/import/month", String(ea->getUseThisMonth(), 1)); uint8_t peakCount = ea->getConfig()->hours; if(peakCount > 5) peakCount = 5; for(uint8_t i = 1; i <= peakCount; i++) { @@ -101,6 +102,7 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin mqtt->publish(topic + "/realtime/import/monthmax", String(ea->getMonthMax(), 3), true, 0); mqtt->publish(topic + "/realtime/export/hour", String(ea->getProducedThisHour(), 3)); mqtt->publish(topic + "/realtime/export/day", String(ea->getProducedToday(), 2)); + mqtt->publish(topic + "/realtime/export/month", String(ea->getProducedThisMonth(), 1)); return true; } diff --git a/lib/SvelteUi/app/src/app.postcss b/lib/SvelteUi/app/src/app.postcss index a3e3dcf9..dace2220 100644 --- a/lib/SvelteUi/app/src/app.postcss +++ b/lib/SvelteUi/app/src/app.postcss @@ -63,7 +63,7 @@ } .pl-ov { position: absolute; - top: 28%; + top: 27%; left: 25%; width: 50%; text-align: center; @@ -76,6 +76,7 @@ color: grey; } .pl-sub { + padding-top: 10px; font-size: 1.0rem; } .pl-snt { diff --git a/lib/SvelteUi/app/src/lib/BarChart.svelte b/lib/SvelteUi/app/src/lib/BarChart.svelte index 8713a153..b6532b5a 100644 --- a/lib/SvelteUi/app/src/lib/BarChart.svelte +++ b/lib/SvelteUi/app/src/lib/BarChart.svelte @@ -19,8 +19,13 @@ return (i*barWidth)+config.padding.left; }; yScale = function(i) { - if(i > config.y.max) return heightAvailable; - let ret = heightAvailable-config.padding.bottom-((i-config.y.min)*yPerUnit); + let ret = 0; + if(i > config.y.max) + ret = config.padding.bottom; + else if(i < config.y.min) + ret = heightAvailable-config.padding.bottom; + else + ret = heightAvailable-config.padding.bottom-((i-config.y.min)*yPerUnit); return ret > heightAvailable || ret < 0.0 ? 0.0 : ret; }; }; diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 01a83724..a64f2afb 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -31,6 +31,13 @@ h: '', p: 1883, u: '', a: '', b: '', s: { e: false, c: false, r: true, k: false } }, + o: { + e: '', + c: '', + u1: '', + u2: '', + u3: '' + }, t: { t: [0,0,0,0,0,0,0,0,0,0], h: 1 }, @@ -120,7 +127,7 @@ } -
+
General @@ -257,14 +264,14 @@
Main fuse
Production
@@ -457,6 +464,31 @@
+ {#if configuration.q.m == 3} +
+ Domoticz + + +
+
+ Electricity IDX
+ +
+
+ Current IDX
+ +
+
+
+ Voltage IDX: L1, L2 & L3 +
+ + + +
+
+
+ {/if} {#if configuration.p.r.startsWith("10YNO") || configuration.p.r == '10Y1001A1001A48H'}
Tariff thresholds diff --git a/lib/SvelteUi/app/src/lib/ConsentComponent.svelte b/lib/SvelteUi/app/src/lib/ConsentComponent.svelte index 8bfa9007..3e8568d3 100644 --- a/lib/SvelteUi/app/src/lib/ConsentComponent.svelte +++ b/lib/SvelteUi/app/src/lib/ConsentComponent.svelte @@ -34,7 +34,7 @@
- +
Various permissions we need to do stuff:
diff --git a/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte b/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte index eee6c877..a47fbf24 100644 --- a/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte +++ b/lib/SvelteUi/app/src/lib/FileUploadComponent.svelte @@ -11,7 +11,7 @@
Upload {title}

Select a suitable file and click upload

- uploading=true}> + uploading=true} autocomplete="off">
diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte index 16984e66..250c7706 100644 --- a/lib/SvelteUi/app/src/lib/SetupPanel.svelte +++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte @@ -69,7 +69,7 @@
- + Setup
diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index 6091a676..02ea016d 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -135,7 +135,7 @@ {/if} {#if sysinfo.security == 0 || data.a}
- firmwareUploading=true}> + firmwareUploading=true} autocomplete="off"> {#if firmwareFiles.length == 0} @@ -150,7 +150,7 @@ {#if sysinfo.security == 0 || data.a}
Configuration - +
@@ -167,7 +167,7 @@ {/if} -
configUploading=true}> + configUploading=true} autocomplete="off"> {#if configFiles.length == 0} diff --git a/lib/SvelteUi/app/src/lib/VendorPanel.svelte b/lib/SvelteUi/app/src/lib/VendorPanel.svelte index 8740f27c..032927a5 100644 --- a/lib/SvelteUi/app/src/lib/VendorPanel.svelte +++ b/lib/SvelteUi/app/src/lib/VendorPanel.svelte @@ -35,7 +35,7 @@
- + Initial configuration
diff --git a/lib/SvelteUi/app/vite.config.js b/lib/SvelteUi/app/vite.config.js index 9bcb4a69..295482b8 100644 --- a/lib/SvelteUi/app/vite.config.js +++ b/lib/SvelteUi/app/vite.config.js @@ -17,14 +17,14 @@ export default defineConfig({ plugins: [svelte()], server: { proxy: { - "/data.json": "http://192.168.233.229", - "/energyprice.json": "http://192.168.233.229", - "/dayplot.json": "http://192.168.233.229", - "/monthplot.json": "http://192.168.233.229", - "/temperature.json": "http://192.168.233.229", - "/sysinfo.json": "http://192.168.233.229", + "/data.json": "https://ams2mqtt.no23.cc", + "/energyprice.json": "https://ams2mqtt.no23.cc", + "/dayplot.json": "https://ams2mqtt.no23.cc", + "/monthplot.json": "https://ams2mqtt.no23.cc", + "/temperature.json": "https://ams2mqtt.no23.cc", + "/sysinfo.json": "https://ams2mqtt.no23.cc", "/configuration.json": "http://192.168.233.229", - "/tariff.json": "http://192.168.233.229", + "/tariff.json": "https://ams2mqtt.no23.cc", "/save": "http://192.168.233.229", "/reboot": "http://192.168.233.229", "/configfile": "http://192.168.233.229", diff --git a/lib/SvelteUi/json/conf_domoticz.json b/lib/SvelteUi/json/conf_domoticz.json new file mode 100644 index 00000000..3c11d996 --- /dev/null +++ b/lib/SvelteUi/json/conf_domoticz.json @@ -0,0 +1,7 @@ +"o": { + "e" : %d, + "c" : %d, + "u1" : %d, + "u2" : %d, + "u3" : %d +} diff --git a/lib/SvelteUi/json/conf_gpio.json b/lib/SvelteUi/json/conf_gpio.json index 4cea40be..c887d2f3 100644 --- a/lib/SvelteUi/json/conf_gpio.json +++ b/lib/SvelteUi/json/conf_gpio.json @@ -25,4 +25,4 @@ }, "b": %.1f } -} +}, diff --git a/lib/SvelteUi/json/firmware.html b/lib/SvelteUi/json/firmware.html index b4e32ece..da27f421 100644 --- a/lib/SvelteUi/json/firmware.html +++ b/lib/SvelteUi/json/firmware.html @@ -1,5 +1,5 @@ - + diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 8631a640..1577cf09 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -25,6 +25,7 @@ #include "html/conf_thresholds_json.h" #include "html/conf_debug_json.h" #include "html/conf_gpio_json.h" +#include "html/conf_domoticz_json.h" #include "html/firmware_html.h" #include "version.h" @@ -727,6 +728,8 @@ void AmsWebServer::configurationJson() { config->getEntsoeConfig(entsoe); DebugConfig debugConfig; config->getDebugConfig(debugConfig); + DomoticzConfig domo; + config->getDomoticzConfig(domo); bool qsc = false; bool qsr = false; @@ -854,6 +857,14 @@ void AmsWebServer::configurationJson() { gpioConfig->vccBootLimit / 10.0 ); server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_DOMOTICZ_JSON, + domo.elidx, + domo.cl1idx, + domo.vl1idx, + domo.vl2idx, + domo.vl3idx + ); + server.sendContent(buf); server.sendContent("}"); } @@ -1141,14 +1152,14 @@ void AmsWebServer::handleSave() { config->setMqttConfig(mqtt); } - if(server.hasArg(F("dc")) && server.arg(F("dc")) == F("true")) { + if(server.hasArg(F("o")) && server.arg(F("o")) == F("true")) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received Domoticz config")); DomoticzConfig domo { - static_cast(server.arg(F("elidx")).toInt()), - static_cast(server.arg(F("vl1idx")).toInt()), - static_cast(server.arg(F("vl2idx")).toInt()), - static_cast(server.arg(F("vl3idx")).toInt()), - static_cast(server.arg(F("cl1idx")).toInt()) + static_cast(server.arg(F("oe")).toInt()), + static_cast(server.arg(F("ou1")).toInt()), + static_cast(server.arg(F("ou2")).toInt()), + static_cast(server.arg(F("ou3")).toInt()), + static_cast(server.arg(F("oc")).toInt()) }; config->setDomoticzConfig(domo); } @@ -1830,10 +1841,11 @@ void AmsWebServer::configFileDownload() { if(ds != NULL) { DayDataPoints day = ds->getDayData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("dayplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), day.version, (int32_t) day.lastMeterReadTime, day.activeImport, + day.accuracy, ds->getHourImport(0), ds->getHourImport(1), ds->getHourImport(2), @@ -1892,10 +1904,11 @@ void AmsWebServer::configFileDownload() { } MonthDataPoints month = ds->getMonthData(); - server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), + server.sendContent(buf, snprintf_P(buf, BufferSize, PSTR("monthplot %d %lu %lu %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"), month.version, (int32_t) month.lastMeterReadTime, month.activeImport, + month.accuracy, ds->getDayImport(1), ds->getDayImport(2), ds->getDayImport(3), diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index f2255c36..266abd7d 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -1724,20 +1724,38 @@ void configFileParse() { eac.hours = String(pch).toInt(); } else if(strncmp_P(buf, PSTR("dayplot "), 8) == 0) { int i = 0; - DayDataPoints day = { 4 }; // Use a version we know the multiplier of the data points + DayDataPoints day = { 0 }; char * pch = strtok (buf+8," "); while (pch != NULL) { int64_t val = String(pch).toInt(); - if(i == 1) { - day.lastMeterReadTime = val; - } else if(i == 2) { - day.activeImport = val; - } else if(i > 2 && i < 27) { - day.hImport[i-3] = val / 10; - } else if(i == 27) { - day.activeExport = val; - } else if(i > 27 && i < 52) { - day.hExport[i-28] = val / 10; + if(day.version < 5) { + if(i == 0) { + day.version = val; + } else if(i == 1) { + day.lastMeterReadTime = val; + } else if(i == 2) { + day.activeImport = val; + } else if(i > 2 && i < 27) { + day.hImport[i-3] = val / 10; + } else if(i == 27) { + day.activeExport = val; + } else if(i > 27 && i < 52) { + day.hExport[i-28] = val / 10; + } + } else { + if(i == 1) { + day.lastMeterReadTime = val; + } else if(i == 2) { + day.activeImport = val; + } else if(i == 3) { + day.accuracy = val; + } else if(i > 3 && i < 28) { + day.hImport[i-4] = val / pow(10, day.accuracy); + } else if(i == 28) { + day.activeExport = val; + } else if(i > 28 && i < 53) { + day.hExport[i-29] = val / pow(10, day.accuracy); + } } pch = strtok (NULL, " "); @@ -1747,22 +1765,39 @@ void configFileParse() { sDs = true; } else if(strncmp_P(buf, PSTR("monthplot "), 10) == 0) { int i = 0; - MonthDataPoints month = { 5 }; // Use a version we know the multiplier of the data points + MonthDataPoints month = { 0 }; char * pch = strtok (buf+10," "); while (pch != NULL) { int64_t val = String(pch).toInt(); - if(i == 1) { - month.lastMeterReadTime = val; - } else if(i == 2) { - month.activeImport = val; - } else if(i > 2 && i < 34) { - month.dImport[i-3] = val / 10; - } else if(i == 34) { - month.activeExport = val; - } else if(i > 34 && i < 66) { - month.dExport[i-35] = val / 10; + if(month.version < 6) { + if(i == 0) { + month.version = val; + } else if(i == 1) { + month.lastMeterReadTime = val; + } else if(i == 2) { + month.activeImport = val; + } else if(i > 2 && i < 34) { + month.dImport[i-3] = val / 10; + } else if(i == 34) { + month.activeExport = val; + } else if(i > 34 && i < 66) { + month.dExport[i-35] = val / 10; + } + } else { + if(i == 1) { + month.lastMeterReadTime = val; + } else if(i == 2) { + month.activeImport = val; + } else if(i == 3) { + month.accuracy = val; + } else if(i > 3 && i < 35) { + month.dImport[i-4] = val / pow(10, month.accuracy); + } else if(i == 35) { + month.activeExport = val; + } else if(i > 35 && i < 67) { + month.dExport[i-36] = val / pow(10, month.accuracy); + } } - pch = strtok (NULL, " "); i++; } From 870617f780a8302c734fcf2786423eedbba560d9 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 11 Jan 2023 20:41:27 +0100 Subject: [PATCH 40/66] More changes for v2.2 --- .../include/AmsConfiguration.h | 19 ++++ lib/AmsConfiguration/src/AmsConfiguration.cpp | 45 ++++++++- lib/EntsoePriceApi/include/EntsoeApi.h | 5 +- lib/EntsoePriceApi/src/EntsoeApi.cpp | 90 ++++++++--------- .../src/HomeAssistantMqttHandler.cpp | 2 +- lib/JsonMqttHandler/src/JsonMqttHandler.cpp | 2 +- lib/RawMqttHandler/src/RawMqttHandler.cpp | 2 +- lib/SvelteUi/app/src/App.svelte | 2 +- lib/SvelteUi/app/src/lib/AmpPlot.svelte | 6 +- lib/SvelteUi/app/src/lib/BarChart.svelte | 71 +++++++------- .../app/src/lib/ConfigurationPanel.svelte | 98 +++++++++++++++++++ lib/SvelteUi/app/src/lib/Dashboard.svelte | 23 +++-- lib/SvelteUi/app/src/lib/DataStores.js | 82 +++++++++++----- lib/SvelteUi/app/src/lib/Header.svelte | 4 +- lib/SvelteUi/app/src/lib/Helpers.js | 16 ++- lib/SvelteUi/app/src/lib/PricePlot.svelte | 2 - lib/SvelteUi/app/src/lib/SetupPanel.svelte | 1 + lib/SvelteUi/app/src/lib/StatusPage.svelte | 9 +- lib/SvelteUi/app/src/lib/Uptime.svelte | 38 +++---- lib/SvelteUi/app/src/lib/VoltPlot.svelte | 6 +- lib/SvelteUi/app/vite.config.js | 14 +-- lib/SvelteUi/json/conf_ui.json | 13 +++ lib/SvelteUi/json/sysinfo.json | 14 +++ lib/SvelteUi/src/AmsWebServer.cpp | 69 ++++++++++++- src/AmsToMqttBridge.ino | 54 +++++----- 25 files changed, 508 insertions(+), 179 deletions(-) create mode 100644 lib/SvelteUi/json/conf_ui.json diff --git a/lib/AmsConfiguration/include/AmsConfiguration.h b/lib/AmsConfiguration/include/AmsConfiguration.h index c66885ac..1980378f 100644 --- a/lib/AmsConfiguration/include/AmsConfiguration.h +++ b/lib/AmsConfiguration/include/AmsConfiguration.h @@ -11,6 +11,7 @@ #define CONFIG_SYSTEM_START 8 #define CONFIG_METER_START 32 +#define CONFIG_UI_START 248 #define CONFIG_GPIO_START 266 #define CONFIG_ENTSOE_START 290 #define CONFIG_WIFI_START 360 @@ -216,6 +217,20 @@ struct EnergyAccountingConfig { uint8_t hours; }; // 11 +struct UiConfig { + uint8_t showImport; + uint8_t showExport; + uint8_t showVoltage; + uint8_t showAmperage; + uint8_t showReactive; + uint8_t showRealtime; + uint8_t showPeaks; + uint8_t showPricePlot; + uint8_t showDayPlot; + uint8_t showMonthPlot; + uint8_t showTemperaturePlot; +}; // 11 + struct TempSensorConfig { uint8_t address[8]; char name[16]; @@ -292,6 +307,10 @@ public: bool isEnergyAccountingChanged(); void ackEnergyAccountingChange(); + bool getUiConfig(UiConfig&); + bool setUiConfig(UiConfig&); + void clearUiConfig(UiConfig&); + void loadTempSensors(); void saveTempSensors(); uint8_t getTempSensorCount(); diff --git a/lib/AmsConfiguration/src/AmsConfiguration.cpp b/lib/AmsConfiguration/src/AmsConfiguration.cpp index f88f7ea1..9001342f 100644 --- a/lib/AmsConfiguration/src/AmsConfiguration.cpp +++ b/lib/AmsConfiguration/src/AmsConfiguration.cpp @@ -549,7 +549,6 @@ bool AmsConfiguration::setEnergyAccountingConfig(EnergyAccountingConfig& config) bool ret = EEPROM.commit(); EEPROM.end(); return ret; - } void AmsConfiguration::clearEnergyAccountingConfig(EnergyAccountingConfig& config) { @@ -574,6 +573,42 @@ void AmsConfiguration::ackEnergyAccountingChange() { energyAccountingChanged = false; } +bool AmsConfiguration::getUiConfig(UiConfig& config) { + if(hasConfig()) { + EEPROM.begin(EEPROM_SIZE); + EEPROM.get(CONFIG_UI_START, config); + if(config.showImport > 2) clearUiConfig(config); // Must be wrong + EEPROM.end(); + return true; + } else { + clearUiConfig(config); + return false; + } +} + +bool AmsConfiguration::setUiConfig(UiConfig& config) { + EEPROM.begin(EEPROM_SIZE); + EEPROM.put(CONFIG_UI_START, config); + bool ret = EEPROM.commit(); + EEPROM.end(); + return ret; +} + +void AmsConfiguration::clearUiConfig(UiConfig& config) { + // 1 = Always, 2 = If value present, 0 = Hidden + config.showImport = 1; + config.showExport = 2; + config.showVoltage = 2; + config.showAmperage = 2; + config.showReactive = 0; + config.showRealtime = 1; + config.showPeaks = 2; + config.showPricePlot = 2; + config.showDayPlot = 1; + config.showMonthPlot = 1; + config.showTemperaturePlot = 2; +} + void AmsConfiguration::clear() { EEPROM.begin(EEPROM_SIZE); @@ -621,6 +656,10 @@ void AmsConfiguration::clear() { clearDebug(debug); EEPROM.put(CONFIG_DEBUG_START, debug); + UiConfig ui; + clearUiConfig(ui); + EEPROM.put(CONFIG_UI_START, ui); + EEPROM.put(EEPROM_CONFIG_ADDRESS, EEPROM_CLEARED_INDICATOR); EEPROM.commit(); EEPROM.end(); @@ -949,6 +988,10 @@ bool AmsConfiguration::relocateConfig100() { EEPROM.put(CONFIG_METER_START, meter); + UiConfig ui; + clearUiConfig(ui); + EEPROM.put(CONFIG_UI_START, ui); + EEPROM.put(EEPROM_CONFIG_ADDRESS, 101); bool ret = EEPROM.commit(); EEPROM.end(); diff --git a/lib/EntsoePriceApi/include/EntsoeApi.h b/lib/EntsoePriceApi/include/EntsoeApi.h index 7ff12fba..af7aaff7 100644 --- a/lib/EntsoePriceApi/include/EntsoeApi.h +++ b/lib/EntsoePriceApi/include/EntsoeApi.h @@ -37,8 +37,7 @@ private: HTTPClient http; uint8_t currentDay = 0, currentHour = 0; - uint32_t tomorrowFetchMillis = 36000000; // Number of ms before midnight. Default fetch 10hrs before midnight (14:00 CE(S)T) - uint64_t midnightMillis = 0; + uint8_t tomorrowFetchMinute = 15; // How many minutes over 13:00 should it fetch prices uint64_t lastTodayFetch = 0; uint64_t lastTomorrowFetch = 0; uint64_t lastCurrencyFetch = 0; @@ -60,7 +59,7 @@ private: PricesContainer* fetchPrices(time_t); bool retrieve(const char* url, Stream* doc); - float getCurrencyMultiplier(const char* from, const char* to); + float getCurrencyMultiplier(const char* from, const char* to, time_t t); void printD(String fmt, ...); void printE(String fmt, ...); diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index ce939c9c..2d64ae5a 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -21,7 +21,7 @@ EntsoeApi::EntsoeApi(RemoteDebug* Debug) { TimeChangeRule CET = {"CET ", Last, Sun, Oct, 3, 60}; tz = new Timezone(CEST, CET); - tomorrowFetchMillis = 36000000 + (random(1800) * 1000); // Random between 13:30 and 14:00 + tomorrowFetchMinute = 15 + random(45); // Random between 13:15 and 14:00 } void EntsoeApi::setup(EntsoeConfig& config) { @@ -96,7 +96,7 @@ float EntsoeApi::getValueForHour(time_t cur, int8_t hour) { } else { return ENTSOE_NO_VALUE; } - float mult = getCurrencyMultiplier(tomorrow->currency, config->currency); + float mult = getCurrencyMultiplier(tomorrow->currency, config->currency, cur); if(mult == 0) return ENTSOE_NO_VALUE; multiplier *= mult; } else if(pos >= 0) { @@ -112,7 +112,7 @@ float EntsoeApi::getValueForHour(time_t cur, int8_t hour) { } else { return ENTSOE_NO_VALUE; } - float mult = getCurrencyMultiplier(today->currency, config->currency); + float mult = getCurrencyMultiplier(today->currency, config->currency, cur); if(mult == 0) return ENTSOE_NO_VALUE; multiplier *= mult; } @@ -138,21 +138,15 @@ bool EntsoeApi::loop() { if(strlen(config->currency) == 0) return false; - bool ret = false; tmElements_t tm; breakTime(tz->toLocal(t), tm); - if(currentHour != tm.Hour) { - currentHour = tm.Hour; - ret = today != NULL; // Only trigger MQTT publish if we have todays prices. - } - if(midnightMillis == 0) { - uint32_t curDayMillis = (((((tm.Hour * 60) + tm.Minute) * 60) + tm.Second) * 1000); - midnightMillis = now + (SECS_PER_DAY * 1000) - curDayMillis; - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Setting midnight millis %llu\n", midnightMillis); + if(currentDay == 0) { currentDay = tm.Day; - return false; - } else if(now > midnightMillis && currentDay != tm.Day) { + currentHour = tm.Hour; + } + + if(currentDay != tm.Day) { if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Rotating price objects at %lu\n", t); if(today != NULL) delete today; if(tomorrow != NULL) { @@ -160,38 +154,38 @@ bool EntsoeApi::loop() { tomorrow = NULL; } currentDay = tm.Day; - midnightMillis = 0; // Force new midnight millis calculation - return true; - } else { - if(today == NULL && (lastTodayFetch == 0 || now - lastTodayFetch > 60000)) { - try { - lastTodayFetch = now; - today = fetchPrices(t); - } catch(const std::exception& e) { - if(lastError == 0) lastError = 900; - today = NULL; - } - return today != NULL; - } - - // Prices for next day are published at 13:00 CE(S)T, but to avoid heavy server traffic at that time, we will - // fetch 1 hr after that (with some random delay) and retry every 15 minutes - if(tomorrow == NULL - && midnightMillis - now < tomorrowFetchMillis - && (lastTomorrowFetch == 0 || now - lastTomorrowFetch > 900000) - ) { - try { - breakTime(t+SECS_PER_DAY, tm); // Break UTC tomorrow to find UTC midnight - lastTomorrowFetch = now; - tomorrow = fetchPrices(t+SECS_PER_DAY); - } catch(const std::exception& e) { - if(lastError == 0) lastError = 900; - tomorrow = NULL; - } - return tomorrow != NULL; - } + currentHour = tm.Hour; + return today != NULL; // Only trigger MQTT publish if we have todays prices. + } else if(currentHour != tm.Hour) { + currentHour = tm.Hour; + return today != NULL; // Only trigger MQTT publish if we have todays prices. } - return ret; + + if(today == NULL && (lastTodayFetch == 0 || now - lastTodayFetch > 60000)) { + try { + lastTodayFetch = now; + today = fetchPrices(t); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + today = NULL; + } + return today != NULL; // Only trigger MQTT publish if we have todays prices. + } + + // Prices for next day are published at 13:00 CE(S)T, but to avoid heavy server traffic at that time, we will + // fetch with one hour (with some random delay) and retry every 15 minutes + if(tomorrow == NULL && (tm.Hour > 13 || (tm.Hour == 13 && tm.Minute >= tomorrowFetchMinute)) && (lastTomorrowFetch == 0 || now - lastTomorrowFetch > 900000)) { + try { + lastTomorrowFetch = now; + tomorrow = fetchPrices(t+SECS_PER_DAY); + } catch(const std::exception& e) { + if(lastError == 0) lastError = 900; + tomorrow = NULL; + } + return tomorrow != NULL; + } + + return false; } bool EntsoeApi::retrieve(const char* url, Stream* doc) { @@ -235,7 +229,7 @@ bool EntsoeApi::retrieve(const char* url, Stream* doc) { return false; } -float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { +float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to, time_t t) { if(strcmp(from, to) == 0) return 1.00; @@ -272,7 +266,9 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { return 0; } if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) Resulting currency multiplier: %.4f\n", currencyMultiplier); - lastCurrencyFetch = midnightMillis; + tmElements_t tm; + breakTime(t, tm); + lastCurrencyFetch = now + (SECS_PER_DAY * 1000) - (((((tm.Hour * 60) + tm.Minute) * 60) + tm.Second) * 1000); } return currencyMultiplier; } diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 17066021..80ef0012 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -136,7 +136,7 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) { if(topic.isEmpty() || !mqtt->connected()) return false; - if(strlen(eapi->getToken()) == 0) + if(eapi->getValueForHour(0) == ENTSOE_NO_VALUE) return false; time_t now = time(nullptr); diff --git a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp index 58bec458..273a331e 100644 --- a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp +++ b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp @@ -175,7 +175,7 @@ bool JsonMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { if(topic.isEmpty() || !mqtt->connected()) return false; - if(strlen(eapi->getToken()) == 0) + if(eapi->getValueForHour(0) == ENTSOE_NO_VALUE) return false; time_t now = time(nullptr); diff --git a/lib/RawMqttHandler/src/RawMqttHandler.cpp b/lib/RawMqttHandler/src/RawMqttHandler.cpp index ee8ae40c..35a516f8 100644 --- a/lib/RawMqttHandler/src/RawMqttHandler.cpp +++ b/lib/RawMqttHandler/src/RawMqttHandler.cpp @@ -123,7 +123,7 @@ bool RawMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) bool RawMqttHandler::publishPrices(EntsoeApi* eapi) { if(topic.isEmpty() || !mqtt->connected()) return false; - if(strcmp(eapi->getToken(), "") == 0) + if(eapi->getValueForHour(0) == ENTSOE_NO_VALUE) return false; time_t now = time(nullptr); diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 785b1688..9433ffa5 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -33,7 +33,7 @@
- + diff --git a/lib/SvelteUi/app/src/lib/AmpPlot.svelte b/lib/SvelteUi/app/src/lib/AmpPlot.svelte index 40bec75a..3e5c9a75 100644 --- a/lib/SvelteUi/app/src/lib/AmpPlot.svelte +++ b/lib/SvelteUi/app/src/lib/AmpPlot.svelte @@ -18,7 +18,7 @@ if(u1 > 0) { xTicks.push({ label: 'L1' }); points.push({ - label: i1 ? i1 + 'A' : '-', + label: i1 ? (i1 > 10 ? i1.toFixed(0) : i1.toFixed(1)) + 'A' : '-', value: i1 ? i1 : 0, color: ampcol(i1 ? (i1)/(max)*100 : 0) }); @@ -26,7 +26,7 @@ if(u2 > 0) { xTicks.push({ label: 'L2' }); points.push({ - label: i2 ? i2 + 'A' : '-', + label: i2 ? (i2 > 10 ? i2.toFixed(0) : i2.toFixed(1)) + 'A' : '-', value: i2 ? i2 : 0, color: ampcol(i2 ? (i2)/(max)*100 : 0) }); @@ -34,7 +34,7 @@ if(u3 > 0) { xTicks.push({ label: 'L3' }); points.push({ - label: i3 ? i3 + 'A' : '-', + label: i3 ? (i3 > 10 ? i3.toFixed(0) : i3.toFixed(1)) + 'A' : '-', value: i3 ? i3 : 0, color: ampcol(i3 ? (i3)/(max)*100 : 0) }); diff --git a/lib/SvelteUi/app/src/lib/BarChart.svelte b/lib/SvelteUi/app/src/lib/BarChart.svelte index b6532b5a..e2ba9732 100644 --- a/lib/SvelteUi/app/src/lib/BarChart.svelte +++ b/lib/SvelteUi/app/src/lib/BarChart.svelte @@ -7,11 +7,13 @@ let xScale; let yScale; let heightAvailable; + let labelOffset; $: { heightAvailable = height-(config.title ? 20 : 0); let innerWidth = width - (config.padding.left + config.padding.right); barWidth = innerWidth / config.points.length; + labelOffset = barWidth < 25 ? 28 : 17; let yPerUnit = (heightAvailable-config.padding.top-config.padding.bottom)/(config.y.max-config.y.min); @@ -58,42 +60,45 @@ {#each config.points as point, i} {#if point.value !== undefined} - + - {point.label} + {#if barWidth > 15} + {point.label} + {/if} {/if} {#if point.value2 > 0.0001} - - - {point.label2} + + {#if barWidth > 15} + {point.label2} + {/if} {/if} {/each} diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index a64f2afb..37e843fd 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -47,6 +47,9 @@ d: { s: false, t: false, l: 5 }, + u: { + i: 0, e: 0, v: 0, a: 0, r: 0, c: 0, t: 0, p: 0, d: 0, m: 0, s: 0 + }, i: { h: null, a: null, l: { p: null, i: false }, @@ -94,6 +97,7 @@ sysinfoStore.update(s => { s.booting = res.reboot; + s.ui = configuration.u; return s; }); @@ -548,6 +552,100 @@
{/if} +
+ User interface + +
+
+ Import gauge
+ +
+
+ Export gauge
+ +
+
+ Voltage
+ +
+
+ Amperage
+ +
+
+ Reactive
+ +
+
+ Realtime
+ +
+
+ Peaks
+ +
+
+ Price
+ +
+
+ Day plot
+ +
+
+ Month plot
+ +
+
+ Temperature plot
+ +
+
+
{#if sysinfo.board > 20 || sysinfo.chip == 'esp8266'}
Hardware diff --git a/lib/SvelteUi/app/src/lib/Dashboard.svelte b/lib/SvelteUi/app/src/lib/Dashboard.svelte index a27a8752..8cc35c26 100644 --- a/lib/SvelteUi/app/src/lib/Dashboard.svelte +++ b/lib/SvelteUi/app/src/lib/Dashboard.svelte @@ -1,6 +1,6 @@
+ {#if uiVisibility(sysinfo.ui.i, data.i)}
@@ -41,7 +43,8 @@
{data.ic ? data.ic.toFixed(1) : '-'} kWh
- {#if data.om || data.e > 0} + {/if} + {#if uiVisibility(sysinfo.ui.e, data.om || data.e > 0)}
@@ -52,39 +55,47 @@
{/if} - {#if data.u1 > 100 || data.u2 > 100 || data.u3 > 100} + {#if uiVisibility(sysinfo.ui.v, data.u1 > 100 || data.u2 > 100 || data.u3 > 100)}
{/if} - {#if data.i1 > 0.01 || data.i2 > 0.01 || data.i3 > 0.01} + {#if uiVisibility(sysinfo.ui.a, data.i1 > 0.01 || data.i2 > 0.01 || data.i3 > 0.01)}
{/if} + {#if uiVisibility(sysinfo.ui.r, data.ri > 0 || data.re > 0 || data.ric > 0 || data.rec > 0)}
+ {/if} + {#if uiVisibility(sysinfo.ui.c, data.ea)}
+ {/if} {#if data && data.pr && (data.pr.startsWith("10YNO") || data.pr == '10Y1001A1001A48H')}
{/if} - {#if (typeof data.p == "number") && !Number.isNaN(data.p)} + {#if uiVisibility(sysinfo.ui.p, (typeof data.p == "number") && !Number.isNaN(data.p))}
{/if} + {#if uiVisibility(sysinfo.ui.d, dayPlot)}
+ {/if} + {#if uiVisibility(sysinfo.ui.m, monthPlot)}
- {#if data.t && data.t != -127 && temperatures.c > 1} + {/if} + {#if uiVisibility(sysinfo.ui.s, data.t && data.t != -127 && temperatures.c > 1)}
diff --git a/lib/SvelteUi/app/src/lib/DataStores.js b/lib/SvelteUi/app/src/lib/DataStores.js index 7970faa6..32ea927e 100644 --- a/lib/SvelteUi/app/src/lib/DataStores.js +++ b/lib/SvelteUi/app/src/lib/DataStores.js @@ -1,4 +1,5 @@ import { readable, writable } from 'svelte/store'; +import { isBusPowered } from './Helpers'; async function fetchWithTimeout(resource, options = {}) { const { timeout = 8000 } = options; @@ -16,11 +17,14 @@ async function fetchWithTimeout(resource, options = {}) { let sysinfo = { version: '', chip: '', + mac: null, + apmac: null, vndcfg: null, usrcfg: null, fwconsent: null, booting: false, upgrading: false, + ui: {}, security: 0 }; export const sysinfoStore = writable(sysinfo); @@ -43,18 +47,31 @@ export const dataStore = readable(data, (set) => { set(data); if(lastTemp != data.t) { lastTemp = data.t; - getTemperatures(); + setTimeout(getTemperatures, 2000); } if(lastPrice != data.p) { lastPrice = data.p; - getPrices(); + setTimeout(getPrices, 4000); } if(sysinfo.upgrading) { window.location.reload(); - } else if(sysinfo.booting) { + } else if(!sysinfo || !sysinfo.chip || sysinfo.booting || (tries > 1 && !isBusPowered(sysinfo.board))) { getSysinfo(); + if(dayPlotTimeout) clearTimeout(dayPlotTimeout); + dayPlotTimeout = setTimeout(getDayPlot, 2000); + if(monthPlotTimeout) clearTimeout(monthPlotTimeout); + monthPlotTimeout = setTimeout(getMonthPlot, 3000); } - timeout = setTimeout(getData, 5000); + let to = 5000; + if(isBusPowered(sysinfo.board) && data.v > 2.5) { + let diff = (3.3 - Math.min(3.3, data.v)); + if(diff > 0) { + to = Math.max(diff, 0.1) * 10 * 5000; + } + } + if(to > 5000) console.log("Scheduling next data fetch in " + to + "ms"); + if(timeout) clearTimeout(timeout); + timeout = setTimeout(getData, to); tries = 0; }) .catch((err) => { @@ -68,7 +85,7 @@ export const dataStore = readable(data, (set) => { }); timeout = setTimeout(getData, 15000); } else { - timeout = setTimeout(getData, 5000); + timeout = setTimeout(getData, isBusPowered(sysinfo.board) ? 10000 : 5000); } }); } @@ -80,37 +97,49 @@ export const dataStore = readable(data, (set) => { let prices = {}; export const pricesStore = writable(prices); -export async function getPrices(){ +export async function getPrices() { const response = await fetchWithTimeout("/energyprice.json"); prices = (await response.json()) pricesStore.set(prices); } let dayPlot = {}; -export const dayPlotStore = readable(dayPlot, (set) => { - async function getDayPlot(){ - const response = await fetchWithTimeout("/dayplot.json"); - dayPlot = (await response.json()) - set(dayPlot); - - let date = new Date(); - setTimeout(getDayPlot, (61-date.getMinutes())*60000) +let dayPlotTimeout; +export async function getDayPlot() { + if(dayPlotTimeout) { + clearTimeout(dayPlotTimeout); + dayPlotTimeout = 0; } + const response = await fetchWithTimeout("/dayplot.json"); + dayPlot = (await response.json()) + dayPlotStore.set(dayPlot); + + let date = new Date(); + dayPlotTimeout = setTimeout(getDayPlot, ((60-date.getMinutes())*60000)+20) +} + +export const dayPlotStore = writable(dayPlot, (set) => { getDayPlot(); return function stop() {} }); let monthPlot = {}; -export const monthPlotStore = readable(monthPlot, (set) => { - async function getmonthPlot(){ - const response = await fetchWithTimeout("/monthplot.json"); - monthPlot = (await response.json()) - set(monthPlot); - - let date = new Date(); - setTimeout(getmonthPlot, (24-date.getHours())*3600000) +let monthPlotTimeout; +export async function getMonthPlot() { + if(monthPlotTimeout) { + clearTimeout(monthPlotTimeout); + monthPlotTimeout = 0; } - getmonthPlot(); + const response = await fetchWithTimeout("/monthplot.json"); + monthPlot = (await response.json()) + monthPlotStore.set(monthPlot); + + let date = new Date(); + monthPlotTimeout = setTimeout(getMonthPlot, ((24-date.getHours())*3600000)+40) +} + +export const monthPlotStore = writable(monthPlot, (set) => { + getMonthPlot(); return function stop() {} }); @@ -127,12 +156,17 @@ export const temperaturesStore = writable(temperatures, (set) => { }); let tariff = {}; +let tariffTimeout; export async function getTariff() { + if(tariffTimeout) { + clearTimeout(tariffTimeout); + tariffTimeout = 0; + } const response = await fetchWithTimeout("/tariff.json"); tariff = (await response.json()) tariffStore.set(tariff); let date = new Date(); - setTimeout(getTariff, (61-date.getMinutes())*60000) + tariffTimeout = setTimeout(getTariff, ((60-date.getMinutes())*60000)+30) } export const tariffStore = writable(tariff, (set) => { diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index 1a701c58..95910656 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -2,7 +2,7 @@ import { Link } from "svelte-navigator"; import { sysinfoStore, getGitHubReleases, gitHubReleaseStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; - import { boardtype, hanError, mqttError, priceError } from './Helpers.js'; + import { boardtype, hanError, mqttError, priceError, isBusPowered } from './Helpers.js'; import GitHubLogo from './../assets/github.svg'; import Uptime from "./Uptime.svelte"; import Badge from './Badge.svelte'; @@ -19,7 +19,7 @@ function askUpgrade() { if(confirm('Do you want to upgrade this device to ' + nextVersion.tag_name + '?')) { - if((sysinfo.board != 2 && sysinfo.board != 4 && sysinfo.board != 7) || confirm('WARNING: ' + boardtype(sysinfo.chip, sysinfo.board) + ' must be connected to an external power supply during firmware upgrade. Failure to do so may cause power-down during upload resulting in non-functioning unit.')) { + if(!isBusPowered(sysinfo.board) || confirm('WARNING: ' + boardtype(sysinfo.chip, sysinfo.board) + ' must be connected to an external power supply during firmware upgrade. Failure to do so may cause power-down during upload resulting in non-functioning unit.')) { sysinfoStore.update(s => { s.upgrading = true; return s; diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index eb313ce5..36a9490c 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -143,4 +143,18 @@ export function priceError(err) { if(err < 0) return "Unspecified error "+err; return ""; -} \ No newline at end of file +} + +export function isBusPowered(boardType) { + switch(boardType) { + case 2: + case 4: + case 7: + return true; + } + return false; +} + +export function uiVisibility(choice, state) { + return choice == 1 || (choice == 2 && state); +} diff --git a/lib/SvelteUi/app/src/lib/PricePlot.svelte b/lib/SvelteUi/app/src/lib/PricePlot.svelte index 8d2509ef..c7d5d78a 100644 --- a/lib/SvelteUi/app/src/lib/PricePlot.svelte +++ b/lib/SvelteUi/app/src/lib/PricePlot.svelte @@ -76,8 +76,6 @@ }); } - console.log(yTicks); - config = { title: "Future energy price (" + json.currency + ")", padding: { top: 20, right: 15, bottom: 20, left: 35 }, diff --git a/lib/SvelteUi/app/src/lib/SetupPanel.svelte b/lib/SvelteUi/app/src/lib/SetupPanel.svelte index 250c7706..835af0d7 100644 --- a/lib/SvelteUi/app/src/lib/SetupPanel.svelte +++ b/lib/SvelteUi/app/src/lib/SetupPanel.svelte @@ -46,6 +46,7 @@ const data = new URLSearchParams(); for (let field of formData) { const [key, value] = field; + data.append(key, value) if(key == 'sh') hostname = value; } diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index 02ea016d..dda8bd3a 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -1,5 +1,5 @@ -Up -{#if days > 1} -{days} days -{:else if days > 0} -{days} day -{:else if hours > 1} -{hours} hours -{:else if hours > 0} -{hours} hour -{:else if minutes > 1} -{minutes} minutes -{:else if minutes > 0} -{minutes} minute -{:else} -{epoch} seconds +{#if epoch} + Up + {#if days > 1} + {days} days + {:else if days > 0} + {days} day + {:else if hours > 1} + {hours} hours + {:else if hours > 0} + {hours} hour + {:else if minutes > 1} + {minutes} minutes + {:else if minutes > 0} + {minutes} minute + {:else} + {epoch} seconds + {/if} {/if} diff --git a/lib/SvelteUi/app/src/lib/VoltPlot.svelte b/lib/SvelteUi/app/src/lib/VoltPlot.svelte index 7751ade9..14ce6a01 100644 --- a/lib/SvelteUi/app/src/lib/VoltPlot.svelte +++ b/lib/SvelteUi/app/src/lib/VoltPlot.svelte @@ -17,7 +17,7 @@ if(u1 > 0) { xTicks.push({ label: ds === 1 ? 'L1-L2' : 'L1' }); points.push({ - label: u1 ? u1 + 'V' : '-', + label: u1 ? u1.toFixed(0) + 'V' : '-', value: u1 ? u1 : 0, color: voltcol(u1 ? (u1-min)/(max-min)*100 : 0) }); @@ -25,7 +25,7 @@ if(u2 > 0) { xTicks.push({ label: ds === 1 ? 'L1-L3' : 'L2' }); points.push({ - label: u2 ? u2 + 'V' : '-', + label: u2 ? u2.toFixed(0) + 'V' : '-', value: u2 ? u2 : 0, color: voltcol(u2 ? (u2-min)/(max-min)*100 : 0) }); @@ -33,7 +33,7 @@ if(u3 > 0) { xTicks.push({ label: ds === 1 ? 'L2-L3' : 'L3' }); points.push({ - label: u3 ? u3 + 'V' : '-', + label: u3 ? u3.toFixed(0) + 'V' : '-', value: u3 ? u3 : 0, color: voltcol(u3 ? (u3-min)/(max-min)*100 : 0) }); diff --git a/lib/SvelteUi/app/vite.config.js b/lib/SvelteUi/app/vite.config.js index 295482b8..9bcb4a69 100644 --- a/lib/SvelteUi/app/vite.config.js +++ b/lib/SvelteUi/app/vite.config.js @@ -17,14 +17,14 @@ export default defineConfig({ plugins: [svelte()], server: { proxy: { - "/data.json": "https://ams2mqtt.no23.cc", - "/energyprice.json": "https://ams2mqtt.no23.cc", - "/dayplot.json": "https://ams2mqtt.no23.cc", - "/monthplot.json": "https://ams2mqtt.no23.cc", - "/temperature.json": "https://ams2mqtt.no23.cc", - "/sysinfo.json": "https://ams2mqtt.no23.cc", + "/data.json": "http://192.168.233.229", + "/energyprice.json": "http://192.168.233.229", + "/dayplot.json": "http://192.168.233.229", + "/monthplot.json": "http://192.168.233.229", + "/temperature.json": "http://192.168.233.229", + "/sysinfo.json": "http://192.168.233.229", "/configuration.json": "http://192.168.233.229", - "/tariff.json": "https://ams2mqtt.no23.cc", + "/tariff.json": "http://192.168.233.229", "/save": "http://192.168.233.229", "/reboot": "http://192.168.233.229", "/configfile": "http://192.168.233.229", diff --git a/lib/SvelteUi/json/conf_ui.json b/lib/SvelteUi/json/conf_ui.json new file mode 100644 index 00000000..97fd05e3 --- /dev/null +++ b/lib/SvelteUi/json/conf_ui.json @@ -0,0 +1,13 @@ +"u": { + "i": %d, + "e": %d, + "v": %d, + "a": %d, + "r": %d, + "c": %d, + "t": %d, + "p": %d, + "d": %d, + "m": %d, + "s": %d +}, \ No newline at end of file diff --git a/lib/SvelteUi/json/sysinfo.json b/lib/SvelteUi/json/sysinfo.json index 77c61290..f22661ee 100644 --- a/lib/SvelteUi/json/sysinfo.json +++ b/lib/SvelteUi/json/sysinfo.json @@ -3,6 +3,7 @@ "chip": "%s", "chipId": "%s", "mac": "%s", + "apmac": "%s", "board": %d, "vndcfg": %s, "usrcfg": %s, @@ -22,5 +23,18 @@ "model": "%s", "id": "%s" }, + "ui": { + "i": %d, + "e": %d, + "v": %d, + "a": %d, + "r": %d, + "c": %d, + "t": %d, + "p": %d, + "d": %d, + "m": %d, + "s": %d + }, "security": %d } \ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 1577cf09..7c2d0d98 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -26,12 +26,14 @@ #include "html/conf_debug_json.h" #include "html/conf_gpio_json.h" #include "html/conf_domoticz_json.h" +#include "html/conf_ui_json.h" #include "html/firmware_html.h" #include "version.h" #if defined(ESP32) #include +#include #endif @@ -216,6 +218,26 @@ void AmsWebServer::sysinfoJson() { IPAddress dns1 = WiFi.dnsIP(0); IPAddress dns2 = WiFi.dnsIP(1); + char macStr[18] = { 0 }; + char apMacStr[18] = { 0 }; + + uint8_t mac[6]; + uint8_t apmac[6]; + + #if defined(ESP8266) + wifi_get_macaddr(STATION_IF, mac); + wifi_get_macaddr(SOFTAP_IF, apmac); + #elif defined(ESP32) + esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_STA, mac); + esp_wifi_get_mac((wifi_interface_t)ESP_IF_WIFI_AP, apmac); + #endif + + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + sprintf(apMacStr, "%02X:%02X:%02X:%02X:%02X:%02X", apmac[0], apmac[1], apmac[2], apmac[3], apmac[4], apmac[5]); + + UiConfig ui; + config->getUiConfig(ui); + snprintf_P(buf, BufferSize, SYSINFO_JSON, VERSION, #if defined(CONFIG_IDF_TARGET_ESP32S2) @@ -228,7 +250,8 @@ void AmsWebServer::sysinfoJson() { "esp8266", #endif chipIdStr.c_str(), - WiFi.macAddress().c_str(), + macStr, + apMacStr, sys.boardType, sys.vendorConfigured ? "true" : "false", sys.userConfigured ? "true" : "false", @@ -249,6 +272,17 @@ void AmsWebServer::sysinfoJson() { meterState->getMeterType(), meterState->getMeterModel().c_str(), meterState->getMeterId().c_str(), + ui.showImport, + ui.showExport, + ui.showVoltage, + ui.showAmperage, + ui.showReactive, + ui.showRealtime, + ui.showPeaks, + ui.showPricePlot, + ui.showDayPlot, + ui.showMonthPlot, + ui.showTemperaturePlot, webConfig.security ); @@ -730,6 +764,8 @@ void AmsWebServer::configurationJson() { config->getDebugConfig(debugConfig); DomoticzConfig domo; config->getDomoticzConfig(domo); + UiConfig ui; + config->getUiConfig(ui); bool qsc = false; bool qsr = false; @@ -857,6 +893,20 @@ void AmsWebServer::configurationJson() { gpioConfig->vccBootLimit / 10.0 ); server.sendContent(buf); + snprintf_P(buf, BufferSize, CONF_UI_JSON, + ui.showImport, + ui.showExport, + ui.showVoltage, + ui.showAmperage, + ui.showReactive, + ui.showRealtime, + ui.showPeaks, + ui.showPricePlot, + ui.showDayPlot, + ui.showMonthPlot, + ui.showTemperaturePlot + ); + server.sendContent(buf); snprintf_P(buf, BufferSize, CONF_DOMOTICZ_JSON, domo.elidx, domo.cl1idx, @@ -1251,6 +1301,23 @@ void AmsWebServer::handleSave() { config->setDebugConfig(debug); } + if(server.hasArg(F("u")) && server.arg(F("u")) == F("true")) { + UiConfig ui; + config->getUiConfig(ui); + ui.showImport = server.arg(F("ui")).toInt(); + ui.showExport = server.arg(F("ue")).toInt(); + ui.showVoltage = server.arg(F("uv")).toInt(); + ui.showAmperage = server.arg(F("ua")).toInt(); + ui.showReactive = server.arg(F("ur")).toInt(); + ui.showRealtime = server.arg(F("uc")).toInt(); + ui.showPeaks = server.arg(F("ut")).toInt(); + ui.showPricePlot = server.arg(F("up")).toInt(); + ui.showDayPlot = server.arg(F("ud")).toInt(); + ui.showMonthPlot = server.arg(F("um")).toInt(); + ui.showTemperaturePlot = server.arg(F("us")).toInt(); + config->setUiConfig(ui); + } + if(server.hasArg(F("p")) && server.arg(F("p")) == F("true")) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Received price API config")); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 266abd7d..11e2c5d6 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -1124,7 +1124,6 @@ void WiFi_connect() { #endif MDNS.end(); - WiFi.persistent(false); WiFi.disconnect(true); WiFi.softAPdisconnect(true); WiFi.enableAP(false); @@ -1175,8 +1174,11 @@ void WiFi_connect() { WiFi.hostname(wifi.hostname); } #endif + #if defined(ESP32) + WiFi.setScanMethod(WIFI_ALL_CHANNEL_SCAN); + WiFi.setSortMethod(WIFI_CONNECT_AP_BY_SIGNAL); + #endif WiFi.setAutoReconnect(true); - WiFi.persistent(true); if(WiFi.begin(wifi.ssid, wifi.psk)) { if(wifi.sleep <= 2) { switch(wifi.sleep) { @@ -1536,54 +1538,62 @@ void configFileParse() { char* buf = (char*) commonBuffer; memset(buf, 0, 1024); while((size = file.readBytesUntil('\n', buf, 1024)) > 0) { + for(uint16_t i = 0; i < size; i++) { + if(buf[i] < 32 || buf[i] > 126) { + memset(buf+i, 0, size-i); + debugD("Found non-ascii, shortening line from %d to %d", size, i); + size = i; + break; + } + } if(strncmp_P(buf, PSTR("boardType "), 10) == 0) { if(!lSys) { config.getSystemConfig(sys); lSys = true; }; sys.boardType = String(buf+10).toInt(); } else if(strncmp_P(buf, PSTR("ssid "), 5) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.ssid, buf+5, size-5); + strcpy(wifi.ssid, buf+5); } else if(strncmp_P(buf, PSTR("psk "), 4) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.psk, buf+4, size-4); + strcpy(wifi.psk, buf+4); } else if(strncmp_P(buf, PSTR("ip "), 3) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.ip, buf+3, size-3); + strcpy(wifi.ip, buf+3); } else if(strncmp_P(buf, PSTR("gateway "), 8) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.gateway, buf+8, size-8); + strcpy(wifi.gateway, buf+8); } else if(strncmp_P(buf, PSTR("subnet "), 7) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.subnet, buf+7, size-7); + strcpy(wifi.subnet, buf+7); } else if(strncmp_P(buf, PSTR("dns1 "), 5) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.dns1, buf+5, size-5); + strcpy(wifi.dns1, buf+5); } else if(strncmp_P(buf, PSTR("dns2 "), 5) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.dns2, buf+5, size-5); + strcpy(wifi.dns2, buf+5); } else if(strncmp_P(buf, PSTR("hostname "), 9) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; - memcpy(wifi.hostname, buf+9, size-9); + strcpy(wifi.hostname, buf+9); } else if(strncmp_P(buf, PSTR("mdns "), 5) == 0) { if(!lWiFi) { config.getWiFiConfig(wifi); lWiFi = true; }; wifi.mdns = String(buf+5).toInt() == 1;; } else if(strncmp_P(buf, PSTR("mqttHost "), 9) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; - memcpy(mqtt.host, buf+9, size-9); + strcpy(mqtt.host, buf+9); } else if(strncmp_P(buf, PSTR("mqttPort "), 9) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; mqtt.port = String(buf+9).toInt(); } else if(strncmp_P(buf, PSTR("mqttClientId "), 13) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; - memcpy(mqtt.clientId, buf+13, size-13); + strcpy(mqtt.clientId, buf+13); } else if(strncmp_P(buf, PSTR("mqttPublishTopic "), 17) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; - memcpy(mqtt.publishTopic, buf+17, size-17); + strcpy(mqtt.publishTopic, buf+17); } else if(strncmp_P(buf, PSTR("mqttUsername "), 13) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; - memcpy(mqtt.username, buf+13, size-13); + strcpy(mqtt.username, buf+13); } else if(strncmp_P(buf, PSTR("mqttPassword "), 13) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; - memcpy(mqtt.password, buf+13, size-13); + strcpy(mqtt.password, buf+13); } else if(strncmp_P(buf, PSTR("mqttPayloadFormat "), 18) == 0) { if(!lMqtt) { config.getMqttConfig(mqtt); lMqtt = true; }; mqtt.payloadFormat = String(buf+18).toInt(); @@ -1595,10 +1605,10 @@ void configFileParse() { web.security = String(buf+12).toInt(); } else if(strncmp_P(buf, PSTR("webUsername "), 12) == 0) { if(!lWeb) { config.getWebConfig(web); lWeb = true; }; - memcpy(web.username, buf+12, size-12); + strcpy(web.username, buf+12); } else if(strncmp_P(buf, PSTR("webPassword "), 12) == 0) { if(!lWeb) { config.getWebConfig(web); lWeb = true; }; - memcpy(web.username, buf+12, size-12); + strcpy(web.username, buf+12); } else if(strncmp_P(buf, PSTR("meterBaud "), 10) == 0) { if(!lMeter) { config.getMeterConfig(meter); lMeter = true; }; meter.baud = String(buf+10).toInt(); @@ -1697,19 +1707,19 @@ void configFileParse() { ntp.dhcp = String(buf+8).toInt() == 1; } else if(strncmp_P(buf, PSTR("ntpServer "), 10) == 0) { if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; - memcpy(ntp.server, buf+10, size-10); + strcpy(ntp.server, buf+10); } else if(strncmp_P(buf, PSTR("ntpTimezone "), 12) == 0) { if(!lNtp) { config.getNtpConfig(ntp); lNtp = true; }; - memcpy(ntp.timezone, buf+12, size-12); + strcpy(ntp.timezone, buf+12); } else if(strncmp_P(buf, PSTR("entsoeToken "), 12) == 0) { if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; }; - memcpy(entsoe.token, buf+12, size-12); + strcpy(entsoe.token, buf+12); } else if(strncmp_P(buf, PSTR("entsoeArea "), 11) == 0) { if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; }; - memcpy(entsoe.area, buf+11, size-11); + strcpy(entsoe.area, buf+11); } else if(strncmp_P(buf, PSTR("entsoeCurrency "), 15) == 0) { if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; }; - memcpy(entsoe.currency, buf+15, size-15); + strcpy(entsoe.currency, buf+15); } else if(strncmp_P(buf, PSTR("entsoeMultiplier "), 17) == 0) { if(!lEntsoe) { config.getEntsoeConfig(entsoe); lEntsoe = true; }; entsoe.multiplier = String(buf+17).toDouble() * 1000; From 365061df29caafce1c06407535c33d3882a82ec3 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Thu, 12 Jan 2023 20:17:37 +0100 Subject: [PATCH 41/66] Some changes after testing --- lib/SvelteUi/app/src/lib/StatusPage.svelte | 2 +- lib/SvelteUi/include/AmsWebServer.h | 5 ++ lib/SvelteUi/json/firmware.html | 7 ++- lib/SvelteUi/src/AmsWebServer.cpp | 54 ++++++++++++++++++++-- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/lib/SvelteUi/app/src/lib/StatusPage.svelte b/lib/SvelteUi/app/src/lib/StatusPage.svelte index dda8bd3a..3b8344a1 100644 --- a/lib/SvelteUi/app/src/lib/StatusPage.svelte +++ b/lib/SvelteUi/app/src/lib/StatusPage.svelte @@ -108,7 +108,7 @@ Gateway: {sysinfo.net.gw}
- DNS: {sysinfo.net.dns1} {#if sysinfo.net.dns2 != '0.0.0.0'}/ {sysinfo.net.dns2}{/if} + DNS: {sysinfo.net.dns1} {#if sysinfo.net.dns2 && sysinfo.net.dns2 != '0.0.0.0'}/ {sysinfo.net.dns2}{/if}
{/if} diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index b5714da5..9955baab 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -61,6 +61,11 @@ private: bool performUpgrade = false; bool rebootForUpgrade = false; String priceRegion = ""; + #if defined(AMS2MQTT_FIRMWARE_URL) + String customFirmwareUrl = AMS2MQTT_FIRMWARE_URL; + #else + String customFirmwareUrl; + #endif static const uint16_t BufferSize = 2048; char* buf; diff --git a/lib/SvelteUi/json/firmware.html b/lib/SvelteUi/json/firmware.html index da27f421..a6faa73f 100644 --- a/lib/SvelteUi/json/firmware.html +++ b/lib/SvelteUi/json/firmware.html @@ -1,6 +1,9 @@
- - + File:
+ or
+ URL:
+
+
\ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 7c2d0d98..4abe05da 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -1429,7 +1429,6 @@ void AmsWebServer::upgrade() { server.handleClient(); delay(250); - String customFirmwareUrl = ""; if(server.hasArg(F("url"))) { customFirmwareUrl = server.arg(F("url")); } @@ -1493,8 +1492,55 @@ void AmsWebServer::firmwarePost() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Handling firmware post...")); if(!checkSecurity(1)) return; + + if(rebootForUpgrade) { + server.send(200); + } else { + if(server.hasArg(F("url"))) { + String url = server.arg(F("url")); + if(!url.isEmpty() && (url.startsWith(F("http://")) || url.startsWith(F("https://")))) { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf(PSTR("Custom firmware URL was provided")); - server.send(200); + WiFiClient client; + #if defined(ESP8266) + String chipType = F("esp8266"); + #elif defined(CONFIG_IDF_TARGET_ESP32S2) + String chipType = F("esp32s2"); + #elif defined(ESP32) + #if defined(CONFIG_FREERTOS_UNICORE) + String chipType = F("esp32solo"); + #else + String chipType = F("esp32"); + #endif + #endif + + #if defined(ESP8266) + ESPhttpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + t_httpUpdate_return ret = ESPhttpUpdate.update(client, url, VERSION); + #elif defined(ESP32) + HTTPUpdate httpUpdate; + httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); + HTTPUpdateResult ret = httpUpdate.update(client, url, String(VERSION) + "-" + chipType); + #endif + + switch(ret) { + case HTTP_UPDATE_FAILED: + debugger->printf(PSTR("Update failed")); + break; + case HTTP_UPDATE_NO_UPDATES: + debugger->printf(PSTR("No Update")); + break; + case HTTP_UPDATE_OK: + debugger->printf(PSTR("Update OK")); + break; + } + server.send(200, MIME_PLAIN, "OK"); + return; + } + } + server.sendHeader(HEADER_LOCATION,F("/firmware")); + server.send(303); + } } @@ -1503,7 +1549,9 @@ void AmsWebServer::firmwareUpload() { return; HTTPUpload& upload = server.upload(); - if(upload.status == UPLOAD_FILE_START) { + if(upload.totalSize == 0) { + return; + } else if(upload.status == UPLOAD_FILE_START) { String filename = upload.filename; if(!filename.endsWith(".bin")) { server.send(500, MIME_PLAIN, "500: couldn't create file"); From c28752a00ac1595256b4fc376ac235dead874a25 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Thu, 12 Jan 2023 21:24:36 +0100 Subject: [PATCH 42/66] Fixed firmware upgrade --- lib/SvelteUi/json/firmware.html | 10 ++++++---- lib/SvelteUi/src/AmsWebServer.cpp | 20 +++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/SvelteUi/json/firmware.html b/lib/SvelteUi/json/firmware.html index a6faa73f..2e3e6555 100644 --- a/lib/SvelteUi/json/firmware.html +++ b/lib/SvelteUi/json/firmware.html @@ -1,9 +1,11 @@
- File:
- or
- URL:
-
+ File: + +
+ or

+
+ URL:
\ No newline at end of file diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 4abe05da..1f7c800d 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -1549,10 +1549,12 @@ void AmsWebServer::firmwareUpload() { return; HTTPUpload& upload = server.upload(); - if(upload.totalSize == 0) { - return; - } else if(upload.status == UPLOAD_FILE_START) { + if(upload.status == UPLOAD_FILE_START) { String filename = upload.filename; + if(filename.isEmpty()) { + if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("No file, falling back to post\n")); + return; + } if(!filename.endsWith(".bin")) { server.send(500, MIME_PLAIN, "500: couldn't create file"); } else { @@ -1576,10 +1578,10 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { HTTPUpload& upload = server.upload(); if(upload.status == UPLOAD_FILE_START){ if(uploading) { - if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("Upload already in progress")); + if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("Upload already in progress\n")); server.send_P(500, MIME_HTML, PSTR("

Upload already in progress!

")); } else if (!LittleFS.begin()) { - if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("An Error has occurred while mounting LittleFS")); + if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("An Error has occurred while mounting LittleFS\n")); server.send_P(500, MIME_HTML, PSTR("

Unable to mount LittleFS!

")); } else { uploading = true; @@ -1617,7 +1619,7 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { if(debugger->isActive(RemoteDebug::ERROR)) debugger->printf(PSTR("An Error has occurred while writing file")); snprintf_P(buf, BufferSize, RESPONSE_JSON, "false", - "Unable to upload", + "File size does not match", "false" ); server.setContentLength(strlen(buf)); @@ -1625,14 +1627,18 @@ HTTPUpload& AmsWebServer::uploadFile(const char* path) { } } } else if(upload.status == UPLOAD_FILE_END) { + if(debugger->isActive(RemoteDebug::DEBUG)) { + debugger->printf_P(PSTR("handleFileUpload Ended\n")); + } if(file) { file.flush(); file.close(); // LittleFS.end(); } else { + debugger->printf_P(PSTR("File was not valid in the end... Write error: %d, \n"), file.getWriteError()); snprintf_P(buf, BufferSize, RESPONSE_JSON, "false", - "Unable to upload", + "Upload ended, but file is missing", "false" ); server.setContentLength(strlen(buf)); From 1cee48eab4b72ef7574dcb07aa0c8aff15a1c8c2 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 14 Jan 2023 09:34:28 +0100 Subject: [PATCH 43/66] Some design changes --- lib/SvelteUi/app/index.html | 1 + lib/SvelteUi/app/manifest.json | 19 +++++++++++++++++++ lib/SvelteUi/app/service-worker.js | 11 +++++++++++ lib/SvelteUi/app/src/App.svelte | 2 +- lib/SvelteUi/app/src/assets/favicon.svg | 19 +++++++++++++++++++ lib/SvelteUi/app/src/lib/Header.svelte | 1 + lib/SvelteUi/include/AmsWebServer.h | 2 +- lib/SvelteUi/src/AmsWebServer.cpp | 8 +++++--- 8 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 lib/SvelteUi/app/manifest.json create mode 100644 lib/SvelteUi/app/service-worker.js create mode 100644 lib/SvelteUi/app/src/assets/favicon.svg diff --git a/lib/SvelteUi/app/index.html b/lib/SvelteUi/app/index.html index 4a138bae..3e5d5417 100644 --- a/lib/SvelteUi/app/index.html +++ b/lib/SvelteUi/app/index.html @@ -3,6 +3,7 @@ + AMS reader diff --git a/lib/SvelteUi/app/manifest.json b/lib/SvelteUi/app/manifest.json new file mode 100644 index 00000000..9f8e30eb --- /dev/null +++ b/lib/SvelteUi/app/manifest.json @@ -0,0 +1,19 @@ +// HTTPS required for this to work +// Remember: +{ + "short_name": "amsreader", + "name": "AMS reader", + "icons": [ + { + "src": "/favicon.svg", + "sizes": "any", + "type": "image/svg+xml", + "purpose": "any" + } + ], + "start_url": "/", + "background_color": "#f3f4f6", + "display": "standalone", + "scope": "/", + "theme_color": "#7c3aed" +} diff --git a/lib/SvelteUi/app/service-worker.js b/lib/SvelteUi/app/service-worker.js new file mode 100644 index 00000000..55683df7 --- /dev/null +++ b/lib/SvelteUi/app/service-worker.js @@ -0,0 +1,11 @@ +self.addEventListener('install', (event) => { + self.skipWaiting(); +}); + +self.addEventListener('activate', (event) => { + return self.clients.claim(); +}); + +self.addEventListener('fetch', function(event) { + event.respondWith(fetch(event.request)); +}); \ No newline at end of file diff --git a/lib/SvelteUi/app/src/App.svelte b/lib/SvelteUi/app/src/App.svelte index 9433ffa5..dae7d266 100644 --- a/lib/SvelteUi/app/src/App.svelte +++ b/lib/SvelteUi/app/src/App.svelte @@ -10,7 +10,7 @@ import Mask from './lib/Mask.svelte'; import FileUploadComponent from "./lib/FileUploadComponent.svelte"; import ConsentComponent from "./lib/ConsentComponent.svelte"; - + let sysinfo = {}; sysinfoStore.subscribe(update => { sysinfo = update; diff --git a/lib/SvelteUi/app/src/assets/favicon.svg b/lib/SvelteUi/app/src/assets/favicon.svg new file mode 100644 index 00000000..b00c064f --- /dev/null +++ b/lib/SvelteUi/app/src/assets/favicon.svg @@ -0,0 +1,19 @@ + + + + Amsleser + + + + + + + + + diff --git a/lib/SvelteUi/app/src/lib/Header.svelte b/lib/SvelteUi/app/src/lib/Header.svelte index 95910656..3d30cafb 100644 --- a/lib/SvelteUi/app/src/lib/Header.svelte +++ b/lib/SvelteUi/app/src/lib/Header.svelte @@ -3,6 +3,7 @@ import { sysinfoStore, getGitHubReleases, gitHubReleaseStore } from './DataStores.js'; import { upgrade, getNextVersion } from './UpgradeHelper'; import { boardtype, hanError, mqttError, priceError, isBusPowered } from './Helpers.js'; + import AmsleserSvg from "./../assets/favicon.svg"; import GitHubLogo from './../assets/github.svg'; import Uptime from "./Uptime.svelte"; import Badge from './Badge.svelte'; diff --git a/lib/SvelteUi/include/AmsWebServer.h b/lib/SvelteUi/include/AmsWebServer.h index 9955baab..bc576203 100644 --- a/lib/SvelteUi/include/AmsWebServer.h +++ b/lib/SvelteUi/include/AmsWebServer.h @@ -82,7 +82,7 @@ private: void indexJs(); void indexCss(); void githubSvg(); - void faviconIco(); + void faviconSvg(); void sysinfoJson(); void dataJson(); diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index 1f7c800d..d52d6641 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -7,6 +7,7 @@ #include "html/index_css.h" #include "html/index_js.h" #include "html/github_svg.h" +#include "html/favicon_svg.h" #include "html/data_json.h" #include "html/dayplot_json.h" #include "html/monthplot_json.h" @@ -67,7 +68,7 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter server.on(F("/mqtt-key"), HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on(F("/github.svg"), HTTP_GET, std::bind(&AmsWebServer::githubSvg, this)); - server.on(F("/favicon.ico"), HTTP_GET, std::bind(&AmsWebServer::faviconIco, this)); + server.on(F("/favicon.svg"), HTTP_GET, std::bind(&AmsWebServer::faviconSvg, this)); server.on(F("/sysinfo.json"), HTTP_GET, std::bind(&AmsWebServer::sysinfoJson, this)); server.on(F("/data.json"), HTTP_GET, std::bind(&AmsWebServer::dataJson, this)); server.on(F("/dayplot.json"), HTTP_GET, std::bind(&AmsWebServer::dayplotJson, this)); @@ -186,10 +187,11 @@ void AmsWebServer::githubSvg() { server.send_P(200, "image/svg+xml", GITHUB_SVG); } -void AmsWebServer::faviconIco() { +void AmsWebServer::faviconSvg() { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("Serving /favicon.ico over http...\n"); - notFound(); //TODO + server.sendHeader(HEADER_CACHE_CONTROL, CACHE_1HR); + server.send_P(200, "image/svg+xml", FAVICON_SVG); } void AmsWebServer::sysinfoJson() { From dbb3eac7093e229d16a617e67117414070429c04 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sun, 15 Jan 2023 10:56:46 +0100 Subject: [PATCH 44/66] Some changes for L&G --- lib/SvelteUi/app/src/lib/Helpers.js | 4 +++- src/LNG.cpp | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index 36a9490c..e5a3e57f 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -31,9 +31,11 @@ export function metertype(mt) { case 8: return "Iskra"; case 9: - return "Landis"; + return "Landis+Gyr"; case 10: return "Sagemcom"; + case 11: + return "L&G"; default: return ""; } diff --git a/src/LNG.cpp b/src/LNG.cpp index e7d818d3..452dcdae 100644 --- a/src/LNG.cpp +++ b/src/LNG.cpp @@ -26,6 +26,7 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da if(descriptor->obis[3] == 7) { if(descriptor->obis[4] == 0) { o170 = getNumber(item); + listType = listType >= 1 ? listType : 1; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o170); } } else if(descriptor->obis[3] == 8) { @@ -36,9 +37,11 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da activeImportCounter = o180 / 1000.0; } else if(descriptor->obis[4] == 1) { o181 = getNumber(item); + listType = listType >= 3 ? listType : 3; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o181); } else if(descriptor->obis[4] == 2) { o182 = getNumber(item); + listType = listType >= 3 ? listType : 3; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o182); } } @@ -46,6 +49,7 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da if(descriptor->obis[3] == 7) { if(descriptor->obis[4] == 0) { o270 = getNumber(item); + listType = listType >= 2 ? listType : 2; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o270); } } else if(descriptor->obis[3] == 8) { @@ -56,9 +60,11 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da activeExportCounter = o280 / 1000.0; } else if(descriptor->obis[4] == 1) { o281 = getNumber(item); + listType = listType >= 3 ? listType : 3; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o281); } else if(descriptor->obis[4] == 2) { o282 = getNumber(item); + listType = listType >= 3 ? listType : 3; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %lu", o282); } } @@ -69,12 +75,14 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da memcpy(str, item->oct.data, item->oct.length); str[item->oct.length] = '\0'; meterId = String(str); + listType = listType >= 2 ? listType : 2; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %s (oct)", str); } else if(descriptor->obis[4] == 1) { char str[item->oct.length+1]; memcpy(str, item->oct.data, item->oct.length); str[item->oct.length] = '\0'; meterModel = String(str); + listType = listType >= 2 ? listType : 2; if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf(" and value %s (oct)", str); } } @@ -85,21 +93,17 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da if(o170 > 0 || o270 > 0) { int32_t sum = o170-o270; if(sum > 0) { - listType = listType >= 1 ? listType : 1; activeImportPower = sum; } else { - listType = listType >= 2 ? listType : 2; activeExportPower = sum * -1; } } if(o181 > 0 || o182 > 0) { activeImportCounter = (o181 + o182) / 1000.0; - listType = listType >= 3 ? listType : 3; } if(o281 > 0 || o282 > 0) { activeExportCounter = (o281 + o282) / 1000.0; - listType = listType >= 3 ? listType : 3; } if((*data) == 0x09) { From 3bc6c75c5a6bde870dcea90d1bcc315780a90f2a Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sun, 15 Jan 2023 11:20:28 +0100 Subject: [PATCH 45/66] Some more changes for L&G --- lib/AmsData/src/AmsData.cpp | 9 ++++++--- src/LNG.cpp | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/AmsData/src/AmsData.cpp b/lib/AmsData/src/AmsData.cpp index ddf02688..8e892cca 100644 --- a/lib/AmsData/src/AmsData.cpp +++ b/lib/AmsData/src/AmsData.cpp @@ -64,7 +64,6 @@ void AmsData::apply(AmsData& other) { this->meterType = other.getMeterType(); this->meterModel = other.getMeterModel(); this->reactiveImportPower = other.getReactiveImportPower(); - this->activeExportPower = other.getActiveExportPower(); this->reactiveExportPower = other.getReactiveExportPower(); this->l1current = other.getL1Current(); this->l2current = other.getL2Current(); @@ -74,9 +73,13 @@ void AmsData::apply(AmsData& other) { this->l3voltage = other.getL3Voltage(); this->threePhase = other.isThreePhase(); this->twoPhase = other.isTwoPhase(); - case 1: - this->activeImportPower = other.getActiveImportPower(); } + + // Moved outside switch to handle meters alternating between sending active and accumulated values + if(other.getListType() == 1 || (other.getActiveImportPower() > 0 || other.getActiveExportPower() > 0)) + this->activeImportPower = other.getActiveImportPower(); + if(other.getListType() == 2 || (other.getActiveImportPower() > 0 || other.getActiveExportPower() > 0)) + this->activeExportPower = other.getActiveExportPower(); } unsigned long AmsData::getLastUpdateMillis() { diff --git a/src/LNG.cpp b/src/LNG.cpp index 452dcdae..23b4ad4e 100644 --- a/src/LNG.cpp +++ b/src/LNG.cpp @@ -96,6 +96,7 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, Da activeImportPower = sum; } else { activeExportPower = sum * -1; + listType = listType >= 2 ? listType : 2; } } From 222a4f13e26b1b185242ea3c6ee1e9a38385ef19 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 17:48:42 +0100 Subject: [PATCH 46/66] Changes after testing --- lib/AmsData/include/AmsData.h | 1 - lib/SvelteUi/app/src/lib/Helpers.js | 2 -- src/LNG.cpp | 2 +- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/AmsData/include/AmsData.h b/lib/AmsData/include/AmsData.h index 7f396c15..c28038b7 100644 --- a/lib/AmsData/include/AmsData.h +++ b/lib/AmsData/include/AmsData.h @@ -12,7 +12,6 @@ enum AmsType { AmsTypeIskra = 0x08, AmsTypeLandisGyr = 0x09, AmsTypeSagemcom = 0x0A, - AmsTypeLng = 0x0B, AmsTypeCustom = 0x88, AmsTypeUnknown = 0xFF }; diff --git a/lib/SvelteUi/app/src/lib/Helpers.js b/lib/SvelteUi/app/src/lib/Helpers.js index e5a3e57f..f1a21569 100644 --- a/lib/SvelteUi/app/src/lib/Helpers.js +++ b/lib/SvelteUi/app/src/lib/Helpers.js @@ -34,8 +34,6 @@ export function metertype(mt) { return "Landis+Gyr"; case 10: return "Sagemcom"; - case 11: - return "L&G"; default: return ""; } diff --git a/src/LNG.cpp b/src/LNG.cpp index 23b4ad4e..97c2087e 100644 --- a/src/LNG.cpp +++ b/src/LNG.cpp @@ -5,7 +5,7 @@ LNG::LNG(const char* payload, uint8_t useMeterType, MeterConfig* meterConfig, DataParserContext &ctx, RemoteDebug* debugger) { LngHeader* h = (LngHeader*) payload; if(h->tag == CosemTypeStructure && h->arrayTag == CosemTypeArray) { - meterType = AmsTypeLng; + meterType = AmsTypeLandisGyr; this->packageTimestamp = ctx.timestamp; uint8_t* ptr = (uint8_t*) &h[1]; From af630615db444ce7bb8276761baa0d83c344384e Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 17:49:01 +0100 Subject: [PATCH 47/66] Changes after testing --- lib/SvelteUi/src/AmsWebServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/SvelteUi/src/AmsWebServer.cpp b/lib/SvelteUi/src/AmsWebServer.cpp index d52d6641..2b211d4b 100644 --- a/lib/SvelteUi/src/AmsWebServer.cpp +++ b/lib/SvelteUi/src/AmsWebServer.cpp @@ -879,7 +879,7 @@ void AmsWebServer::configurationJson() { snprintf_P(buf, BufferSize, CONF_GPIO_JSON, gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(), gpioConfig->apPin == 0xff ? "null" : String(gpioConfig->apPin, 10).c_str(), - gpioConfig->hanPin == 0xff ? "null" : String(gpioConfig->hanPin, 10).c_str(), + gpioConfig->ledPin == 0xff ? "null" : String(gpioConfig->ledPin, 10).c_str(), gpioConfig->ledInverted ? "true" : "false", gpioConfig->ledPinRed == 0xff ? "null" : String(gpioConfig->ledPinRed, 10).c_str(), gpioConfig->ledPinGreen == 0xff ? "null" : String(gpioConfig->ledPinGreen, 10).c_str(), From 508b2e6c45c1ecb5ca87f452796d512d8b2414db Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 17:51:50 +0100 Subject: [PATCH 48/66] Icon for safari --- lib/SvelteUi/app/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/SvelteUi/app/index.html b/lib/SvelteUi/app/index.html index 3e5d5417..b1a58959 100644 --- a/lib/SvelteUi/app/index.html +++ b/lib/SvelteUi/app/index.html @@ -4,6 +4,7 @@ + AMS reader From 8fd411c1d67fd6241a88ec1f70b3880e0c516516 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:13:20 +0100 Subject: [PATCH 49/66] Updated build --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 568eea05..a03d2899 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -40,6 +40,18 @@ jobs: run: | python -m pip install --upgrade pip pip install -U platformio css_html_js_minify + - name: Set up node + uses: actions/setup-node@v1 + with: + node-version: '16.x' + - name: Build with node + run: | + cd lib/SvelteUi/app + npm ci + npm run build + cd - + env: + CI: false - name: PlatformIO lib install run: pio lib install - name: PlatformIO run From cce5d75fd726bcab2ff6f0cddaed5789a6c13836 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:13:54 +0100 Subject: [PATCH 50/66] Updated build --- .github/workflows/build.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a03d2899..f3123a48 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,17 +41,17 @@ jobs: python -m pip install --upgrade pip pip install -U platformio css_html_js_minify - name: Set up node - uses: actions/setup-node@v1 - with: - node-version: '16.x' - - name: Build with node - run: | - cd lib/SvelteUi/app - npm ci - npm run build - cd - - env: - CI: false + uses: actions/setup-node@v1 + with: + node-version: '16.x' + - name: Build with node + run: | + cd lib/SvelteUi/app + npm ci + npm run build + cd - + env: + CI: false - name: PlatformIO lib install run: pio lib install - name: PlatformIO run From 6c3dca93444a5c0e501b8bb16b34eb0ebf65852c Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:15:32 +0100 Subject: [PATCH 51/66] Updated build --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f3123a48..d2a40124 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,6 +8,7 @@ on: - scripts/** - web/** - platformio.ini + - .github/workflows/** branches: - '*' tags: From fb2cfdfe011dbd8be08ef5d5fa60c0048cdd63fc Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:28:08 +0100 Subject: [PATCH 52/66] Trying to fix build --- platformio.ini | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platformio.ini b/platformio.ini index 017622fe..132d0bb5 100755 --- a/platformio.ini +++ b/platformio.ini @@ -21,6 +21,7 @@ board = esp12e board_build.ldscript = eagle.flash.4m2m.ld build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions lib_ldf_mode = off +lib_compat_mode = off lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP8266httpUpdate, ${common.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} @@ -32,6 +33,7 @@ board = esp32dev board_build.f_cpu = 160000000L build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions lib_ldf_mode = off +lib_compat_mode = off lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} @@ -50,6 +52,7 @@ board_build.f_cpu = 160000000L board_build.f_flash = 40000000L build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions lib_ldf_mode = off +lib_compat_mode = off lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} @@ -61,6 +64,7 @@ board = esp32-solo1 board_build.f_cpu = 160000000L build_flags = -D WEBSOCKET_DISABLED=1 -DFRAMEWORK_ARDUINO_SOLO1 -fexceptions lib_ldf_mode = off +lib_compat_mode = off lib_deps = ${esp32.lib_deps} lib_ignore = ${common.lib_ignore} extra_scripts = ${common.extra_scripts} From 7a36082564fe687d64b7bf0b0fd55e4acf7dbfd7 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:34:47 +0100 Subject: [PATCH 53/66] Trying stuff to get build working --- lib/{AmsMqttHandler => AmsData}/include/AmsMqttHandler.h | 0 .../src/HomeAssistantMqttHandler.cpp | 6 +++++- platformio.ini | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) rename lib/{AmsMqttHandler => AmsData}/include/AmsMqttHandler.h (100%) diff --git a/lib/AmsMqttHandler/include/AmsMqttHandler.h b/lib/AmsData/include/AmsMqttHandler.h similarity index 100% rename from lib/AmsMqttHandler/include/AmsMqttHandler.h rename to lib/AmsData/include/AmsMqttHandler.h diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 80ef0012..2629b65f 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -280,7 +280,11 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, EntsoeApi* eapi, Energ String uom = String(sensor.uom); if(strncmp(sensor.devcl, "monetary", 8) == 0) { if(eapi == NULL) continue; - uom = String(eapi->getCurrency()); + if(strncmp(sensor.path, "prices", 5) == 0) { + uom = String(eapi->getCurrency()) + "/kWh"; + } else { + uom = String(eapi->getCurrency()); + } } if(strncmp(sensor.path, "peaks[", 6) == 0) { if(peaks >= peakCount) continue; diff --git a/platformio.ini b/platformio.ini index 132d0bb5..627f9b0a 100755 --- a/platformio.ini +++ b/platformio.ini @@ -2,7 +2,7 @@ extra_configs = platformio-user.ini [common] -lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, EntsoePriceApi, EnergyAccounting, AmsMqttHandler, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi +lib_deps = EEPROM, LittleFS, DNSServer, 256dpi/MQTT@2.5.0, OneWireNg@0.10.0, DallasTemperature@3.9.1, EspSoftwareSerial@6.14.1, https://github.com/gskjold/RemoteDebug.git, Time@1.6.1, Timezone@1.2.4, AmsConfiguration, AmsData, AmsDataStorage, HwTools, Uptime, AmsDecoder, EntsoePriceApi, EnergyAccounting, RawMqttHandler, JsonMqttHandler, DomoticzMqttHandler, HomeAssistantMqttHandler, SvelteUi lib_ignore = OneWire extra_scripts = pre:scripts/addversion.py From 43fbca7099c8218a5aa3bb2e06afc697c20fb163 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:42:09 +0100 Subject: [PATCH 54/66] Update release build --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 35 +++++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d2a40124..9d5f84ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -52,7 +52,7 @@ jobs: npm run build cd - env: - CI: false + CI: true - name: PlatformIO lib install run: pio lib install - name: PlatformIO run diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9f958c7..a67a99fe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -41,12 +41,39 @@ jobs: run: | python -m pip install --upgrade pip pip install -U platformio css_html_js_minify + + - name: Set up node + uses: actions/setup-node@v1 + with: + node-version: '16.x' + - name: Build with node + run: | + cd lib/SvelteUi/app + npm ci + npm run build + cd - + env: + CI: false + - name: PlatformIO lib install run: pio lib install - - name: PlatformIO run - run: pio run - - name: Create zip files - run: /bin/sh scripts/mkzip.sh + - name: Build ESP8266 firmware + run: pio run -e esp8266 + - name: Create ESP8266 zip file + run: /bin/sh scripts/esp8266/mkzip.sh + - name: Build ESP32 firmware + run: pio run -e esp32 + - name: Create ESP32 zip file + run: /bin/sh scripts/esp32/mkzip.sh + - name: Build ESP32-S2 firmware + run: pio run -e esp32s2 + - name: Create ESP32-S2 zip file + run: /bin/sh scripts/esp32s2/mkzip.sh + - name: Build ESP32-SOLO firmware + run: pio run -e esp32solo + - name: Create ESP32-SOLO zip file + run: /bin/sh scripts/esp32solo/mkzip.sh + - name: Create Release id: create_release uses: actions/create-release@v1.0.0 From 1f3c32e80a7f15fa47c15a75cd8cb9342c1ee67e Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 18:57:11 +0100 Subject: [PATCH 55/66] Adding secrets to build --- .github/workflows/build.yml | 6 ++++++ .github/workflows/release.yml | 6 ++++++ lib/EntsoePriceApi/src/EntsoeApi.cpp | 2 ++ platformio.ini | 13 +++++++++---- 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9d5f84ed..d39778a5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,6 +23,12 @@ jobs: steps: - name: Check out code from repo uses: actions/checkout@v1 + + - name: Inject secrets into ini file + run: | + sed -i 's/NO_AMS2MQTT_PRICE_KEY/AMS2MQTT_PRICE_KEY="${{secrets.AMS2MQTT_PRICE_KEY}}"/g' platformio.ini + sed -i 's/NO_AMS2MQTT_PRICE_AUTHENTICATION/AMS2MQTT_PRICE_AUTHENTICATION="${{secrets.AMS2MQTT_PRICE_AUTHENTICATION}}"/g' platformio.ini + - name: Cache Python dependencies uses: actions/cache@v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a67a99fe..6ec08587 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,6 +23,12 @@ jobs: env: GITHUB_REF: ${{ github.ref }} run: echo "GITHUB_TAG=$(echo ${GITHUB_REF##*/})" >> $GITHUB_ENV + + - name: Inject secrets into ini file + run: | + sed -i 's/NO_AMS2MQTT_PRICE_KEY/AMS2MQTT_PRICE_KEY="${{secrets.AMS2MQTT_PRICE_KEY}}"/g' platformio.ini + sed -i 's/NO_AMS2MQTT_PRICE_AUTHENTICATION/AMS2MQTT_PRICE_AUTHENTICATION="${{secrets.AMS2MQTT_PRICE_AUTHENTICATION}}"/g' platformio.ini + - name: Cache Python dependencies uses: actions/cache@v1 with: diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 2d64ae5a..50f7b506 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -41,12 +41,14 @@ void EntsoeApi::setup(EntsoeConfig& config) { http.useHTTP10(true); #if defined(AMS2MQTT_PRICE_KEY) + #pragma message("Using AMS2MQTT_PRICE_KEY from environment") key = new uint8_t[16] AMS2MQTT_PRICE_KEY; hub = true; #else hub = false; #endif #if defined(AMS2MQTT_PRICE_AUTHENTICATION) + #pragma message("Using AMS2MQTT_PRICE_AUTHENTICATION from environment") auth = new uint8_t[16] AMS2MQTT_PRICE_AUTHENTICATION; hub = hub && true; #else diff --git a/platformio.ini b/platformio.ini index 627f9b0a..7b1fde3e 100755 --- a/platformio.ini +++ b/platformio.ini @@ -10,6 +10,11 @@ extra_scripts = lib/DomoticzMqttHandler/scripts/generate_includes.py lib/HomeAssistantMqttHandler/scripts/generate_includes.py lib/SvelteUi/scripts/generate_includes.py +build_flags = + -D WEBSOCKET_DISABLED=1 + -D NO_AMS2MQTT_PRICE_KEY + -D NO_AMS2MQTT_PRICE_AUTHENTICATION + -fexceptions [esp32] lib_deps = WiFi, ESPmDNS, WiFiClientSecure, HTTPClient, FS, Update, HTTPUpdate, WebServer, ${common.lib_deps} @@ -19,7 +24,7 @@ platform = espressif8266@3.2.0 framework = arduino board = esp12e board_build.ldscript = eagle.flash.4m2m.ld -build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions +build_flags = ${common.build_flags} lib_ldf_mode = off lib_compat_mode = off lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP8266httpUpdate, ${common.lib_deps} @@ -31,7 +36,7 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/v2. framework = arduino board = esp32dev board_build.f_cpu = 160000000L -build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions +build_flags = ${common.build_flags} lib_ldf_mode = off lib_compat_mode = off lib_deps = ${esp32.lib_deps} @@ -50,7 +55,7 @@ board_build.variant = esp32s2 board_build.flash_mode = qio board_build.f_cpu = 160000000L board_build.f_flash = 40000000L -build_flags = -D WEBSOCKET_DISABLED=1 -fexceptions +build_flags = ${common.build_flags} lib_ldf_mode = off lib_compat_mode = off lib_deps = ${esp32.lib_deps} @@ -62,7 +67,7 @@ platform = https://github.com/tasmota/platform-espressif32/releases/download/v2. framework = arduino board = esp32-solo1 board_build.f_cpu = 160000000L -build_flags = -D WEBSOCKET_DISABLED=1 -DFRAMEWORK_ARDUINO_SOLO1 -fexceptions +build_flags = ${common.build_flags} -DFRAMEWORK_ARDUINO_SOLO1 lib_ldf_mode = off lib_compat_mode = off lib_deps = ${esp32.lib_deps} From fb1d343ee390c8b0de875619092706a8e675b3fb Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 19:03:07 +0100 Subject: [PATCH 56/66] Removed debugging --- lib/EntsoePriceApi/src/EntsoeApi.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/EntsoePriceApi/src/EntsoeApi.cpp b/lib/EntsoePriceApi/src/EntsoeApi.cpp index 50f7b506..2d64ae5a 100644 --- a/lib/EntsoePriceApi/src/EntsoeApi.cpp +++ b/lib/EntsoePriceApi/src/EntsoeApi.cpp @@ -41,14 +41,12 @@ void EntsoeApi::setup(EntsoeConfig& config) { http.useHTTP10(true); #if defined(AMS2MQTT_PRICE_KEY) - #pragma message("Using AMS2MQTT_PRICE_KEY from environment") key = new uint8_t[16] AMS2MQTT_PRICE_KEY; hub = true; #else hub = false; #endif #if defined(AMS2MQTT_PRICE_AUTHENTICATION) - #pragma message("Using AMS2MQTT_PRICE_AUTHENTICATION from environment") auth = new uint8_t[16] AMS2MQTT_PRICE_AUTHENTICATION; hub = hub && true; #else From fad6ada1e0ec70f606068c0c47b3e741da11e15c Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 19:15:57 +0100 Subject: [PATCH 57/66] Updated release --- .github/workflows/release.yml | 87 ++++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6ec08587..a3e5b4b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,22 +63,6 @@ jobs: - name: PlatformIO lib install run: pio lib install - - name: Build ESP8266 firmware - run: pio run -e esp8266 - - name: Create ESP8266 zip file - run: /bin/sh scripts/esp8266/mkzip.sh - - name: Build ESP32 firmware - run: pio run -e esp32 - - name: Create ESP32 zip file - run: /bin/sh scripts/esp32/mkzip.sh - - name: Build ESP32-S2 firmware - run: pio run -e esp32s2 - - name: Create ESP32-S2 zip file - run: /bin/sh scripts/esp32s2/mkzip.sh - - name: Build ESP32-SOLO firmware - run: pio run -e esp32solo - - name: Create ESP32-SOLO zip file - run: /bin/sh scripts/esp32solo/mkzip.sh - name: Create Release id: create_release @@ -91,6 +75,19 @@ jobs: draft: false prerelease: false + - name: Build esp8266 firmware + run: pio run -e esp8266 + - name: Create esp8266 zip file + run: /bin/sh scripts/esp8266/mkzip.sh + - name: Upload esp8266 binary to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: .pio/build/esp8266/firmware.bin + asset_name: ams2mqtt-esp8266-${{ steps.release_tag.outputs.tag }}.bin + asset_content_type: application/octet-stream - name: Upload esp8266 zip to release uses: actions/upload-release-asset@v1 env: @@ -100,6 +97,20 @@ jobs: asset_path: esp8266.zip asset_name: ams2mqtt-esp8266-${{ steps.release_tag.outputs.tag }}.zip asset_content_type: application/zip + + - name: Build esp32 firmware + run: pio run -e esp32 + - name: Create esp32 zip file + run: /bin/sh scripts/esp32/mkzip.sh + - name: Upload esp32 binary to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: .pio/build/esp32/firmware.bin + asset_name: ams2mqtt-esp32-${{ steps.release_tag.outputs.tag }}.bin + asset_content_type: application/octet-stream - name: Upload esp32 zip to release uses: actions/upload-release-asset@v1 env: @@ -109,6 +120,20 @@ jobs: asset_path: esp32.zip asset_name: ams2mqtt-esp32-${{ steps.release_tag.outputs.tag }}.zip asset_content_type: application/zip + + - name: Build esp32s2 firmware + run: pio run -e esp32s2 + - name: Create esp32s2 zip file + run: /bin/sh scripts/esp32s2/mkzip.sh + - name: Upload esp32s2 binary to release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: .pio/build/esp32s2/firmware.bin + asset_name: ams2mqtt-esp32s2-${{ steps.release_tag.outputs.tag }}.bin + asset_content_type: application/octet-stream - name: Upload esp32s2 zip to release uses: actions/upload-release-asset@v1 env: @@ -119,24 +144,10 @@ jobs: asset_name: ams2mqtt-esp32s2-${{ steps.release_tag.outputs.tag }}.zip asset_content_type: application/zip - - name: Upload esp8266 binary to release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: .pio/build/esp8266/firmware.bin - asset_name: ams2mqtt-esp8266-${{ steps.release_tag.outputs.tag }}.bin - asset_content_type: application/octet-stream - - name: Upload esp32 binary to release - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: .pio/build/esp32/firmware.bin - asset_name: ams2mqtt-esp32-${{ steps.release_tag.outputs.tag }}.bin - asset_content_type: application/octet-stream + - name: Build esp32solo firmware + run: pio run -e esp32solo + - name: Create esp32solo zip file + run: /bin/sh scripts/esp32solo/mkzip.sh - name: Upload esp32solo binary to release uses: actions/upload-release-asset@v1 env: @@ -146,12 +157,12 @@ jobs: asset_path: .pio/build/esp32solo/firmware.bin asset_name: ams2mqtt-esp32solo-${{ steps.release_tag.outputs.tag }}.bin asset_content_type: application/octet-stream - - name: Upload esp32s2 binary to release + - name: Upload esp32solo zip to release uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: .pio/build/esp32s2/firmware.bin - asset_name: ams2mqtt-esp32s2-${{ steps.release_tag.outputs.tag }}.bin - asset_content_type: application/octet-stream + asset_path: esp32solo.zip + asset_name: ams2mqtt-esp32solo-${{ steps.release_tag.outputs.tag }}.zip + asset_content_type: application/zip From 762c17ca8e14a9b76619981e69627b9f4e117486 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 19:48:24 +0100 Subject: [PATCH 58/66] Updated readme and example ini file --- README.md | 4 ++-- platformio-user.ini-example | 17 +++++++---------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index c32a12f7..fb052922 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# AMS MQTT Bridge +# AMS Reader This code is designed to decode data from electric smart meters installed in many countries in Europe these days. The data is presented in a graphical web interface and can also send the data to a MQTT broker which makes it suitable for home automation project. Originally it was only designed to work with Norwegian meters, but has since been adapter to read any IEC-62056-7-5 or IEC-62056-21 compliant meters. -Later development have added Energy usage graph for both day and month, as well as future energy price (Prices only available for ESP32). The code can run on any ESP8266 or ESP32 hardware which you can read more about in the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki). If you don't have the knowledge to set up a ESP device yourself, have a look at the shop at [amsleser.no](https://amsleser.no/). +Later development have added Energy usage graph for both day and month, as well as future energy price. The code can run on any ESP8266 or ESP32 hardware which you can read more about in the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki). If you don't have the knowledge to set up a ESP device yourself, have a look at the shop at [amsleser.no](https://amsleser.no/). diff --git a/platformio-user.ini-example b/platformio-user.ini-example index 276bb8a1..a6c816ce 100644 --- a/platformio-user.ini-example +++ b/platformio-user.ini-example @@ -2,19 +2,16 @@ default_envs = dev [env:dev] -platform = espressif8266 +platform = espressif8266@3.2.0 +framework = arduino board = esp12e board_build.ldscript = eagle.flash.4m2m.ld -framework = arduino -lib_deps = ${common.lib_deps} -lib_ignore = ${common.lib_ignore} +build_flags = ${common.build_flags} -D DEBUG_MODE=1 +lib_ldf_mode = off lib_compat_mode = off -build_flags = - -D WEBSOCKET_DISABLED=1 - -D DEBUG_MODE=1 -extra_scripts = - pre:scripts/addversion.py - scripts/makeweb.py +lib_deps = ESP8266WiFi, ESP8266mDNS, ESP8266WebServer, ESP8266HTTPClient, ESP8266httpUpdate, ${common.lib_deps} +lib_ignore = ${common.lib_ignore} +extra_scripts = ${common.extra_scripts} monitor_speed = 115200 ; If serial port is shared with HAN, use baud and parity configured for meter monitor_flags = --parity From 6ba2b4060e79c971a86761b05f88b87435da67fc Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 17 Jan 2023 19:55:00 +0100 Subject: [PATCH 59/66] Update images for readme and wiki --- images/dashboard.png | Bin 139578 -> 176834 bytes images/dayplot.png | Bin 18838 -> 32689 bytes images/future-energy-price.png | Bin 14133 -> 36092 bytes images/main-header.png | Bin 10357 -> 22114 bytes images/monthplot.png | Bin 22154 -> 34923 bytes images/real-time-calculation.png | Bin 11051 -> 23286 bytes images/sensor-displays.png | Bin 35410 -> 33699 bytes images/status-bar.png | Bin 12229 -> 0 bytes images/tempsensors.png | Bin 18434 -> 33130 bytes 9 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 images/status-bar.png diff --git a/images/dashboard.png b/images/dashboard.png index 29eb79923a3f19d2df005fdaefbd9183505556db..66083b8703e8d82cd860e33d62113e0c97fecd79 100644 GIT binary patch literal 176834 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

9`$s@&dIkCgdw})fH!z}}%du+rQ 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 literal 139578 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

+4hP{Jh^elX2ho}v!UIb^Rk7H>zO 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 literal 18838 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%0ACzHe85!^`N>%T;P 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 B1lRxo diff --git a/images/future-energy-price.png b/images/future-energy-price.png index 119ed1d6227cea51cc78cce472450e32f950089a..fa956585f659f8622be501955e7233299d89336c 100644 GIT binary patch literal 36092 zcmeFZbx>VP(>J<9kOT`Z!6CT2TX1)G*tok}2p*i^65QS0-GjTkyTjedbI!?m>V8$X z-m3fk_YRfCS~ER8-M{JX>6x`iu&lHQ9P~$M0000dCMqZo06>Cn-yppE^~))}%?kj4 zA9Yhyb&%I{#<#JvHZrv^#CLGDF~m1?F*O1JTo!T?&F!{0Ec{>1QPsdYSmU~&RKMc@ z@9+6)xYHV93YWTZn+(OMBiY*7p|~TSXT8&QdGEwarby#wie^6E4JI+e!@Ie(^*&P* ztghqAqLbvW zXXDR$rp!!U&=DrL8uurP*O@3zs(KeKg2Z66QB)cM*cFeBz>03{<6vD>15Ntn7@Q-f z(oo=yHG75cmNd?%S%2=lyB4$tJ?7$F;X}cd&JsD7gtIvB=jW$I)|AZ>{EY^1H`nv9 ziI@=vZ1&d?OMJrJm?=Btr|ak4_{}7~a+kOkq1f)xTg0kZef!hg zy2bfeAd5t_%49lMOQ{ckXKldG`GXaPL2sf_+IFI2?R?&71zGxc6*b42>G;x$O=+x` zImf!?x)VM9*l0sa*yOkmPf_HQIu+II8NC3o9x!8DP!265QE z(k`XNd3RC2=tQ|=H+lyz@!CFOnJpTcXmzj9TxACc-lhuEe1n_F`nqW7pGA2a1)u2h z5bU}y?P{;Yw6m1APcP3PzF)N4|Jf;Mb-JqFf?Q2X}$qZg@qE}Toa-ad!qt!j@&XcLTgiA z!dN5=77Syai@H=kKMzKweLes;J}fv0J;Eyb{`2RF_edJN z#KUo!(>K&h0o(G`Po5F)woXq*-FkQV$vN>wD%bcwkei5BMGp7EVsfE7Q4ClrluJ!!JX%+ zG@RzFa+>y;=4Xjte`c`qqQNMG%bNsv*ℜE(z0OVN2L}cQN-_hT3qF5mzy#e#hV$ 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 Ml=6p43DYnC4?c8VJOBUy literal 14133 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 JLgiV=e*>nNk6!=) diff --git a/images/main-header.png b/images/main-header.png index 738442a3e53164a796af6266ffb56b6ee9af1785..80cb3fa986e42be45b400ba1641435a8d94b30f1 100644 GIT binary patch literal 22114 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

~L#;X>N?<$9YoLL1Fo(1{u0bqF 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%0AeTibrm{>6A5D56W+Rh}V)!q=Vh6MDNxW8p1v zc1R^O2LYTHx3HhPZ9e>z!=^F0(3LT%rRrxQAfHi?t`UN2k6d;>n4WyCrxo8IUJ7G2 zcei^M2+^CK&cI^_!!sA1_=Mv)e@RAbMwl9&d`e5b3%Y8(3mT3zsWnq_gChBR!}l&l z+{W)>jzl#Ly6?LvO_H){%%?_*C49*CRg#O~>l z6X)9;g+De}qk@2%8Hdhy+{wg*++n_{Fl500@SDB4jQ79sZGYMDK2eaf2Q4Jj0vu-h z+Os*6K`@-_Ba8-00G_9*%XDSAk9mIw%$9F2&i3uMy#2H(E15+aPLEOBI}7RxbmY1I ztZZR$pmCQdte#^0pXU`L-A0F$A!YE}tZB-=OjUyynw*f7_Q9|<)~3eRqN86zfjn=e!p5quS2z_!2ufD_R2o3^En8M54gi5?^6zv$6RkLI_+6FGb&kOberqc>^T|yPs?d5W4V-Gnfo)FL=8wC zm`TDNUQ;O5m84nzXGV6{243ENM)AAY_$Y~nU*i7KvWVNjl%$`Z*X4Wq6^7}CGs`NA z$KE4UT#Y{$u3xUux|zI!v6Oa4V*DAu2`MIcY13-|qn8*nH`iAL|J}jCk#p6Dmq_Av zsAW(YYJSExb9}aH&Pk)T{`G}gcd+EnvXB4hWpUk$-n?4F&3Z63=Aio>djo!xJsx=G zU78Mqm%oW<{xf#jR*xVQ@bYT5ti-*G;%aL#?1riB8%V;K!!Ti+6JK{-_TpAlmp-QZ zSf9qx$rgXsDcMP_KGOYvC=e^N%T11fau#XUHVzTd>Nrh0BQ2i_7+dJoJ0n`tNc#Wc zL74ZRH9n$mylB90iA9eYRU(x7lmCm~EtsWW0pCJf98LiLRDJ%%j$&TBc4K38@Rix= z{rsnT`R~Xpk8A9rOsTWxkid(Jcu>i1Y&BOx?*ADp$gGmOWH)lky#^b5aoSH&JYz)v z|Bl9NJS(!T>^--8aizLwM2lC)gE`R+8^(sYT7&Unq1j!X_dmqeyJQslLHw)v^aask zonQCee)NE^19w;MMXoM2>>ql})&#XO!rI*!87G%im<)7^6vM3Mw%KeEtxDK`CU(2!+1SNr452wORnxp z(Ep*AaW~TbacJP>yeK9a>V;gjoOXI6irPz);yekd+!=#NJty3>wzFTUz z@WG38`BsDu$|I+r?ZL*^pXU9alzbheUE~ZeKe#70edN#v6Gy=+iOSGxVQ?Yhcl#t* z_=ni``!rWRbuviw=IvHJ5vIH6|D})GLn2twm?mE$A4^)Ip6ee`sGDv1Ic!H~mZdcS z2y^U~{S^S8=8$fwp&Lenl58F`4E(>We&SP%1RWgpVEfNi$}eEG9lEeXC&ZB1f7pF( zi7}$(%yix{hF%lD^u5%&WmqG|601+~Au{#kU;1Gf9MC@u{ogWJX}C<+(BCdq+-Dew zcrPGV8Cdz~w6U732#`Z}R!sXE@dKuoUG~WJ_Kfeg1y{Z#fYV literal 22154 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

  • E9;dqNUBpQE(i|p5nq!$W6>Q&{ltBt{cIP@`}M{X>;c(<44>I!YX^NqJ1-?hBofs^TcQ_c#4=E*jxLj%^vQ1 z+M^KztsJg!7&!wm247HXz`=ZE*jZ{mor`mG?}(U(P+R+n{qv02*j6ThApQ-uFKPHgIUw*LUy7h`Ct^In!sSAILM%l~}Wkx~?8k){Li1W&Pub_bo3BlfRNl zQ}f*ru<#96GfFd=bXHcrT4}_w@B3G+v(!sS&kZ5J_r5pvKD6`M(Yz*TeIwAdmhR-A z9+yQrFEjDx^o7Sw0@+~FvT8zY`sTD*`F?Xt%T(#k+BR5gcDiQ~8;EsO`|G<0&ayZ#lXbP!xc8@;i+oUWgokxpNuJ zJaFmaapra3N0I;WX#Xf5Ld%jL(T~nNE{PGtrtj7(%uwQBU#O52atkauI8Rp%v?^zN z@N+c60O7C?Nt#?2XR7mf@w>4vS+0wP%zCMB5(exV%99EwTuhq^5*Kk4i%%?3; z))%{8b~-o!IGBL6q1q7nSjLBI$;huTWp8QL8wgMRMt@#Wk+$i_V^9)nuvbiKD~}N< z02Ri|LKSu64xipZ7HrFDMV;3S3KrCMwNm=aqf0+}?>tuwFXq!C)XxXnqp@%{UOFNJ zNGQg~5lQG?jHW;(0HT*28x7Ula^K$p;e`>z+hjZ2`xyDz+7bjRSU#Kgo)CMNSu9PY zq8!m+GPI=RnTLM(kE$U0yXQi78tt9NdW|$Y?>Ss_(J~roXV$eaF6u=$z|&#hfeQnc zux4$+8)?9zUlp&8^9AB>Q<-oy$-eCv9dCJQ*lPWaZ)TMr;$ONEUYmi{P<&hASjmds zG$=S_7}X4@=l2sXvu?p=p?gcIN@d3u)m|fe;5z``IxWQg9&X5Z$Jt& z&AQm|+bY0M-F?P`K#GOp0k6tVqLu_N=}K1>m)mJ{%EVv!B6IfN|Zar z@8t>Xoiw*_aTsN1W>IUDk5`J7Eb%9-9v71ESsU$Q&0Bb}t6>9ncKZ=5Rk5f4pcFlo zL=e|quMWeb`(=e;iW}eKYpBy^GFLL${!M&c;{LldbCt$RCpJCpjXyObBO}eJomE9n z3zPfjwBX`n{#`7`+rjIE#*uQ+z()}sBiZicBTSnT&o0D(g+QjNVxMNGeq?zSx2rl<}x?B!69k-46oDersfeh13eR@<>S5U~xud9W8T1RtPb3nBbz$AC5-*N}<1iZ(nM z^`heg#)AS=4Gl*tT*EH@YyFQlV;%Kh&!tt}BFX^u5f;4|aPp@K=c;ILp$sa(-W___549n@(iFL&e%NMRiT3&<@1- zTyQ>ji@`#2Tfe;8sGSkhlkrWP{Z8n^40_xf{{Bgh-Fk<|))zkK`Il4$XzDHQjw{F7M* zo;5f<&0f7emz_Hs|N1tsh{`z?+9Zefm7J!8%9Dd*IK%m;<*(0`tEafh5ZF(xm0!bD zi$j+NHBJ6`7YMpK zsrIjZ8-Tb=tA&PA%lxbc&x3S>A#vl+y?N~FSP0upXmZ)!DuxqTskLL%PYyQ+O8APS z_3dD44ARk4586nL>uRK4 zO3wm^#klR@tnlX`B^~Q|<^uVL(W4_+L;<K!H>S?@`H?=32

    U$d(?>XJ{+y za}!%p1G65F6Yu`?6_ra|Q`j=>_g)Bki}S7u>-xWEB=^fm^HDD7^}}IIOOW@WvLQcwfVY#=5Fc-$HeT{+A89TpBvw-V1{JaoS%a`j<)E(nGPj~ zLXi#zMnytK2JQ37J@ma2=8+~JkN%q3$P9! z>})R1J8CC9#SAAYS>H$`iI10#{4)ye$4siVoM_h$^lvEROpDEA05!Y!6eRx6(glCH9VV1Vvg@&xuG-4htg1yv@B{`rRdji zt#qFo3i?IT%SK|(yN^mQ0E+h(Gr6rN>?$@lOlN(PGqL_XBJVFFd2zvxSHZB z?Gvi{F+reMP3%==KS#)y{$C&UNhKW?^%7z_XJ~(WIE6hYzNB1M=XU*EWYK@ zmJY;v+RY;>8onkCqbQrbVBkQdQ_Br1A6M#9WxP3U6(F5sFN(V{x1*VEOVah-$_>-y zDW2Vr^0_B~uP6QBZm-no@2l2q^%!GHDiRDlJCFO~N^l8rOwB1`;XQ?%$QiyqHNSNGijvl=L)!70O?qWo`Fk39dM)qF^boi!#Pl zE~=NfeBCNd8#t{J>teBX5-k`tY)T?iGM8*$Ow3q1#OOb3<7izba%JL($W*&l(%s)} z1W_ID?}jR1YAzp}FjeDy?U%Fu%_Kb0 zjw9*lI$l(Y#WKA06fK&&b*s*r$)?U@a=zp)bC^5%Qu!B4U_-!oseK|yVQ>3!M5xa$ zJdP&u6mi=HW4DPp*i@5Uzj*ll4U^;SS9PAzi1DP>U)QE_FYIL(Ty;wldk-?^)F#Yz zUk}xA^-%@0N9f^~PSx7TEfvJ y(~4eAygjWye*i;Qw*6sZ*GY4BW3Z+E%TXeO&3 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 aa4a5JHTFI^UG?UF4T7F)KPyyy{r*2)neRjZ diff --git a/images/real-time-calculation.png b/images/real-time-calculation.png index e5af9129fb803ec5277b47139b5bd0f7f51fad65..2b20e3d4ed4202d78e131b25a44dd97595ac1c7c 100644 GIT binary patch literal 23286 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 z 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 literal 11051 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 LmMWGs@cn-PSyhHC literal 35410 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 diff --git a/images/tempsensors.png b/images/tempsensors.png index 7484f1707693e23b66a10ec64f87710557e36630..47701be4c144baa85c5aa5357dd16247a3176c05 100644 GIT binary patch literal 33130 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 Date: Tue, 17 Jan 2023 19:56:28 +0100 Subject: [PATCH 60/66] Update readme --- README.md | 2 +- webui.png | Bin 139578 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 webui.png diff --git a/README.md b/README.md index fb052922..30232a50 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ This code is designed to decode data from electric smart meters installed in man Later development have added Energy usage graph for both day and month, as well as future energy price. The code can run on any ESP8266 or ESP32 hardware which you can read more about in the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki). If you don't have the knowledge to set up a ESP device yourself, have a look at the shop at [amsleser.no](https://amsleser.no/). - + Go to the [WiKi](https://github.com/gskjold/AmsToMqttBridge/wiki) for information on how to get your own device! And find the latest prebuilt firmware file at the [release section](https://github.com/gskjold/AmsToMqttBridge/releases). diff --git a/webui.png b/webui.png deleted file mode 100644 index b39ea7a648a26aedf9920d419694301f49840566..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139578 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 z 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 From c5756f0cba24ee625f52d4f0b89c03a0f278ae2f Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 21 Jan 2023 13:43:11 +0100 Subject: [PATCH 61/66] Renamed repo --- lib/ClassicUi/html/head.html | 6 +++--- lib/ClassicUi/html/meter.html | 2 +- lib/ClassicUi/html/restartwait.html | 2 +- lib/ClassicUi/html/setup.html | 2 +- .../app/src/lib/ConfigurationPanel.svelte | 16 ++++++++-------- lib/SvelteUi/app/src/lib/ConsentComponent.svelte | 2 +- lib/SvelteUi/app/src/lib/DataStores.js | 2 +- lib/SvelteUi/app/src/lib/Header.svelte | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/ClassicUi/html/head.html b/lib/ClassicUi/html/head.html index ef742621..bc831aa2 100644 --- a/lib/ClassicUi/html/head.html +++ b/lib/ClassicUi/html/head.html @@ -48,7 +48,7 @@

    -
    AMS reader ${version}
    +
    AMS reader ${version}
      @@ -66,7 +66,7 @@ NTP Price API
      - Documentation + Documentation
  • @@ -96,7 +96,7 @@
    • - +
    • diff --git a/lib/ClassicUi/html/meter.html b/lib/ClassicUi/html/meter.html index 5659c543..076fcd60 100644 --- a/lib/ClassicUi/html/meter.html +++ b/lib/ClassicUi/html/meter.html @@ -65,7 +65,7 @@
    - Known hardware configurations + Known hardware configurations
    diff --git a/lib/ClassicUi/html/restartwait.html b/lib/ClassicUi/html/restartwait.html index 4ef22ae8..3d0071fd 100644 --- a/lib/ClassicUi/html/restartwait.html +++ b/lib/ClassicUi/html/restartwait.html @@ -12,7 +12,7 @@
    AMS reader ${version}
    • - +
    • diff --git a/lib/ClassicUi/html/setup.html b/lib/ClassicUi/html/setup.html index 87d047f9..3c0b1e37 100644 --- a/lib/ClassicUi/html/setup.html +++ b/lib/ClassicUi/html/setup.html @@ -12,7 +12,7 @@
      AMS reader ${version}
      • - +
      • diff --git a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte index 37e843fd..c76f2959 100644 --- a/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte +++ b/lib/SvelteUi/app/src/lib/ConfigurationPanel.svelte @@ -230,7 +230,7 @@
    Meter - +
    Serial configuration @@ -320,7 +320,7 @@
    WiFi - +
    SSID
    @@ -354,7 +354,7 @@
    Network - +
    IP
    @@ -396,7 +396,7 @@
    MQTT - +
    Server @@ -471,7 +471,7 @@ {#if configuration.q.m == 3}
    Domoticz - +
    @@ -488,7 +488,7 @@
    - +
    @@ -496,7 +496,7 @@ {#if configuration.p.r.startsWith("10YNO") || configuration.p.r == '10Y1001A1001A48H'}
    Tariff thresholds - +