Skip to content

Commit

Permalink
Merge pull request #191 from Pluimvee/main
Browse files Browse the repository at this point in the history
Adding percentage of spread & Resolve missing hours issue
  • Loading branch information
Roeland54 authored Oct 7, 2024
2 parents f5a68f1 + bd09eea commit b9cfb8d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 5 deletions.
31 changes: 26 additions & 5 deletions custom_components/entsoe/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,21 +82,42 @@ 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/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
hour = int(position) - 1
series[date + timedelta(hours=hour)] = float(price)
series[start_time + timedelta(hours=hour)] = float(price)

# Now fill in any missing hours
current_time = start_time
last_price = series[current_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)

return dict(sorted(series.items()))

return series
except Exception as exc:
_LOGGER.debug(f"Failed to parse response content:{response.content}")
raise exc
Expand Down
10 changes: 10 additions & 0 deletions custom_components/entsoe/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}
# 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}
# 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
Expand Down Expand Up @@ -270,6 +274,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_of_range(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():
Expand Down
9 changes: 9 additions & 0 deletions custom_components/entsoe/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ def sensor_descriptions(
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda coordinator: coordinator.get_percentage_of_max(),
),
EntsoeEntityDescription(
key="percentage_of_range",
name="Current percentage in electricity price 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_of_range(),
),
EntsoeEntityDescription(
key="highest_price_time_today",
name="Time of highest price",
Expand Down

0 comments on commit b9cfb8d

Please sign in to comment.