Fixed ESP8266 memory issue with price decoding (#1089)

This commit is contained in:
Gunnar Skjold 2025-12-11 11:37:52 +01:00 committed by GitHub
parent ad73821f1c
commit fc6e9e8085
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 22 additions and 21 deletions

View File

@ -124,9 +124,6 @@ private:
Timezone* tz = NULL; Timezone* tz = NULL;
Timezone* entsoeTz = NULL; Timezone* entsoeTz = NULL;
static const uint16_t BufferSize = 256;
char* buf;
bool hub = false; bool hub = false;
uint8_t* key = NULL; uint8_t* key = NULL;
uint8_t* auth = NULL; uint8_t* auth = NULL;

View File

@ -25,8 +25,6 @@ PriceService::PriceService(RemoteDebug* Debug) : priceConfig(std::vector<PriceCo
#else #else
PriceService::PriceService(Stream* Debug) : priceConfig(std::vector<PriceConfig>()) { PriceService::PriceService(Stream* Debug) : priceConfig(std::vector<PriceConfig>()) {
#endif #endif
this->buf = (char*) malloc(BufferSize);
debugger = Debug; debugger = Debug;
// Entso-E uses CET/CEST // Entso-E uses CET/CEST
@ -430,11 +428,12 @@ float PriceService::getCurrencyMultiplier(const char* from, const char* to, time
#endif #endif
float currencyMultiplier = 0; float currencyMultiplier = 0;
snprintf_P(buf, BufferSize, PSTR("https://data.norges-bank.no/api/data/EXR/B.%s.NOK.SP?lastNObservations=1"), from); char buf[80];
snprintf_P(buf, 80, PSTR("https://data.norges-bank.no/api/data/EXR/B.%s.NOK.SP?lastNObservations=1"), from);
if(retrieve(buf, &p)) { if(retrieve(buf, &p)) {
currencyMultiplier = p.getValue(); currencyMultiplier = p.getValue();
if(strncmp(to, "NOK", 3) != 0) { if(strncmp(to, "NOK", 3) != 0) {
snprintf_P(buf, BufferSize, PSTR("https://data.norges-bank.no/api/data/EXR/B.%s.NOK.SP?lastNObservations=1"), to); snprintf_P(buf, 80, PSTR("https://data.norges-bank.no/api/data/EXR/B.%s.NOK.SP?lastNObservations=1"), to);
if(retrieve(buf, &p)) { if(retrieve(buf, &p)) {
if(p.getValue() > 0.0) { if(p.getValue() > 0.0) {
currencyMultiplier /= p.getValue(); currencyMultiplier /= p.getValue();
@ -477,7 +476,8 @@ PricesContainer* PriceService::fetchPrices(time_t t) {
breakTime(e1, d1); breakTime(e1, d1);
breakTime(e2, d2); breakTime(e2, d2);
snprintf_P(buf, BufferSize, PSTR("https://web-api.tp.entsoe.eu/api?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s"), char buf[256];
snprintf_P(buf, 256, PSTR("https://web-api.tp.entsoe.eu/api?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s"),
getToken(), getToken(),
d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00, d1.Year+1970, d1.Month, d1.Day, d1.Hour, 00,
d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00, d2.Year+1970, d2.Month, d2.Day, d2.Hour, 00,
@ -514,8 +514,8 @@ PricesContainer* PriceService::fetchPrices(time_t t) {
tmElements_t tm; tmElements_t tm;
breakTime(entsoeTz->toLocal(t), tm); breakTime(entsoeTz->toLocal(t), tm);
String data; char buf[128];
snprintf_P(buf, BufferSize, PSTR("http://hub.amsleser.no/hub/price/%s/%d/%d/%d/pt%dm?currency=%s"), snprintf_P(buf, 128, PSTR("http://hub.amsleser.no/hub/price/%s/%d/%d/%d/pt%dm?currency=%s"),
config->area, config->area,
tm.Year+1970, tm.Year+1970,
tm.Month, tm.Month,
@ -547,13 +547,14 @@ PricesContainer* PriceService::fetchPrices(time_t t) {
#endif #endif
if(status == HTTP_CODE_OK) { if(status == HTTP_CODE_OK) {
data = http->getString(); uint8_t content[1024];
http->end();
WiFiClient* stream = http->getStreamPtr();
uint8_t* content = (uint8_t*) (data.c_str());
DataParserContext ctx = {0,0,0,0}; DataParserContext ctx = {0,0,0,0};
ctx.length = data.length(); ctx.length = stream->readBytes(content, http->getSize());
http->end();
GCMParser gcm(key, auth); GCMParser gcm(key, auth);
int8_t gcmRet = gcm.parse(content, ctx); int8_t gcmRet = gcm.parse(content, ctx);
if(gcmRet > 0) { if(gcmRet > 0) {
@ -569,9 +570,11 @@ PricesContainer* PriceService::fetchPrices(time_t t) {
ret->setCurrency(header->currency); ret->setCurrency(header->currency);
int32_t* points = (int32_t*) &header[1]; int32_t* points = (int32_t*) &header[1];
for(uint8_t i = 0; i < header->numberOfPoints; i++) { int32_t intval;
int32_t intval = ntohl(points[i]); for(uint8_t i = 0; i < ret->getNumberOfPoints(); i++) {
float value = intval / 10000.0; // To avoid alignment issues on ESP8266, we use memcpy
memcpy(&intval, &points[i], sizeof(int32_t));
float value = ntohl(intval) / 10000.0;
#if defined(AMS_REMOTE_DEBUG) #if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::VERBOSE)) if (debugger->isActive(RemoteDebug::VERBOSE))
#endif #endif
@ -579,9 +582,10 @@ PricesContainer* PriceService::fetchPrices(time_t t) {
ret->setPrice(i, value, PRICE_DIRECTION_IMPORT); ret->setPrice(i, value, PRICE_DIRECTION_IMPORT);
} }
if(header->differentExportPrices) { if(header->differentExportPrices) {
for(uint8_t i = 0; i < header->numberOfPoints; i++) { for(uint8_t i = 0; i < ret->getNumberOfPoints(); i++) {
int32_t intval = ntohl(points[i]); // To avoid alignment issues on ESP8266, we use memcpy
float value = intval / 10000.0; memcpy(&intval, &points[ret->getNumberOfPoints()+i], sizeof(int32_t));
float value = ntohl(intval) / 10000.0;
#if defined(AMS_REMOTE_DEBUG) #if defined(AMS_REMOTE_DEBUG)
if (debugger->isActive(RemoteDebug::VERBOSE)) if (debugger->isActive(RemoteDebug::VERBOSE))
#endif #endif