Fixed price shift for non-CET price area (#1090)

* Fixed non-CET price presentation

* Added compiled version

* Updated fix for non cet

* Fixed! I think...
This commit is contained in:
Gunnar Skjold 2025-12-11 11:42:17 +01:00 committed by GitHub
parent fc6e9e8085
commit 2e4a0fc0a3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 32 additions and 29 deletions

View File

@ -136,7 +136,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 getFixedPrice(uint8_t direction, int8_t point);
float getEnergyPricePoint(uint8_t direction, uint8_t point);
};
#endif

View File

@ -127,15 +127,16 @@ bool PriceService::isExportPricesDifferentFromImport() {
}
float PriceService::getPricePoint(uint8_t direction, uint8_t point) {
float value = getFixedPrice(direction, point * getResolutionInMinutes() / 60);
float value = getFixedPrice(direction, point);
if(value == PRICE_NO_VALUE) value = getEnergyPricePoint(direction, point);
if(value == PRICE_NO_VALUE) return PRICE_NO_VALUE;
tmElements_t tm;
time_t ts = time(nullptr);
breakTime(tz->toLocal(ts), tm);
breakTime(entsoeTz->toLocal(ts), tm);
tm.Hour = tm.Minute = tm.Second = 0;
breakTime(makeTime(tm) + (point * SECS_PER_MIN * getResolutionInMinutes()), tm);
ts = entsoeTz->toUTC(makeTime(tm)) + (point * SECS_PER_MIN * getResolutionInMinutes());
breakTime(tz->toLocal(ts), tm);
for (uint8_t i = 0; i < priceConfig.size(); i++) {
PriceConfig pc = priceConfig.at(i);
@ -162,8 +163,6 @@ float PriceService::getPricePoint(uint8_t direction, uint8_t point) {
float PriceService::getCurrentPrice(uint8_t direction) {
time_t ts = time(nullptr);
tmElements_t tm;
breakTime(tz->toLocal(ts), tm);
uint8_t pos = getCurrentPricePointIndex();
return getPricePoint(direction, pos);
@ -171,6 +170,7 @@ float PriceService::getCurrentPrice(uint8_t direction) {
float PriceService::getEnergyPricePoint(uint8_t direction, uint8_t point) {
uint8_t pos = point;
float multiplier = 1.0;
uint8_t numberOfPointsToday = 24;
if(today != NULL) {
@ -206,10 +206,10 @@ float PriceService::getPriceForRelativeHour(uint8_t direction, int8_t hour) {
time_t ts = time(nullptr);
tmElements_t tm;
breakTime(tz->toLocal(ts), tm);
int8_t targetHour = tm.Hour + hour;
breakTime(entsoeTz->toLocal(ts), tm);
uint8_t targetHour = tm.Hour + hour;
tm.Hour = tm.Minute = tm.Second = 0;
time_t startOfDay = tz->toUTC(makeTime(tm));
time_t startOfDay = entsoeTz->toUTC(makeTime(tm));
if((ts + (hour * SECS_PER_HOUR)) < startOfDay) {
return PRICE_NO_VALUE;
@ -235,15 +235,15 @@ float PriceService::getPriceForRelativeHour(uint8_t direction, int8_t hour) {
return valueSum / valueCount;
}
float PriceService::getFixedPrice(uint8_t direction, int8_t hour) {
float PriceService::getFixedPrice(uint8_t direction, int8_t point) {
time_t ts = time(nullptr);
tmElements_t tm;
breakTime(entsoeTz->toLocal(ts), tm);
tm.Hour = tm.Minute = tm.Second = 0;
ts = entsoeTz->toUTC(makeTime(tm)) + (point * SECS_PER_MIN * getResolutionInMinutes());
breakTime(tz->toLocal(ts), tm);
tm.Hour = hour;
tm.Minute = 0;
tm.Second = 0;
breakTime(makeTime(tm), tm);
tm.Minute = tm.Second = 0;
float value = PRICE_NO_VALUE;
for (uint8_t i = 0; i < priceConfig.size(); i++) {
@ -760,6 +760,6 @@ bool PriceService::timeIsInPeriod(tmElements_t tm, PriceConfig pc) {
uint8_t PriceService::getCurrentPricePointIndex() {
time_t ts = time(nullptr);
tmElements_t tm;
breakTime(tz->toLocal(ts), tm);
breakTime(entsoeTz->toLocal(ts), tm);
return ((tm.Hour * 60) + tm.Minute) / getResolutionInMinutes();
}

File diff suppressed because one or more lines are too long

View File

@ -73,7 +73,7 @@
{#each config.x.ticks as point, i}
{#if !isNaN(xScale(i))}
<g class="tick" transform="translate({xScale(i)},{heightAvailable})">
{#if barWidth > 20 || i%2 == 0}
{#if barWidth > 20 || i%2 == 0 || !config.x.ticks[i-1].label}
<text x="{barWidth/2}" y="-4">{point.label}</text>
{/if}
</g>

View File

@ -140,17 +140,17 @@
{#if uiVisibility(sysinfo.ui.p, data.p && !Number.isNaN(data.p))}
{#if importPrices?.importExportPriceDifferent && (data.om || data.e > 0)}
<div class="cnt gwf">
<PricePlot title="{translations.dashboard?.price_import ?? "Price import"}" json={importPrices}/>
<PricePlot title="{translations.dashboard?.price_import ?? "Price import"}" json={importPrices} sysinfo={sysinfo}/>
</div>
{:else}
<div class="cnt gwf">
<PricePlot title={translations.dashboard?.price ?? "Price"} json={importPrices}/>
<PricePlot title={translations.dashboard?.price ?? "Price"} json={importPrices} sysinfo={sysinfo}/>
</div>
{/if}
{/if}
{#if importPrices?.importExportPriceDifferent && (data.om || data.e > 0) && uiVisibility(sysinfo.ui.p, data.pe && !Number.isNaN(data.pe))}
<div class="cnt gwf">
<PricePlot title={translations.dashboard?.price_export ?? "Price export"} json={exportPrices}/>
<PricePlot title={translations.dashboard?.price_export ?? "Price export"} json={exportPrices} sysinfo={sysinfo}/>
</div>
{/if}
{#if uiVisibility(sysinfo.ui.d, dayPlot)}

View File

@ -5,6 +5,7 @@
export let title;
export let json;
export let sysinfo;
let config = {};
let max;
@ -39,7 +40,8 @@
let xTicks = [];
let values = [];
min = max = 0;
let i = Math.floor(((cur.getHours()*60) + cur.getMinutes()) / json?.resolution);
addHours(cur, sysinfo.clock_offset - ((24 + cur.getHours() - cur.getUTCHours())%24));
let i = json?.cursor ? json.cursor : 0;
cur.setMinutes(Math.floor(cur.getMinutes()/json?.resolution)*json?.resolution,0,0);
while(i < json?.prices?.length) {
val = json.prices[i];

View File

@ -777,11 +777,12 @@ void AmsWebServer::priceJson(uint8_t direction) {
prices[i] = ps->getPricePoint(direction, i);
}
snprintf_P(buf, BufferSize, PSTR("{\"currency\":\"%s\",\"source\":\"%s\",\"resolution\":%d,\"direction\":\"%s\",\"importExportPriceDifferent\":%s,\"prices\":["),
snprintf_P(buf, BufferSize, PSTR("{\"currency\":\"%s\",\"source\":\"%s\",\"resolution\":%d,\"direction\":\"%s\",\"cursor\":%d,\"importExportPriceDifferent\":%s,\"prices\":["),
ps->getCurrency(),
ps->getSource(),
ps->getResolutionInMinutes(),
direction == PRICE_DIRECTION_IMPORT ? "import" : direction == PRICE_DIRECTION_EXPORT ? "export" : "both",
ps->getCurrentPricePointIndex(),
ps->isExportPricesDifferentFromImport() ? "true" : "false"
);