79 lines
2.5 KiB
Python
79 lines
2.5 KiB
Python
"""Common Met Office Data class used by both sensor and entity."""
|
|
|
|
import logging
|
|
|
|
import datapoint
|
|
|
|
from .const import MODE_3HOURLY
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
class MetOfficeData:
|
|
"""Get current and forecast data from Datapoint.
|
|
|
|
Please note that the 'datapoint' library is not asyncio-friendly, so some
|
|
calls have had to be wrapped with the standard hassio helper
|
|
async_add_executor_job.
|
|
"""
|
|
|
|
def __init__(self, hass, api_key, latitude, longitude):
|
|
"""Initialize the data object."""
|
|
self._hass = hass
|
|
self._datapoint = datapoint.connection(api_key=api_key)
|
|
self._site = None
|
|
|
|
# Public attributes
|
|
self.latitude = latitude
|
|
self.longitude = longitude
|
|
|
|
# Holds the current data from the Met Office
|
|
self.site_id = None
|
|
self.site_name = None
|
|
self.now = None
|
|
|
|
async def async_update_site(self):
|
|
"""Async wrapper for getting the DataPoint site."""
|
|
return await self._hass.async_add_executor_job(self._update_site)
|
|
|
|
def _update_site(self):
|
|
"""Return the nearest DataPoint Site to the held latitude/longitude."""
|
|
try:
|
|
new_site = self._datapoint.get_nearest_forecast_site(
|
|
latitude=self.latitude, longitude=self.longitude
|
|
)
|
|
if self._site is None or self._site.id != new_site.id:
|
|
self._site = new_site
|
|
self.now = None
|
|
|
|
self.site_id = self._site.id
|
|
self.site_name = self._site.name
|
|
|
|
except datapoint.exceptions.APIException as err:
|
|
_LOGGER.error("Received error from Met Office Datapoint: %s", err)
|
|
self._site = None
|
|
self.site_id = None
|
|
self.site_name = None
|
|
self.now = None
|
|
|
|
return self._site
|
|
|
|
async def async_update(self):
|
|
"""Async wrapper for update method."""
|
|
return await self._hass.async_add_executor_job(self._update)
|
|
|
|
def _update(self):
|
|
"""Get the latest data from DataPoint."""
|
|
if self._site is None:
|
|
_LOGGER.error("No Met Office forecast site held, check logs for problems")
|
|
return
|
|
|
|
try:
|
|
forecast = self._datapoint.get_forecast_for_site(
|
|
self._site.id, MODE_3HOURLY
|
|
)
|
|
self.now = forecast.now()
|
|
except (ValueError, datapoint.exceptions.APIException) as err:
|
|
_LOGGER.error("Check Met Office connection: %s", err.args)
|
|
self.now = None
|