Added support for 15 minute price resolution (#1031)

* 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
This commit is contained in:
Gunnar Skjold
2025-11-13 15:10:54 +01:00
committed by GitHub
parent ffd8d46f2e
commit c648546b61
44 changed files with 1073 additions and 637 deletions

View File

@@ -27,10 +27,6 @@
#define SSL_BUF_SIZE 512
#define PRICE_DIRECTION_IMPORT 0x01
#define PRICE_DIRECTION_EXPORT 0x02
#define PRICE_DIRECTION_BOTH 0x03
#define PRICE_DAY_MO 0x01
#define PRICE_DAY_TU 0x02
#define PRICE_DAY_WE 0x04
@@ -57,10 +53,13 @@ struct PriceConfig {
uint8_t end_dayofmonth;
};
struct PricePart {
char name[32];
char description[32];
uint32_t value;
struct AmsPriceV2Header {
char currency[4];
char measurementUnit[4];
char source[4];
uint8_t resolutionInMinutes;
bool differentExportPrices;
uint8_t numberOfPoints;
};
class PriceService {
@@ -78,17 +77,25 @@ public:
char* getCurrency();
char* getArea();
char* getSource();
float getValueForHour(uint8_t direction, int8_t hour);
float getValueForHour(uint8_t direction, time_t ts, int8_t hour);
float getEnergyPriceForHour(uint8_t direction, time_t ts, int8_t hour);
uint8_t getResolutionInMinutes();
uint8_t getNumberOfPointsAvailable();
uint8_t getCurrentPricePointIndex();
bool isExportPricesDifferentFromImport();
bool hasPrice() { return hasPrice(PRICE_DIRECTION_IMPORT); }
bool hasPrice(uint8_t direction) { return getCurrentPrice(direction) != PRICE_NO_VALUE; }
bool hasPricePoint(uint8_t direction, int8_t point) { return getPricePoint(direction, point) != PRICE_NO_VALUE; }
float getCurrentPrice(uint8_t direction);
float getPricePoint(uint8_t direction, uint8_t point);
float getPriceForRelativeHour(uint8_t direction, int8_t hour); // If not 60min interval, average
std::vector<PriceConfig>& getPriceConfig();
void setPriceConfig(uint8_t index, PriceConfig &priceConfig);
void cropPriceConfig(uint8_t size);
PricePart getPricePart(uint8_t index);
int16_t getLastError();
bool load();
@@ -103,7 +110,7 @@ private:
PriceServiceConfig* config = NULL;
HTTPClient* http = NULL;
uint8_t currentDay = 0, currentHour = 0;
uint8_t currentDay = 0, currentPricePoint = 0;
uint8_t tomorrowFetchMinute = 15; // How many minutes over 13:00 should it fetch prices
uint8_t nextFetchDelayMinutes = 15;
uint64_t lastTodayFetch = 0;
@@ -132,5 +139,7 @@ private:
bool retrieve(const char* url, Stream* doc);
float getCurrencyMultiplier(const char* from, const char* to, time_t t);
bool timeIsInPeriod(tmElements_t tm, PriceConfig pc);
float getFixedPrice(uint8_t direction, int8_t hour);
float getEnergyPricePoint(uint8_t direction, uint8_t point);
};
#endif