diff --git a/custom_components/knmi/__init__.py b/custom_components/knmi/__init__.py index 0386f61..eaf1ce9 100644 --- a/custom_components/knmi/__init__.py +++ b/custom_components/knmi/__init__.py @@ -9,7 +9,7 @@ import logging from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME, CONF_API_KEY +from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_API_KEY from homeassistant.core import Config, HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession diff --git a/custom_components/knmi/api.py b/custom_components/knmi/api.py index 6e12043..16ee96f 100644 --- a/custom_components/knmi/api.py +++ b/custom_components/knmi/api.py @@ -38,6 +38,9 @@ async def api_wrapper(self, method: str, url: str) -> dict: if "Vraag eerst een API-key op" in await response.text(): raise KnmiApiKeyException("Invalid API key") + if "Dagelijkse limiet" in await response.text(): + raise KnmiApiKeyException("Exceeded Daily Limit") + data = await response.json() return data.get("liveweer")[0] @@ -61,7 +64,7 @@ async def api_wrapper(self, method: str, url: str) -> dict: exception, ) except KnmiApiKeyException as exception: - _LOGGER.error("Error with configuration! - %s", exception) + _LOGGER.error("Error in API! - %s", exception) # Raise to pass on to the user. raise exception except Exception as exception: # pylint: disable=broad-except diff --git a/custom_components/knmi/binary_sensor.py b/custom_components/knmi/binary_sensor.py index 52f7e17..9580bfe 100644 --- a/custom_components/knmi/binary_sensor.py +++ b/custom_components/knmi/binary_sensor.py @@ -1,5 +1,6 @@ """Binary sensor platform for knmi.""" from homeassistant.components.binary_sensor import BinarySensorEntity +from homeassistant.const import CONF_NAME from .const import ( BINARY_SENSORS, @@ -43,8 +44,7 @@ def __init__( data_key, ): super().__init__(coordinator, config_entry) - self.config_entry = config_entry - self.location_name = self.coordinator.data["plaats"] + self.entry_name = config_entry.data.get(CONF_NAME) self._name = name self._icon = icon self._device_class = device_class @@ -54,12 +54,13 @@ def __init__( @property def name(self): """Return the name of the binary_sensor.""" - return f"{DEFAULT_NAME} {self.location_name} {self._name}" + return f"{DEFAULT_NAME} {self.entry_name} {self._name}" @property def is_on(self): """Return true if the binary_sensor is on.""" - return self.coordinator.data[self._data_key] != "0" + if super().getData(self._data_key) is not None: + return super().getData(self._data_key) != "0" @property def icon(self): @@ -78,7 +79,7 @@ def extra_state_attributes(self): for attribute in self._attributes: value = None if "key" in attribute: - value = self.coordinator.data[attribute.get("key", None)] + value = super().getData(attribute.get("key", None)) if "value" in attribute: value = attribute.get("value", None) attributes[attribute.get("name", None)] = value diff --git a/custom_components/knmi/const.py b/custom_components/knmi/const.py index c962882..9c7769f 100644 --- a/custom_components/knmi/const.py +++ b/custom_components/knmi/const.py @@ -26,7 +26,7 @@ # Base component constants. NAME = "KNMI" DOMAIN = "knmi" -VERSION = "1.1.4" +VERSION = "1.1.5" ATTRIBUTION = "KNMI Weergegevens via https://weerlive.nl/" # Platforms. diff --git a/custom_components/knmi/entity.py b/custom_components/knmi/entity.py index 0b18806..af00701 100644 --- a/custom_components/knmi/entity.py +++ b/custom_components/knmi/entity.py @@ -8,8 +8,15 @@ class KnmiEntity(CoordinatorEntity): def __init__(self, coordinator, config_entry): super().__init__(coordinator) + self.coordinator = coordinator self.config_entry = config_entry + def getData(self, key): + """Return the data key from the coordinator.""" + if self.coordinator.data is not None: + return self.coordinator.data[key] + return None + @property def unique_id(self): """Return a unique ID to use for this entity.""" diff --git a/custom_components/knmi/manifest.json b/custom_components/knmi/manifest.json index 859318e..abf3a85 100644 --- a/custom_components/knmi/manifest.json +++ b/custom_components/knmi/manifest.json @@ -4,7 +4,7 @@ "documentation": "https://github.com/golles/ha-knmi/", "iot_class": "cloud_polling", "issue_tracker": "https://github.com/golles/ha-knmi//issues", - "version": "1.1.4", + "version": "1.1.5", "config_flow": true, "codeowners": [ "@golles" diff --git a/custom_components/knmi/sensor.py b/custom_components/knmi/sensor.py index 697acba..81b89d5 100644 --- a/custom_components/knmi/sensor.py +++ b/custom_components/knmi/sensor.py @@ -1,4 +1,5 @@ """Sensor platform for knmi.""" +from homeassistant.const import CONF_NAME from .const import DEFAULT_NAME, DOMAIN, SENSORS from .entity import KnmiEntity @@ -40,8 +41,7 @@ def __init__( data_key, ): super().__init__(coordinator, config_entry) - self.config_entry = config_entry - self.location_name = self.coordinator.data["plaats"] + self.entry_name = config_entry.data.get(CONF_NAME) self._name = name self._unit_of_measurement = unit_of_measurement self._icon = icon @@ -52,12 +52,12 @@ def __init__( @property def name(self): """Return the name of the sensor.""" - return f"{DEFAULT_NAME} {self.location_name} {self._name}" + return f"{DEFAULT_NAME} {self.entry_name} {self._name}" @property def state(self): """Return the state of the sensor.""" - return self.coordinator.data[self._data_key] + return super().getData(self._data_key) @property def unit_of_measurement(self): @@ -81,7 +81,7 @@ def extra_state_attributes(self): for attribute in self._attributes: value = None if "key" in attribute: - value = self.coordinator.data[attribute.get("key", None)] + value = super().getData(attribute.get("key", None)) if "value" in attribute: value = attribute.get("value", None) attributes[attribute.get("name", None)] = value diff --git a/custom_components/knmi/weather.py b/custom_components/knmi/weather.py index 1cd958e..3adacff 100644 --- a/custom_components/knmi/weather.py +++ b/custom_components/knmi/weather.py @@ -13,6 +13,7 @@ WeatherEntity, ) from homeassistant.const import ( + CONF_NAME, TEMP_CELSIUS, ) @@ -29,11 +30,14 @@ async def async_setup_entry(hass, entry, async_add_devices): class KnmiWeather(KnmiEntity, WeatherEntity): """knmi Weather class.""" + def __init__(self, coordinator, config_entry): + super().__init__(coordinator, config_entry) + self.entry_name = config_entry.data.get(CONF_NAME) + @property def name(self): """Return the name of the sensor.""" - location = self.coordinator.data["plaats"] - return f"{DEFAULT_NAME} {location}" + return f"{DEFAULT_NAME} {self.entry_name}" @property def state(self): @@ -43,12 +47,14 @@ def state(self): @property def condition(self): """Return the current condition.""" - return CONDITIONS_MAP[self.coordinator.data["d0weer"]] + if super().getData("d0weer") is not None: + return CONDITIONS_MAP[super().getData("d0weer")] @property def temperature(self): """Return the temperature.""" - return float(self.coordinator.data["temp"]) + if super().getData("temp") is not None: + return float(super().getData("temp")) @property def temperature_unit(self): @@ -58,27 +64,32 @@ def temperature_unit(self): @property def pressure(self): """Return the pressure.""" - return float(self.coordinator.data["luchtd"]) + if super().getData("luchtd") is not None: + return float(super().getData("luchtd")) @property def humidity(self): """Return the humidity.""" - return float(self.coordinator.data["lv"]) + if super().getData("lv") is not None: + return float(super().getData("lv")) @property def wind_speed(self): """Return the wind speed.""" - return float(self.coordinator.data["windkmh"]) + if super().getData("windkmh") is not None: + return float(super().getData("windkmh")) @property def wind_bearing(self): """Return the wind direction.""" - return WIND_DIRECTION_MAP[self.coordinator.data["windr"]] + if super().getData("windr") is not None: + return WIND_DIRECTION_MAP[super().getData("windr")] @property def visibility(self): """Return the wind direction.""" - return float(self.coordinator.data["zicht"]) / 10 + if super().getData("zicht") is not None: + return float(super().getData("zicht")) / 10 @property def forecast(self): @@ -88,21 +99,45 @@ def forecast(self): for i in range(0, 3): date = today + timedelta(days=i) - nextDay = { + condition = ( + CONDITIONS_MAP[super().getData(f"d{i}weer")] + if super().getData(f"d{i}weer") is not None + else None + ) + wind_bearing = ( + WIND_DIRECTION_MAP[super().getData(f"d{i}windr")] + if super().getData(f"d{i}windr") is not None + else None + ) + temp_low = ( + float(super().getData(f"d{i}tmin")) + if super().getData(f"d{i}tmin") is not None + else None + ) + temp = ( + float(super().getData(f"d{i}tmin")) + if super().getData(f"d{i}tmin") is not None + else None + ) + precipitation = ( + float(super().getData(f"d{i}neerslag")) + if super().getData(f"d{i}neerslag") is not None + else None + ) + wind_speed = ( + float(super().getData(f"d{i}windkmh")) + if super().getData(f"d{i}windkmh") is not None + else None + ) + next_day = { ATTR_FORECAST_TIME: date.isoformat(), - ATTR_FORECAST_CONDITION: CONDITIONS_MAP[ - self.coordinator.data[f"d{i}weer"] - ], - ATTR_FORECAST_TEMP_LOW: float(self.coordinator.data[f"d{i}tmin"]), - ATTR_FORECAST_TEMP: float(self.coordinator.data[f"d{i}tmax"]), - ATTR_FORECAST_PRECIPITATION: float( - self.coordinator.data[f"d{i}neerslag"] - ), - ATTR_FORECAST_WIND_BEARING: WIND_DIRECTION_MAP[ - self.coordinator.data[f"d{i}windr"] - ], - ATTR_FORECAST_WIND_SPEED: float(self.coordinator.data[f"d{i}windkmh"]), + ATTR_FORECAST_CONDITION: condition, + ATTR_FORECAST_TEMP_LOW: temp_low, + ATTR_FORECAST_TEMP: temp, + ATTR_FORECAST_PRECIPITATION: precipitation, + ATTR_FORECAST_WIND_BEARING: wind_bearing, + ATTR_FORECAST_WIND_SPEED: wind_speed, } - forecast.append(nextDay) + forecast.append(next_day) return forecast