Add Avri waste collection sensor (#31134)
* Add Avri waste collection sensor * Apply black formatting * Update manifest * Add requirements * Add sensor to coverage * Update import order * Bump dependency to include todays pickup * Bump avri version in requirements_all.txt * Code review comments * Reduce scan interval to 4 hours This makes sure that no matter what happens, in the morning the correct dates have been pulled without the old ones lingering for too long. * Better logging * Made scan interval a timedelta * Fix import order * Update homeassistant/components/avri/sensor.py Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com> * Update homeassistant/components/avri/sensor.py Co-Authored-By: springstan <46536646+springstan@users.noreply.github.com> * Use filter instead of break statement * Use positive int for house number extension * Switch voluptuous types for house number and house number extension * Update homeassistant/components/avri/sensor.py Co-Authored-By: Paulus Schoutsen <paulus@home-assistant.io> * Implement `available` * Bump avri api * Code review comments * Replace `postcode` with `zip_code` * Update logic for `available` * Remove variable for delimiter Co-authored-by: springstan <46536646+springstan@users.noreply.github.com> Co-authored-by: Paulus Schoutsen <paulus@home-assistant.io>
This commit is contained in:
parent
02c170b961
commit
1d962aeb65
6 changed files with 130 additions and 0 deletions
|
@ -65,6 +65,7 @@ omit =
|
|||
homeassistant/components/automatic/device_tracker.py
|
||||
homeassistant/components/avea/light.py
|
||||
homeassistant/components/avion/light.py
|
||||
homeassistant/components/avri/sensor.py
|
||||
homeassistant/components/azure_event_hub/*
|
||||
homeassistant/components/azure_service_bus/*
|
||||
homeassistant/components/baidu/tts.py
|
||||
|
|
|
@ -41,6 +41,7 @@ homeassistant/components/auth/* @home-assistant/core
|
|||
homeassistant/components/automatic/* @armills
|
||||
homeassistant/components/automation/* @home-assistant/core
|
||||
homeassistant/components/avea/* @pattyland
|
||||
homeassistant/components/avri/* @timvancann
|
||||
homeassistant/components/awair/* @danielsjf
|
||||
homeassistant/components/aws/* @awarecan @robbiet480
|
||||
homeassistant/components/axis/* @kane610
|
||||
|
|
1
homeassistant/components/avri/__init__.py
Normal file
1
homeassistant/components/avri/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
"""The avri component."""
|
8
homeassistant/components/avri/manifest.json
Normal file
8
homeassistant/components/avri/manifest.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"domain": "avri",
|
||||
"name": "Avri",
|
||||
"documentation": "https://www.home-assistant.io/integrations/avri",
|
||||
"requirements": ["avri-api==0.1.6"],
|
||||
"dependencies": [],
|
||||
"codeowners": ["@timvancann"]
|
||||
}
|
116
homeassistant/components/avri/sensor.py
Normal file
116
homeassistant/components/avri/sensor.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
"""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()
|
|
@ -278,6 +278,9 @@ avea==1.4
|
|||
# homeassistant.components.avion
|
||||
# avion==0.10
|
||||
|
||||
# homeassistant.components.avri
|
||||
avri-api==0.1.6
|
||||
|
||||
# homeassistant.components.axis
|
||||
axis==25
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue