Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issue with late published prices #333

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 17 additions & 10 deletions custom_components/nordpool/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import logging
from collections import defaultdict
from datetime import datetime, timedelta
from functools import partial
from datetime import timedelta
from random import randint

import backoff
import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Config, HomeAssistant
Expand All @@ -13,7 +13,7 @@
from homeassistant.util import dt as dt_utils
from pytz import timezone

from .aio_price import AioPrices
from .aio_price import AioPrices, InvalidValueException
from .events import async_track_time_change_in_tz

DOMAIN = "nordpool"
Expand Down Expand Up @@ -74,12 +74,12 @@ async def _update(self, type_="today", dt=None):
if data:
self._data[currency][type_] = data["areas"]

async def update_today(self, _: datetime):
async def update_today(self):
"""Update today's prices"""
_LOGGER.debug("Updating today's prices.")
await self._update("today")

async def update_tomorrow(self, _: datetime):
async def update_tomorrow(self):
"""Update tomorrows prices."""
_LOGGER.debug("Updating tomorrows prices.")
await self._update(type_="tomorrow", dt=dt_utils.now() + timedelta(hours=24))
Expand All @@ -96,8 +96,11 @@ async def _someday(self, area: str, currency: str, day: str):
# set in the sensor.
if currency not in self.currency:
self.currency.append(currency)
await self.update_today(None)
await self.update_tomorrow(None)
await self.update_today()
try:
await self.update_tomorrow()
except InvalidValueException:
_LOGGER.debug("No data available for tomorrow, retrying later")

# Send a new data request after new data is updated for this first run
# This way if the user has multiple sensors they will all update
Expand Down Expand Up @@ -128,7 +131,7 @@ async def new_day_cb(_):

for curr in api.currency:
if not api._data.get(curr, {}).get("tomorrow"):
api._data[curr]["today"] = await api.update_today(None)
api._data[curr]["today"] = await api.update_today()
else:
api._data[curr]["today"] = api._data[curr]["tomorrow"]
api._data[curr]["tomorrow"] = {}
Expand All @@ -140,12 +143,16 @@ async def new_hr(_):
_LOGGER.debug("Called new_hr callback")
async_dispatcher_send(hass, EVENT_NEW_HOUR)

async def new_data_cb(tdo):
@backoff.on_exception(
backoff.constant,
(InvalidValueException),
logger=_LOGGER, interval=600, max_time=7200, jitter=None)
async def new_data_cb(_):
"""Callback to fetch new data for tomorrows prices at 1300ish CET
and notify any sensors, about the new data
"""
# _LOGGER.debug("Called new_data_cb")
await api.update_tomorrow(tdo)
await api.update_tomorrow()
async_dispatcher_send(hass, EVENT_NEW_PRICE)

# Handles futures updates
Expand Down
13 changes: 12 additions & 1 deletion custom_components/nordpool/aio_price.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@
"PL ": "PL",
}

INVALID_VALUES = frozenset((None, float("inf")))


class InvalidValueException(ValueError):
pass


def join_result_for_correct_time(results, dt):
"""Parse a list of responses from the api
Expand Down Expand Up @@ -135,6 +141,8 @@ def join_result_for_correct_time(results, dt):
local = val["start"].astimezone(zone)
local_end = val["end"].astimezone(zone)
if start_of_day <= local and local <= end_of_day:
if val['value'] in INVALID_VALUES:
raise InvalidValueException()
if local == local_end:
_LOGGER.info(
"Hour has the same start and end, most likly due to dst change %s exluded this hour",
Expand Down Expand Up @@ -179,7 +187,10 @@ async def _fetch_json(self, data_type, end_date=None):

# Add more exceptions as we find them. KeyError is raised when the api return
# junk due to currency not being available in the data.
@backoff.on_exception(backoff.expo, (aiohttp.ClientError, KeyError), logger=_LOGGER)
@backoff.on_exception(
backoff.expo,
(aiohttp.ClientError, KeyError),
logger=_LOGGER, max_value=20, max_time=60)
async def fetch(self, data_type, end_date=None, areas=None):
"""
Fetch data from API.
Expand Down
Loading