From 68b3415a6c776874c0328fd057a8574fbc24ff37 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Sat, 13 Aug 2022 16:32:55 +0200 Subject: [PATCH] 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 +
+ +
+