diff --git a/homeassistant/components/twentemilieu/sensor.py b/homeassistant/components/twentemilieu/sensor.py index 14568fa5d87..4b76f3f475b 100644 --- a/homeassistant/components/twentemilieu/sensor.py +++ b/homeassistant/components/twentemilieu/sensor.py @@ -10,10 +10,10 @@ from twentemilieu import ( TwenteMilieuConnectionError, ) -from homeassistant.components.sensor import SensorEntity +from homeassistant.components.sensor import SensorEntity, SensorEntityDescription from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_ID, DEVICE_CLASS_DATE -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.exceptions import PlatformNotReady from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import DeviceInfo @@ -23,6 +23,33 @@ from .const import DATA_UPDATE, DOMAIN PARALLEL_UPDATES = 1 +SENSORS: tuple[SensorEntityDescription, ...] = ( + SensorEntityDescription( + key=WASTE_TYPE_NON_RECYCLABLE, + name=f"{WASTE_TYPE_NON_RECYCLABLE} Waste Pickup", + icon="mdi:delete-empty", + device_class=DEVICE_CLASS_DATE, + ), + SensorEntityDescription( + key=WASTE_TYPE_ORGANIC, + name=f"{WASTE_TYPE_ORGANIC} Waste Pickup", + icon="mdi:delete-empty", + device_class=DEVICE_CLASS_DATE, + ), + SensorEntityDescription( + key=WASTE_TYPE_PAPER, + name=f"{WASTE_TYPE_PAPER} Waste Pickup", + icon="mdi:delete-empty", + device_class=DEVICE_CLASS_DATE, + ), + SensorEntityDescription( + key=WASTE_TYPE_PLASTIC, + name=f"{WASTE_TYPE_PLASTIC} Waste Pickup", + icon="mdi:delete-empty", + device_class=DEVICE_CLASS_DATE, + ), +) + async def async_setup_entry( hass: HomeAssistant, @@ -37,118 +64,46 @@ async def async_setup_entry( except TwenteMilieuConnectionError as exception: raise PlatformNotReady from exception - sensors = [ - TwenteMilieuSensor( - twentemilieu, - unique_id=entry.data[CONF_ID], - name=f"{WASTE_TYPE_NON_RECYCLABLE} Waste Pickup", - waste_type=WASTE_TYPE_NON_RECYCLABLE, - icon="mdi:delete-empty", - ), - TwenteMilieuSensor( - twentemilieu, - unique_id=entry.data[CONF_ID], - name=f"{WASTE_TYPE_ORGANIC} Waste Pickup", - waste_type=WASTE_TYPE_ORGANIC, - icon="mdi:delete-empty", - ), - TwenteMilieuSensor( - twentemilieu, - unique_id=entry.data[CONF_ID], - name=f"{WASTE_TYPE_PAPER} Waste Pickup", - waste_type=WASTE_TYPE_PAPER, - icon="mdi:delete-empty", - ), - TwenteMilieuSensor( - twentemilieu, - unique_id=entry.data[CONF_ID], - name=f"{WASTE_TYPE_PLASTIC} Waste Pickup", - waste_type=WASTE_TYPE_PLASTIC, - icon="mdi:delete-empty", - ), - ] - - async_add_entities(sensors, True) + async_add_entities( + [ + TwenteMilieuSensor(twentemilieu, entry.data[CONF_ID], description) + for description in SENSORS + ], + True, + ) class TwenteMilieuSensor(SensorEntity): """Defines a Twente Milieu sensor.""" - _attr_device_class = DEVICE_CLASS_DATE + _attr_should_poll = False def __init__( self, twentemilieu: TwenteMilieu, unique_id: str, - name: str, - waste_type: str, - icon: str, + description: SensorEntityDescription, ) -> None: """Initialize the Twente Milieu entity.""" - self._available = True - self._unique_id = unique_id - self._icon = icon - self._name = name + self.entity_description = description self._twentemilieu = twentemilieu - self._waste_type = waste_type - - self._state = None - - @property - def name(self) -> str: - """Return the name of the entity.""" - return self._name - - @property - def icon(self) -> str: - """Return the mdi icon of the entity.""" - return self._icon - - @property - def available(self) -> bool: - """Return True if entity is available.""" - return self._available - - @property - def unique_id(self) -> str: - """Return the unique ID for this sensor.""" - return f"{DOMAIN}_{self._unique_id}_{self._waste_type}" - - @property - def should_poll(self) -> bool: - """Return the polling requirement of the entity.""" - return False + self._attr_unique_id = f"{DOMAIN}_{unique_id}_{description.key}" + self._attr_device_info = DeviceInfo( + identifiers={(DOMAIN, unique_id)}, + manufacturer="Twente Milieu", + name="Twente Milieu", + ) async def async_added_to_hass(self) -> None: """Connect to dispatcher listening for entity data notifications.""" self.async_on_remove( async_dispatcher_connect( - self.hass, DATA_UPDATE, self._schedule_immediate_update + self.hass, DATA_UPDATE, self.async_schedule_update_ha_state ) ) - @callback - def _schedule_immediate_update(self, unique_id: str) -> None: - """Schedule an immediate update of the entity.""" - if unique_id == self._unique_id: - self.async_schedule_update_ha_state(True) - - @property - def native_value(self): - """Return the state of the sensor.""" - return self._state - async def async_update(self) -> None: """Update Twente Milieu entity.""" - next_pickup = await self._twentemilieu.next_pickup(self._waste_type) + next_pickup = await self._twentemilieu.next_pickup(self.entity_description.key) if next_pickup is not None: - self._state = next_pickup.date().isoformat() - - @property - def device_info(self) -> DeviceInfo: - """Return device information about Twente Milieu.""" - return DeviceInfo( - identifiers={(DOMAIN, self._unique_id)}, - manufacturer="Twente Milieu", - name="Twente Milieu", - ) + self._attr_native_value = next_pickup.date().isoformat()