From a37fc39e61e3c52a2a77585de2260aa52a507883 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 13:42:41 +0200 Subject: [PATCH 01/10] Adding percentage of spread --- custom_components/entsoe/coordinator.py | 13 ++++++++----- custom_components/entsoe/sensor.py | 17 +++++++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/custom_components/entsoe/coordinator.py b/custom_components/entsoe/coordinator.py index c055843..b18782a 100644 --- a/custom_components/entsoe/coordinator.py +++ b/custom_components/entsoe/coordinator.py @@ -178,15 +178,12 @@ async def get_energy_prices(self, start_date, end_date): } return self.parse_hourprices(await self.fetch_prices(start_date, end_date)) - def update_data(self): + def today_data_available(self): now = dt.now() if self.today.date() != now.date(): self.logger.debug(f"new day detected: update today and filtered hourprices") self.today = now.replace(hour=0, minute=0, second=0, microsecond=0) - - self.filtered_hourprices = self._filter_calculated_hourprices(self.data) - - def today_data_available(self): + self.filtered_hourprices = self._filter_calculated_hourprices(self.data) return len(self.get_data_today()) > MIN_HOURS def _filter_calculated_hourprices(self, data): @@ -270,6 +267,12 @@ def get_min_time(self): def get_percentage_of_max(self): return round(self.get_current_hourprice() / self.get_max_price() * 100, 1) + def get_percentage(self): + min = self.get_min_price() + spread = self.get_max_price() - min + current = self.get_current_hourprice() - min + return round(current / spread * 100, 1) + def get_timestamped_prices(self, hourprices): list = [] for hour, price in hourprices.items(): diff --git a/custom_components/entsoe/sensor.py b/custom_components/entsoe/sensor.py index 15d2107..40de118 100644 --- a/custom_components/entsoe/sensor.py +++ b/custom_components/entsoe/sensor.py @@ -46,9 +46,7 @@ class EntsoeEntityDescription(SensorEntityDescription): value_fn: Callable[[dict], StateType] = None -def sensor_descriptions( - currency: str, energy_scale: str -) -> tuple[EntsoeEntityDescription, ...]: +def sensor_descriptions(currency: str, energy_scale: str) -> tuple[EntsoeEntityDescription, ...]: """Construct EntsoeEntityDescription.""" return ( EntsoeEntityDescription( @@ -105,6 +103,15 @@ def sensor_descriptions( state_class=SensorStateClass.MEASUREMENT, value_fn=lambda coordinator: coordinator.get_percentage_of_max(), ), + EntsoeEntityDescription( + key="percentage", + name="Current percentage", + native_unit_of_measurement=f"{PERCENTAGE}", + icon="mdi:percent", + suggested_display_precision=1, + state_class=SensorStateClass.MEASUREMENT, + value_fn=lambda coordinator: coordinator.get_percentage(), + ), EntsoeEntityDescription( key="highest_price_time_today", name="Time of highest price", @@ -134,7 +141,7 @@ async def async_setup_entry( entity = {} for description in sensor_descriptions( currency=config_entry.options.get(CONF_CURRENCY, DEFAULT_CURRENCY), - energy_scale=config_entry.options.get(CONF_ENERGY_SCALE, DEFAULT_ENERGY_SCALE), + energy_scale=config_entry.options.get(CONF_ENERGY_SCALE, DEFAULT_ENERGY_SCALE) ): entity = description entities.append( @@ -215,8 +222,6 @@ async def async_update(self) -> None: utcnow().replace(minute=0, second=0) + timedelta(hours=1), ) - self.coordinator.update_data() - if ( self.coordinator.data is not None and self.coordinator.today_data_available() From 897611c43a606d0a65d7fb2d8117a1cfebc8c210 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 14:17:34 +0200 Subject: [PATCH 02/10] Resolved the missing hours issue --- custom_components/entsoe/api_client.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 54da6bf..87062a3 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -96,7 +96,21 @@ def query_day_ahead_prices( hour = int(position) - 1 series[date + timedelta(hours=hour)] = float(price) + # Start filling from the first hour in the series until the requested end + current_time = min(series.keys(), default=None) # Start from the first time in response + if current_time is None: + return series # No valid data received from the server + + last_price = series[current_time] + + while current_time < end: + if current_time in series: + last_price = series[current_time] # Update to the current price + else: + series[current_time] = last_price # Fill with the last known price + current_time += timedelta(hours=1) return series + except Exception as exc: _LOGGER.debug(f"Failed to parse response content:{response.content}") raise exc From 4047a4807770d70f33c32c37643bae72811cbd82 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 15:09:39 +0200 Subject: [PATCH 03/10] Re applied changes to latest version --- custom_components/entsoe/api_client.py | 3 ++- custom_components/entsoe/coordinator.py | 7 +++++-- custom_components/entsoe/sensor.py | 8 ++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 87062a3..8d1aaa1 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -109,8 +109,9 @@ def query_day_ahead_prices( else: series[current_time] = last_price # Fill with the last known price current_time += timedelta(hours=1) + return series - + except Exception as exc: _LOGGER.debug(f"Failed to parse response content:{response.content}") raise exc diff --git a/custom_components/entsoe/coordinator.py b/custom_components/entsoe/coordinator.py index b18782a..344edb2 100644 --- a/custom_components/entsoe/coordinator.py +++ b/custom_components/entsoe/coordinator.py @@ -178,12 +178,15 @@ async def get_energy_prices(self, start_date, end_date): } return self.parse_hourprices(await self.fetch_prices(start_date, end_date)) - def today_data_available(self): + def update_data(self): now = dt.now() if self.today.date() != now.date(): self.logger.debug(f"new day detected: update today and filtered hourprices") self.today = now.replace(hour=0, minute=0, second=0, microsecond=0) - self.filtered_hourprices = self._filter_calculated_hourprices(self.data) + + self.filtered_hourprices = self._filter_calculated_hourprices(self.data) + + def today_data_available(self): return len(self.get_data_today()) > MIN_HOURS def _filter_calculated_hourprices(self, data): diff --git a/custom_components/entsoe/sensor.py b/custom_components/entsoe/sensor.py index 40de118..5f1c1e1 100644 --- a/custom_components/entsoe/sensor.py +++ b/custom_components/entsoe/sensor.py @@ -46,7 +46,9 @@ class EntsoeEntityDescription(SensorEntityDescription): value_fn: Callable[[dict], StateType] = None -def sensor_descriptions(currency: str, energy_scale: str) -> tuple[EntsoeEntityDescription, ...]: +def sensor_descriptions( + currency: str, energy_scale: str +) -> tuple[EntsoeEntityDescription, ...]: """Construct EntsoeEntityDescription.""" return ( EntsoeEntityDescription( @@ -141,7 +143,7 @@ async def async_setup_entry( entity = {} for description in sensor_descriptions( currency=config_entry.options.get(CONF_CURRENCY, DEFAULT_CURRENCY), - energy_scale=config_entry.options.get(CONF_ENERGY_SCALE, DEFAULT_ENERGY_SCALE) + energy_scale=config_entry.options.get(CONF_ENERGY_SCALE, DEFAULT_ENERGY_SCALE), ): entity = description entities.append( @@ -222,6 +224,8 @@ async def async_update(self) -> None: utcnow().replace(minute=0, second=0) + timedelta(hours=1), ) + self.coordinator.update_data() + if ( self.coordinator.data is not None and self.coordinator.today_data_available() From 46dde45a3061ed39bf5d4ab52b5b74c664061f5e Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 20:57:17 +0200 Subject: [PATCH 04/10] Changed code to fill missing hours to last given hours --- custom_components/entsoe/api_client.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 8d1aaa1..058d2a4 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -96,20 +96,24 @@ def query_day_ahead_prices( hour = int(position) - 1 series[date + timedelta(hours=hour)] = float(price) - # Start filling from the first hour in the series until the requested end - current_time = min(series.keys(), default=None) # Start from the first time in response - if current_time is None: + # Get the min and max time from the server response + first_response_time = min(series.keys(), default=None) + last_response_time = max(series.keys(), default=None) + + if first_response_time is None or last_response_time is None: return series # No valid data received from the server + # Now only fill in missing hours between the first and last response times + current_time = first_response_time last_price = series[current_time] - while current_time < end: + while current_time <= last_response_time: if current_time in series: last_price = series[current_time] # Update to the current price else: series[current_time] = last_price # Fill with the last known price current_time += timedelta(hours=1) - + return series except Exception as exc: From c46c3c3b63f24160e80747e4b77784d8dfe74478 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 20:58:06 +0200 Subject: [PATCH 05/10] Changed code based on feedback --- custom_components/entsoe/coordinator.py | 6 +- custom_components/entsoe/test.txt | 96 +++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 custom_components/entsoe/test.txt diff --git a/custom_components/entsoe/coordinator.py b/custom_components/entsoe/coordinator.py index 344edb2..58b9151 100644 --- a/custom_components/entsoe/coordinator.py +++ b/custom_components/entsoe/coordinator.py @@ -190,17 +190,21 @@ def today_data_available(self): return len(self.get_data_today()) > MIN_HOURS def _filter_calculated_hourprices(self, data): + # rotation = calculations made upon 24hrs today if self.calculation_mode == CALCULATION_MODE["rotation"]: return { hour: price for hour, price in data.items() if hour >= self.today and hour < self.today + timedelta(days=1) } + # sliding = calculations made on all data from the current hour and beyond (future data only) elif self.calculation_mode == CALCULATION_MODE["sliding"]: now = dt.now().replace(minute=0, second=0, microsecond=0) - return {hour: price for hour, price in data.items() if hour >= now} + return {hour: price for hour, price in data.items() if now < hour < now + timedelta(hours=16)} + # rotation = calculations made on all data of today and tomorrow (48 hrs) if we have 72hrs of data elif self.calculation_mode == CALCULATION_MODE["publish"] and len(data) > 48: return {hour: price for hour, price in data.items() if hour >= self.today} + # rotation = calculations made on all data of yesterday and today (48 hrs) elif self.calculation_mode == CALCULATION_MODE["publish"]: return { hour: price diff --git a/custom_components/entsoe/test.txt b/custom_components/entsoe/test.txt new file mode 100644 index 0000000..82e727e --- /dev/null +++ b/custom_components/entsoe/test.txt @@ -0,0 +1,96 @@ +- time: '2024-10-06 00:00:00+02:00' +price: 0.23464 +- time: '2024-10-06 01:00:00+02:00' +price: 0.22923 +- time: '2024-10-06 02:00:00+02:00' +price: 0.22736 +- time: '2024-10-06 03:00:00+02:00' +price: 0.22619 +- time: '2024-10-06 04:00:00+02:00' +price: 0.22473 +- time: '2024-10-06 05:00:00+02:00' +price: 0.22619 +- time: '2024-10-06 06:00:00+02:00' +price: 0.22594 +- time: '2024-10-06 07:00:00+02:00' +price: 0.23613 +- time: '2024-10-06 08:00:00+02:00' +price: 0.24067 +- time: '2024-10-06 09:00:00+02:00' +price: 0.22833 +- time: '2024-10-06 10:00:00+02:00' +price: 0.1982 +- time: '2024-10-06 11:00:00+02:00' +price: 0.17603 +- time: '2024-10-06 12:00:00+02:00' +price: 0.1622 +- time: '2024-10-06 13:00:00+02:00' +price: 0.15584 +- time: '2024-10-06 15:00:00+02:00' +price: 0.15609 +- time: '2024-10-06 16:00:00+02:00' +price: 0.2201 +- time: '2024-10-06 17:00:00+02:00' +price: 0.25601 +- time: '2024-10-06 18:00:00+02:00' +price: 0.28447 +- time: '2024-10-06 20:00:00+02:00' +price: 0.27394 +- time: '2024-10-06 21:00:00+02:00' +price: 0.24817 +- time: '2024-10-06 22:00:00+02:00' +price: 0.23438 +- time: '2024-10-06 23:00:00+02:00' +price: 0.21842 +- time: '2024-10-07 00:00:00+02:00' +price: 0.19769 +- time: '2024-10-07 01:00:00+02:00' +price: 0.19861 +- time: '2024-10-07 02:00:00+02:00' +price: 0.19608 +- time: '2024-10-07 03:00:00+02:00' +price: 0.1921 +- time: '2024-10-07 04:00:00+02:00' +price: 0.19646 +- time: '2024-10-07 05:00:00+02:00' +price: 0.20788 +- time: '2024-10-07 06:00:00+02:00' +price: 0.23338 +- time: '2024-10-07 07:00:00+02:00' +price: 0.27927 +- time: '2024-10-07 08:00:00+02:00' +price: 0.28692 +- time: '2024-10-07 09:00:00+02:00' +price: 0.26696 +- time: '2024-10-07 10:00:00+02:00' +price: 0.23577 +- time: '2024-10-07 11:00:00+02:00' +price: 0.22869 +- time: '2024-10-07 12:00:00+02:00' +price: 0.21136 +- time: '2024-10-07 13:00:00+02:00' +price: 0.20823 +- time: '2024-10-07 14:00:00+02:00' +price: 0.2224 +- time: '2024-10-07 15:00:00+02:00' +price: 0.2302 +- time: '2024-10-07 16:00:00+02:00' +price: 0.26328 +- time: '2024-10-07 17:00:00+02:00' +price: 0.29185 +- time: '2024-10-07 18:00:00+02:00' +price: 0.4313 +- time: '2024-10-07 19:00:00+02:00' +price: 0.41885 +- time: '2024-10-07 20:00:00+02:00' +price: 0.31004 +- time: '2024-10-07 21:00:00+02:00' +price: 0.27674 +- time: '2024-10-07 22:00:00+02:00' +price: 0.26999 +- time: '2024-10-07 23:00:00+02:00' +price: 0.25158 +- time: '2024-10-06 14:00:00+02:00' +price: 0.15584 +- time: '2024-10-06 19:00:00+02:00' +price: 0.28447 \ No newline at end of file From f23ca6f66a22969c78ee0b7f663000c35c6c1472 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:03:17 +0200 Subject: [PATCH 06/10] . --- custom_components/entsoe/test.txt | 96 ------------------------------- 1 file changed, 96 deletions(-) delete mode 100644 custom_components/entsoe/test.txt diff --git a/custom_components/entsoe/test.txt b/custom_components/entsoe/test.txt deleted file mode 100644 index 82e727e..0000000 --- a/custom_components/entsoe/test.txt +++ /dev/null @@ -1,96 +0,0 @@ -- time: '2024-10-06 00:00:00+02:00' -price: 0.23464 -- time: '2024-10-06 01:00:00+02:00' -price: 0.22923 -- time: '2024-10-06 02:00:00+02:00' -price: 0.22736 -- time: '2024-10-06 03:00:00+02:00' -price: 0.22619 -- time: '2024-10-06 04:00:00+02:00' -price: 0.22473 -- time: '2024-10-06 05:00:00+02:00' -price: 0.22619 -- time: '2024-10-06 06:00:00+02:00' -price: 0.22594 -- time: '2024-10-06 07:00:00+02:00' -price: 0.23613 -- time: '2024-10-06 08:00:00+02:00' -price: 0.24067 -- time: '2024-10-06 09:00:00+02:00' -price: 0.22833 -- time: '2024-10-06 10:00:00+02:00' -price: 0.1982 -- time: '2024-10-06 11:00:00+02:00' -price: 0.17603 -- time: '2024-10-06 12:00:00+02:00' -price: 0.1622 -- time: '2024-10-06 13:00:00+02:00' -price: 0.15584 -- time: '2024-10-06 15:00:00+02:00' -price: 0.15609 -- time: '2024-10-06 16:00:00+02:00' -price: 0.2201 -- time: '2024-10-06 17:00:00+02:00' -price: 0.25601 -- time: '2024-10-06 18:00:00+02:00' -price: 0.28447 -- time: '2024-10-06 20:00:00+02:00' -price: 0.27394 -- time: '2024-10-06 21:00:00+02:00' -price: 0.24817 -- time: '2024-10-06 22:00:00+02:00' -price: 0.23438 -- time: '2024-10-06 23:00:00+02:00' -price: 0.21842 -- time: '2024-10-07 00:00:00+02:00' -price: 0.19769 -- time: '2024-10-07 01:00:00+02:00' -price: 0.19861 -- time: '2024-10-07 02:00:00+02:00' -price: 0.19608 -- time: '2024-10-07 03:00:00+02:00' -price: 0.1921 -- time: '2024-10-07 04:00:00+02:00' -price: 0.19646 -- time: '2024-10-07 05:00:00+02:00' -price: 0.20788 -- time: '2024-10-07 06:00:00+02:00' -price: 0.23338 -- time: '2024-10-07 07:00:00+02:00' -price: 0.27927 -- time: '2024-10-07 08:00:00+02:00' -price: 0.28692 -- time: '2024-10-07 09:00:00+02:00' -price: 0.26696 -- time: '2024-10-07 10:00:00+02:00' -price: 0.23577 -- time: '2024-10-07 11:00:00+02:00' -price: 0.22869 -- time: '2024-10-07 12:00:00+02:00' -price: 0.21136 -- time: '2024-10-07 13:00:00+02:00' -price: 0.20823 -- time: '2024-10-07 14:00:00+02:00' -price: 0.2224 -- time: '2024-10-07 15:00:00+02:00' -price: 0.2302 -- time: '2024-10-07 16:00:00+02:00' -price: 0.26328 -- time: '2024-10-07 17:00:00+02:00' -price: 0.29185 -- time: '2024-10-07 18:00:00+02:00' -price: 0.4313 -- time: '2024-10-07 19:00:00+02:00' -price: 0.41885 -- time: '2024-10-07 20:00:00+02:00' -price: 0.31004 -- time: '2024-10-07 21:00:00+02:00' -price: 0.27674 -- time: '2024-10-07 22:00:00+02:00' -price: 0.26999 -- time: '2024-10-07 23:00:00+02:00' -price: 0.25158 -- time: '2024-10-06 14:00:00+02:00' -price: 0.15584 -- time: '2024-10-06 19:00:00+02:00' -price: 0.28447 \ No newline at end of file From a496e5d69da423366aea63551d2577b6408a2310 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Sun, 6 Oct 2024 21:11:08 +0200 Subject: [PATCH 07/10] More descriptive names --- custom_components/entsoe/coordinator.py | 4 ++-- custom_components/entsoe/sensor.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/custom_components/entsoe/coordinator.py b/custom_components/entsoe/coordinator.py index 58b9151..53e39a6 100644 --- a/custom_components/entsoe/coordinator.py +++ b/custom_components/entsoe/coordinator.py @@ -200,7 +200,7 @@ def _filter_calculated_hourprices(self, data): # sliding = calculations made on all data from the current hour and beyond (future data only) elif self.calculation_mode == CALCULATION_MODE["sliding"]: now = dt.now().replace(minute=0, second=0, microsecond=0) - return {hour: price for hour, price in data.items() if now < hour < now + timedelta(hours=16)} + return {hour: price for hour, price in data.items() if hour >= now} # rotation = calculations made on all data of today and tomorrow (48 hrs) if we have 72hrs of data elif self.calculation_mode == CALCULATION_MODE["publish"] and len(data) > 48: return {hour: price for hour, price in data.items() if hour >= self.today} @@ -274,7 +274,7 @@ def get_min_time(self): def get_percentage_of_max(self): return round(self.get_current_hourprice() / self.get_max_price() * 100, 1) - def get_percentage(self): + def get_percentage_of_range(self): min = self.get_min_price() spread = self.get_max_price() - min current = self.get_current_hourprice() - min diff --git a/custom_components/entsoe/sensor.py b/custom_components/entsoe/sensor.py index 5f1c1e1..9dabf4d 100644 --- a/custom_components/entsoe/sensor.py +++ b/custom_components/entsoe/sensor.py @@ -106,13 +106,13 @@ def sensor_descriptions( value_fn=lambda coordinator: coordinator.get_percentage_of_max(), ), EntsoeEntityDescription( - key="percentage", - name="Current percentage", + key="percentage_of_range", + name="Current Price Percentage in Range", native_unit_of_measurement=f"{PERCENTAGE}", icon="mdi:percent", suggested_display_precision=1, state_class=SensorStateClass.MEASUREMENT, - value_fn=lambda coordinator: coordinator.get_percentage(), + value_fn=lambda coordinator: coordinator.get_percentage_of_range(), ), EntsoeEntityDescription( key="highest_price_time_today", From ca63ab86b77e7fd37662d77818f33429d7f1bc09 Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:08:59 +0200 Subject: [PATCH 08/10] Now filling the empty hours based on XML response Changed the code to fill missing hours based on the start/end times given in the response message. --- custom_components/entsoe/api_client.py | 41 +++++++++++++------------- custom_components/entsoe/sensor.py | 2 +- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 058d2a4..7cd045c 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -82,10 +82,16 @@ def query_day_ahead_prices( if resolution != "PT60M": continue - start_time = period.find(".//timeInterval/start").text + response_start = period.find(".//timeInterval/start").text + start_time = ( + datetime.strptime(response_start, "%Y-%m-%dT%H:%MZ") + .replace(tzinfo=pytz.UTC) + .astimezone() + ) - date = ( - datetime.strptime(start_time, "%Y-%m-%dT%H:%MZ") + response_end = period.find(".//timeInterval/start").text + end_time = ( + datetime.strptime(response_end, "%Y-%m-%dT%H:%MZ") .replace(tzinfo=pytz.UTC) .astimezone() ) @@ -94,28 +100,21 @@ def query_day_ahead_prices( position = point.find(".//position").text price = point.find(".//price.amount").text hour = int(position) - 1 - series[date + timedelta(hours=hour)] = float(price) + series[start_time + timedelta(hours=hour)] = float(price) - # Get the min and max time from the server response - first_response_time = min(series.keys(), default=None) - last_response_time = max(series.keys(), default=None) + # Now fill in any missing hours + current_time = start_time + last_price = series[current_time] - if first_response_time is None or last_response_time is None: - return series # No valid data received from the server - - # Now only fill in missing hours between the first and last response times - current_time = first_response_time - last_price = series[current_time] - - while current_time <= last_response_time: - if current_time in series: - last_price = series[current_time] # Update to the current price - else: - series[current_time] = last_price # Fill with the last known price - current_time += timedelta(hours=1) + while current_time <= end_time: + if current_time in series: + last_price = series[current_time] # Update to the current price + else: + series[current_time] = last_price # Fill with the last known price + current_time += timedelta(hours=1) return series - + except Exception as exc: _LOGGER.debug(f"Failed to parse response content:{response.content}") raise exc diff --git a/custom_components/entsoe/sensor.py b/custom_components/entsoe/sensor.py index 9dabf4d..7c324c0 100644 --- a/custom_components/entsoe/sensor.py +++ b/custom_components/entsoe/sensor.py @@ -107,7 +107,7 @@ def sensor_descriptions( ), EntsoeEntityDescription( key="percentage_of_range", - name="Current Price Percentage in Range", + name="Current percentage in electricity price range", native_unit_of_measurement=f"{PERCENTAGE}", icon="mdi:percent", suggested_display_precision=1, From ee1083cd9c15525b2dc8396f78326bf819879f1e Mon Sep 17 00:00:00 2001 From: Pluimvee <124380379+Pluimvee@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:31:39 +0200 Subject: [PATCH 09/10] Copy values excluding the given endtime --- custom_components/entsoe/api_client.py | 7 +++++-- custom_components/entsoe/coordinator.py | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 7cd045c..57cc551 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -89,13 +89,15 @@ def query_day_ahead_prices( .astimezone() ) - response_end = period.find(".//timeInterval/start").text + response_end = period.find(".//timeInterval/end").text end_time = ( datetime.strptime(response_end, "%Y-%m-%dT%H:%MZ") .replace(tzinfo=pytz.UTC) .astimezone() ) + _LOGGER.debug(f"Period found is from {start_time} till {end_time}") + for point in period.findall(".//Point"): position = point.find(".//position").text price = point.find(".//price.amount").text @@ -106,10 +108,11 @@ def query_day_ahead_prices( current_time = start_time last_price = series[current_time] - while current_time <= end_time: + while current_time < end_time: # upto excluding! the endtime if current_time in series: last_price = series[current_time] # Update to the current price else: + _LOGGER.debug(f"Extending the price {last_price} of the previous hour to {current_time}") series[current_time] = last_price # Fill with the last known price current_time += timedelta(hours=1) diff --git a/custom_components/entsoe/coordinator.py b/custom_components/entsoe/coordinator.py index 53e39a6..6d2a79a 100644 --- a/custom_components/entsoe/coordinator.py +++ b/custom_components/entsoe/coordinator.py @@ -201,10 +201,10 @@ def _filter_calculated_hourprices(self, data): elif self.calculation_mode == CALCULATION_MODE["sliding"]: now = dt.now().replace(minute=0, second=0, microsecond=0) return {hour: price for hour, price in data.items() if hour >= now} - # rotation = calculations made on all data of today and tomorrow (48 hrs) if we have 72hrs of data + # publish >48 hrs of data = calculations made on all data of today and tomorrow (48 hrs) elif self.calculation_mode == CALCULATION_MODE["publish"] and len(data) > 48: return {hour: price for hour, price in data.items() if hour >= self.today} - # rotation = calculations made on all data of yesterday and today (48 hrs) + # publish <=48 hrs of data = calculations made on all data of yesterday and today (48 hrs) elif self.calculation_mode == CALCULATION_MODE["publish"]: return { hour: price From bd09eea86bbe348ceefc5de7061b67b80092bfe8 Mon Sep 17 00:00:00 2001 From: Roeland Lutters <3277418+Roeland54@users.noreply.github.com> Date: Mon, 7 Oct 2024 16:31:24 +0200 Subject: [PATCH 10/10] Sort the parsed response after adding missing values --- custom_components/entsoe/api_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/entsoe/api_client.py b/custom_components/entsoe/api_client.py index 57cc551..0495d59 100644 --- a/custom_components/entsoe/api_client.py +++ b/custom_components/entsoe/api_client.py @@ -116,7 +116,7 @@ def query_day_ahead_prices( series[current_time] = last_price # Fill with the last known price current_time += timedelta(hours=1) - return series + return dict(sorted(series.items())) except Exception as exc: _LOGGER.debug(f"Failed to parse response content:{response.content}")