From 11399bf21bfc786e016d3a6639773b97b80e2adc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0trauch?= Date: Sat, 9 Nov 2024 01:27:31 +0100 Subject: [PATCH] Cheapest and the most expensive hours by average --- calculator/index.html | 15 ++++++++++----- calculator/main.py | 22 ++++++++++++++++++++++ calculator/schema.py | 2 ++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/calculator/index.html b/calculator/index.html index c4cd0d1..2c133ed 100644 --- a/calculator/index.html +++ b/calculator/index.html @@ -33,12 +33,17 @@ } for (let i = 0; i < 24; i++) { - if(data.cheapest_hours.hours.includes(i)) { - document.getElementById(prefix + i).className = "px-1 bg-green-500"; - } else if (data.most_expensive_hours.hours.includes(i)) { - document.getElementById(prefix + i).className = "px-1 bg-rose-400"; + let extra_class = ""; + if(today && i == new Date().getHours()) { + extra_class = " border-solid border-4 border-gray-900 font-bold"; + } + + if(data.cheapest_hours_by_average.hours.includes(i)) { + document.getElementById(prefix + i).className = "px-1 bg-green-500" + extra_class; + } else if (data.most_expensive_hours_by_average.hours.includes(i)) { + document.getElementById(prefix + i).className = "px-1 bg-rose-400" + extra_class; } else { - document.getElementById(prefix + i).className = "px-1 bg-amber-100"; + document.getElementById(prefix + i).className = "px-1 bg-amber-100" + extra_class; } document.getElementById(prefix + i).innerText = Math.round(data.total.hours[i]*100)/100; } diff --git a/calculator/main.py b/calculator/main.py index 3441d6f..5bf9911 100644 --- a/calculator/main.py +++ b/calculator/main.py @@ -41,11 +41,17 @@ Return spot prices for the whole day with all fees included.
**num_cheapest_hours** - number of cheapest hours to return, default is 8, use this to plan your consumption
**num_most_expensive_hours** - number of the most expensive hours to return, default is 8, use this to plan your consumption
**low_tariff_hours** - list of low tariff hours, default is 0,1,2,3,4,5,6,7,9,10,11,13,14,16,17,18,20,21,22,23 (D57d, ČEZ)
+**average_hours** - used for calculation of cheapest hours based on average price of first few hours, this sets number of cheapest hours used to calculate number that is a base number for the calculation
+**average_hours_threshold** - used for calculation of average price, cheapest hours will be all hours with price lower than `average_price * threshold`

Output:
**spot** - current spot prices on our market
**total** - total price for the day including all fees and VAT
**sell** - current spot prices minus sell_fees
+**cheapest_hours** - 8 (or configured) cheapest hours in the day
+**most_expensive_hours** - 8 (or configured) the most expensive hours in the day
+**cheapest_hours_by_average** - cheapest hours based on average_hours and average_hours_threshold
+**most_expensive_hours_by_average** - the most expensive hours based on average_hours and average_hours_threshold

The final price on the invoice is calculated as:
monthly_fees + kWh consumption in low tariff * kwh_fees_low + kWh consumption in high tariff * kwh_fees_high
@@ -72,6 +78,12 @@ rest: binary_sensor: - name: "energy_cheap_hour" value_template: "{{ value_json.cheapest_hours.is_cheapest }}" + - name: "energy_expensive_hour" + value_template: "{{ value_json.most_expensive_hours.is_the_most_expensive }}" + - name: "energy_expensive_hour_by_average" + value_template: "{{ value_json.most_expensive_hours_by_average.is_the_most_expensive }}" + - name: "energy_cheap_hour_by_average" + value_template: "{{ value_json.cheapest_hours_by_average.is_cheapest }}"" ``` """ @@ -90,6 +102,8 @@ def read_item( no_cache:bool = False, num_cheapest_hours:int = 8, num_most_expensive_hours:int = 8, + average_hours:int=4, + average_hours_threshold:float=1.25, ) -> DayPrice: if not date: @@ -126,6 +140,12 @@ def read_item( cheapest_hours = [int(k) for k, v in list(spot_hours_total_sorted.items())[0:num_cheapest_hours]] most_expensive_hours = [int(k) for k, v in list(reversed(spot_hours_total_sorted.items()))[0:num_most_expensive_hours]] + + # Average over four cheapest hours and calculation of all hours that are in this average +20 % + four_cheapest_hours = [v for k, v in list(spot_hours_total_sorted.items())[0:average_hours]] + four_cheapest_hours_average = sum(four_cheapest_hours) / average_hours + cheapest_hours_by_average = [int(k) for k, v in list(spot_hours_total_sorted.items()) if v < four_cheapest_hours_average * average_hours_threshold] + most_expensive_hours_by_average = set(range(24)) - set(cheapest_hours_by_average) data = DayPrice( monthly_fees=monthly_fees * VAT, @@ -141,6 +161,8 @@ def read_item( sell=spot_for_sell, cheapest_hours=CheapestHours(hours=cheapest_hours, is_cheapest=hour in cheapest_hours if is_today else None), most_expensive_hours=MostExpensiveHours(hours=most_expensive_hours, is_the_most_expensive=hour in most_expensive_hours if is_today else None), + cheapest_hours_by_average=CheapestHours(hours=cheapest_hours_by_average, is_cheapest=hour in cheapest_hours_by_average if is_today else None), + most_expensive_hours_by_average=MostExpensiveHours(hours=most_expensive_hours_by_average, is_the_most_expensive=hour in most_expensive_hours_by_average if is_today else None), ) return data diff --git a/calculator/schema.py b/calculator/schema.py index a158ca3..f310d1c 100644 --- a/calculator/schema.py +++ b/calculator/schema.py @@ -35,6 +35,8 @@ class DayPrice: sell: Price cheapest_hours: CheapestHours most_expensive_hours: MostExpensiveHours + cheapest_hours_by_average: CheapestHours + most_expensive_hours_by_average: MostExpensiveHours