mirror of
https://github.com/UtilitechAS/amsreader-firmware.git
synced 2026-03-13 14:01:09 +00:00
* 15min prices WIP * WIP more changes for 15min prices * More work on 15min pricing * Fixed some errors * Some changes after testing * Graphical changes for 15min pricing * Adjustments on MQTT handlers after switching to 15min prices * Reverted some MQTT changes * Adapted HA integration for 15min pricing * Adapted JSON payload for 15min * Adjustments during testing * Set default price interval * Fixed refresh of price graph when data changes * Bugfixes * Fixed some issues with raw payload * Adjustments for meter timestamp from Kamstrup * Updated readme * Added detailed breakdown of payloads coming from Norwegian meters * Minor changes relating to price * Fixed byte alignment on price config * Changes to support RC upgraders
127 lines
3.4 KiB
C++
127 lines
3.4 KiB
C++
/**
|
|
* @copyright Utilitech AS 2023
|
|
* License: Fair Source
|
|
*
|
|
*/
|
|
|
|
#include "EntsoeA44Parser.h"
|
|
#include "HardwareSerial.h"
|
|
|
|
EntsoeA44Parser::EntsoeA44Parser(PricesContainer *container) {
|
|
this->container = container;
|
|
}
|
|
|
|
EntsoeA44Parser::~EntsoeA44Parser() {
|
|
|
|
}
|
|
|
|
int EntsoeA44Parser::available() {
|
|
return 0;
|
|
}
|
|
|
|
int EntsoeA44Parser::read() {
|
|
return 0;
|
|
}
|
|
|
|
int EntsoeA44Parser::peek() {
|
|
return 0;
|
|
}
|
|
|
|
void EntsoeA44Parser::flush() {
|
|
|
|
}
|
|
|
|
size_t EntsoeA44Parser::write(const uint8_t *buffer, size_t size) {
|
|
for(size_t i = 0; i < size; i++) {
|
|
write(buffer[i]);
|
|
}
|
|
return size;
|
|
}
|
|
|
|
size_t EntsoeA44Parser::write(uint8_t byte) {
|
|
if(pos >= 64) pos = 0;
|
|
if(docPos == DOCPOS_CURRENCY) {
|
|
buf[pos++] = byte;
|
|
if(pos == 3) {
|
|
buf[pos++] = '\0';
|
|
container->setCurrency(buf);
|
|
docPos = DOCPOS_SEEK;
|
|
pos = 0;
|
|
}
|
|
} else if(docPos == DOCPOS_MEASUREMENTUNIT) {
|
|
buf[pos++] = byte;
|
|
if(pos == 3) {
|
|
buf[pos++] = '\0';
|
|
if(strcmp_P(buf, PSTR("MWH"))) multiplier = 0.001;
|
|
docPos = DOCPOS_SEEK;
|
|
pos = 0;
|
|
}
|
|
} else if(docPos == DOCPOS_POSITION) {
|
|
if(byte == '<') {
|
|
buf[pos] = '\0';
|
|
long pn = String(buf).toInt() - 1;
|
|
if(pn < container->getNumberOfPoints()) {
|
|
pointNum = pn;
|
|
}
|
|
docPos = DOCPOS_SEEK;
|
|
pos = 0;
|
|
} else {
|
|
buf[pos++] = byte;
|
|
}
|
|
} else if(docPos == DOCPOS_AMOUNT) {
|
|
if(byte == '<') {
|
|
buf[pos] = '\0';
|
|
float val = String(buf).toFloat();
|
|
for(uint8_t i = pointNum; i < container->getNumberOfPoints(); i++) {
|
|
container->setPrice(i, val * multiplier, PRICE_DIRECTION_IMPORT);
|
|
}
|
|
docPos = DOCPOS_SEEK;
|
|
pos = 0;
|
|
} else {
|
|
buf[pos++] = byte;
|
|
}
|
|
} else if(docPos == DOCPOS_RESOLUTION) {
|
|
if(byte == '<') {
|
|
buf[pos] = '\0';
|
|
|
|
// This happens if there are two time series in the XML. We are only interrested in the first one, so we ignore the rest of the document
|
|
if(container->hasPrice(0, PRICE_DIRECTION_IMPORT)) return 1;
|
|
|
|
if(strcmp_P(buf, PSTR("PT15M"))) {
|
|
container->setup(15, 100, false);
|
|
} else if(strcmp_P(buf, PSTR("PT60M"))) {
|
|
container->setup(60, 25, false);
|
|
}
|
|
docPos = DOCPOS_SEEK;
|
|
pos = 0;
|
|
} else {
|
|
buf[pos++] = byte;
|
|
}
|
|
} else {
|
|
if(pos == 0) {
|
|
if(byte == '<') {
|
|
buf[pos++] = byte;
|
|
}
|
|
} else if(byte == '>') {
|
|
buf[pos++] = byte;
|
|
buf[pos] = '\0';
|
|
if(strcmp_P(buf, PSTR("<currency_Unit.name>")) == 0) {
|
|
docPos = DOCPOS_CURRENCY;
|
|
} else if(strcmp(buf, PSTR("<price_Measure_Unit.name>")) == 0) {
|
|
docPos = DOCPOS_MEASUREMENTUNIT;
|
|
} else if(strcmp(buf, PSTR("<position>")) == 0) {
|
|
docPos = DOCPOS_POSITION;
|
|
pointNum = 0xFF;
|
|
} else if(strcmp(buf, PSTR("<price.amount>")) == 0) {
|
|
docPos = DOCPOS_AMOUNT;
|
|
} else if(strcmp(buf, PSTR("<resolution>")) == 0) {
|
|
docPos = DOCPOS_RESOLUTION;
|
|
}
|
|
pos = 0;
|
|
} else {
|
|
buf[pos++] = byte;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|