Cleanup for price API

This commit is contained in:
Gunnar Skjold 2022-08-13 16:32:55 +02:00
parent d8f3ae8b07
commit 68b3415a6c
8 changed files with 85 additions and 70 deletions

View File

@ -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);

View File

@ -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();
}

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -84,7 +84,7 @@ private:
void configMqttHtml();
void configWebHtml();
void configDomoticzHtml();
void configEntsoeHtml();
void configPriceApiHtml();
void configNtpHtml();
void configGpioHtml();
void configDebugHtml();

View File

@ -63,7 +63,7 @@
<a class="dropdown-item" href="/mqtt">MQTT</a>
<a class="dropdown-item" href="/web">Web</a>
<a class="dropdown-item" href="/ntp">NTP</a>
<a class="dropdown-item d-none ssl-capable" href="/entsoe">ENTSO-E API</a>
<a class="dropdown-item" href="/priceapi">Price API</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="https://github.com/gskjold/AmsToMqttBridge/wiki" target="_blank">Documentation</a>
</div>

View File

@ -1,22 +1,15 @@
<form method="post" action="/save">
<input type="hidden" name="ec" value="true"/>
<div class="my-3 p-3 bg-white rounded shadow">
<h6>ENTSO-E API</h6>
<h6>Price API</h6>
<div class="row">
<div class="col-xl-4 col-lg-6 col-md-8">
<div class="m-2 input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Token</span>
</div>
<input type="text" name="et" class="form-control" value="{et}"/>
</div>
</div>
<div class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
<div class="m-2 input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">Region</span>
</div>
<select name="ea" class="form-control">
<option value="">None</option>
<optgroup label="Norway">
<option value="10YNO-1--------2" {eaNo1}>NO1</option>
<option value="10YNO-2--------T" {eaNo2}>NO2</option>
@ -58,6 +51,14 @@
<input name="em" type="number" min="0.001" max="1000" step="0.001" class="form-control" value="{em}"/>
</div>
</div>
<div class="col-xl-4 col-lg-6 col-md-8 {dt}">
<div class="m-2 input-group input-group-sm">
<div class="input-group-prepend">
<span class="input-group-text">ENTSO-E token</span>
</div>
<input type="text" name="et" class="form-control" value="{et}" placeholder="Optional"/>
</div>
</div>
</div>
</div>
<hr/>