"""Support for Avri waste curbside collection pickup.""" from datetime import timedelta import logging from avri.api import Avri, AvriException import voluptuous as vol from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import CONF_NAME from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity _LOGGER = logging.getLogger(__name__) CONF_COUNTRY_CODE = "country_code" CONF_ZIP_CODE = "zip_code" CONF_HOUSE_NUMBER = "house_number" CONF_HOUSE_NUMBER_EXTENSION = "house_number_extension" DEFAULT_NAME = "avri" ICON = "mdi:trash-can-outline" SCAN_INTERVAL = timedelta(hours=4) DEFAULT_COUNTRY_CODE = "NL" PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_ZIP_CODE): cv.string, vol.Required(CONF_HOUSE_NUMBER): cv.positive_int, vol.Optional(CONF_HOUSE_NUMBER_EXTENSION): cv.string, vol.Optional(CONF_COUNTRY_CODE, default=DEFAULT_COUNTRY_CODE): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, } ) def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Avri Waste platform.""" client = Avri( postal_code=config[CONF_ZIP_CODE], house_nr=config[CONF_HOUSE_NUMBER], house_nr_extension=config.get(CONF_HOUSE_NUMBER_EXTENSION), country_code=config[CONF_COUNTRY_CODE], ) try: each_upcoming = client.upcoming_of_each() except AvriException as ex: raise PlatformNotReady from ex else: entities = [ AvriWasteUpcoming(config[CONF_NAME], client, upcoming.name) for upcoming in each_upcoming ] add_entities(entities, True) class AvriWasteUpcoming(Entity): """Avri Waste Sensor.""" def __init__(self, name: str, client: Avri, waste_type: str): """Initialize the sensor.""" self._waste_type = waste_type self._name = f"{name}_{self._waste_type}" self._state = None self._client = client self._state_available = False @property def name(self): """Return the name of the sensor.""" return self._name @property def unique_id(self) -> str: """Return a unique ID.""" return ( f"{self._waste_type}" f"-{self._client.country_code}" f"-{self._client.postal_code}" f"-{self._client.house_nr}" f"-{self._client.house_nr_extension}" ) @property def state(self): """Return the state of the sensor.""" return self._state @property def available(self): """Return True if entity is available.""" return self._state_available @property def icon(self): """Icon to use in the frontend.""" return ICON def update(self): """Update device state.""" try: pickup_events = self._client.upcoming_of_each() except AvriException as ex: _LOGGER.error( "There was an error retrieving upcoming garbage pickups: %s", ex ) self._state_available = False self._state = None else: self._state_available = True matched_events = list( filter(lambda event: event.name == self._waste_type, pickup_events) ) if not matched_events: self._state = None else: self._state = matched_events[0].day.date()