Move ReCollect Waste "next pickup" info to its own sensor (#62558)

This commit is contained in:
Aaron Bach 2022-01-06 08:05:48 -07:00 committed by GitHub
parent 1baa3d87d1
commit c341adb0d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 28 deletions

View File

@ -2,14 +2,15 @@
from __future__ import annotations
from datetime import date, timedelta
from typing import Any
from aiorecollect.client import Client, PickupEvent
from aiorecollect.errors import RecollectError
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import aiohttp_client
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import aiohttp_client, entity_registry as er
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import CONF_PLACE_ID, CONF_SERVICE_ID, DOMAIN, LOGGER
@ -69,3 +70,32 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Migrate an old config entry."""
version = entry.version
LOGGER.debug("Migrating from version %s", version)
# 1 -> 2: Update unique ID of existing, single sensor entity to be consistent with
# common format for platforms going forward:
if version == 1:
version = entry.version = 2
@callback
def migrate_unique_id(entity_entry: er.RegistryEntry) -> dict[str, Any]:
"""Migrate the unique ID to a new format."""
return {
"new_unique_id": (
f"{entry.data[CONF_PLACE_ID]}_"
f"{entry.data[CONF_SERVICE_ID]}_"
"current_pickup"
)
}
await er.async_migrate_entries(hass, entry.entry_id, migrate_unique_id)
LOGGER.info("Migration to version %s successful", version)
return True

View File

@ -23,7 +23,7 @@ DATA_SCHEMA = vol.Schema(
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for ReCollect Waste."""
VERSION = 1
VERSION = 2
@staticmethod
@callback

View File

@ -3,7 +3,11 @@ from __future__ import annotations
from aiorecollect.client import PickupType
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_FRIENDLY_NAME
from homeassistant.core import HomeAssistant, callback
@ -13,14 +17,24 @@ from homeassistant.helpers.update_coordinator import (
DataUpdateCoordinator,
)
from .const import CONF_PLACE_ID, CONF_SERVICE_ID, DOMAIN
from .const import CONF_PLACE_ID, CONF_SERVICE_ID, DOMAIN, LOGGER
ATTR_PICKUP_TYPES = "pickup_types"
ATTR_AREA_NAME = "area_name"
ATTR_NEXT_PICKUP_TYPES = "next_pickup_types"
ATTR_NEXT_PICKUP_DATE = "next_pickup_date"
DEFAULT_NAME = "Waste Pickup"
SENSOR_TYPE_CURRENT_PICKUP = "current_pickup"
SENSOR_TYPE_NEXT_PICKUP = "next_pickup"
SENSOR_DESCRIPTIONS = (
SensorEntityDescription(
key=SENSOR_TYPE_CURRENT_PICKUP,
name="Current Pickup",
),
SensorEntityDescription(
key=SENSOR_TYPE_NEXT_PICKUP,
name="Next Pickup",
),
)
@callback
@ -41,7 +55,13 @@ async def async_setup_entry(
) -> None:
"""Set up ReCollect Waste sensors based on a config entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities([ReCollectWasteSensor(coordinator, entry)])
async_add_entities(
[
ReCollectWasteSensor(coordinator, entry, description)
for description in SENSOR_DESCRIPTIONS
]
)
class ReCollectWasteSensor(CoordinatorEntity, SensorEntity):
@ -49,16 +69,19 @@ class ReCollectWasteSensor(CoordinatorEntity, SensorEntity):
_attr_device_class = SensorDeviceClass.DATE
def __init__(self, coordinator: DataUpdateCoordinator, entry: ConfigEntry) -> None:
def __init__(
self,
coordinator: DataUpdateCoordinator,
entry: ConfigEntry,
description: SensorEntityDescription,
) -> None:
"""Initialize the sensor."""
super().__init__(coordinator)
self._attr_extra_state_attributes = {}
self._attr_name = DEFAULT_NAME
self._attr_unique_id = (
f"{entry.data[CONF_PLACE_ID]}{entry.data[CONF_SERVICE_ID]}"
)
self._attr_unique_id = f"{entry.data[CONF_PLACE_ID]}_{entry.data[CONF_SERVICE_ID]}_{description.key}"
self._entry = entry
self.entity_description = description
@callback
def _handle_coordinator_update(self) -> None:
@ -74,24 +97,25 @@ class ReCollectWasteSensor(CoordinatorEntity, SensorEntity):
@callback
def update_from_latest_data(self) -> None:
"""Update the state."""
try:
pickup_event = self.coordinator.data[0]
next_pickup_event = self.coordinator.data[1]
except IndexError:
self._attr_native_value = None
self._attr_extra_state_attributes = {}
return
if self.entity_description.key == SENSOR_TYPE_CURRENT_PICKUP:
try:
event = self.coordinator.data[0]
except IndexError:
LOGGER.error("No current pickup found")
return
else:
try:
event = self.coordinator.data[1]
except IndexError:
LOGGER.info("No next pickup found")
return
self._attr_extra_state_attributes.update(
{
ATTR_PICKUP_TYPES: async_get_pickup_type_names(
self._entry, pickup_event.pickup_types
self._entry, event.pickup_types
),
ATTR_AREA_NAME: pickup_event.area_name,
ATTR_NEXT_PICKUP_TYPES: async_get_pickup_type_names(
self._entry, next_pickup_event.pickup_types
),
ATTR_NEXT_PICKUP_DATE: next_pickup_event.date.isoformat(),
ATTR_AREA_NAME: event.area_name,
}
)
self._attr_native_value = pickup_event.date
self._attr_native_value = event.date