From a9c5f68d646676cbe130d4af785b9866589bc624 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sat, 6 Nov 2021 08:13:48 -0500 Subject: [PATCH] Reduce code duplication in gogogate2 (#59165) --- homeassistant/components/gogogate2/common.py | 23 ++++-- homeassistant/components/gogogate2/cover.py | 42 +++-------- homeassistant/components/gogogate2/sensor.py | 73 +++++++------------- 3 files changed, 51 insertions(+), 87 deletions(-) diff --git a/homeassistant/components/gogogate2/common.py b/homeassistant/components/gogogate2/common.py index a70a1b6bf81..5d0392e6db2 100644 --- a/homeassistant/components/gogogate2/common.py +++ b/homeassistant/components/gogogate2/common.py @@ -80,18 +80,24 @@ class GoGoGate2Entity(CoordinatorEntity): super().__init__(data_update_coordinator) self._config_entry = config_entry self._door = door - self._unique_id = unique_id + self._door_id = door.door_id + self._api = data_update_coordinator.api + self._attr_unique_id = unique_id @property - def unique_id(self) -> str | None: - """Return a unique ID.""" - return self._unique_id - - def _get_door(self) -> AbstractDoor: + def door(self) -> AbstractDoor: + """Return the door object.""" door = get_door_by_id(self._door.door_id, self.coordinator.data) self._door = door or self._door return self._door + @property + def door_status(self) -> AbstractDoor: + """Return the door with status.""" + data = self.coordinator.data + door_with_statuses = self._api.async_get_door_statuses_from_info(data) + return door_with_statuses[self._door_id] + @property def device_info(self) -> DeviceInfo: """Device info for the controller.""" @@ -108,6 +114,11 @@ class GoGoGate2Entity(CoordinatorEntity): sw_version=data.firmwareversion, ) + @property + def extra_state_attributes(self): + """Return the state attributes.""" + return {"door_id": self._door_id} + def get_data_update_coordinator( hass: HomeAssistant, config_entry: ConfigEntry diff --git a/homeassistant/components/gogogate2/cover.py b/homeassistant/components/gogogate2/cover.py index fb5871e8636..16191304bb9 100644 --- a/homeassistant/components/gogogate2/cover.py +++ b/homeassistant/components/gogogate2/cover.py @@ -55,64 +55,42 @@ class DeviceCover(GoGoGate2Entity, CoverEntity): """Initialize the object.""" unique_id = cover_unique_id(config_entry, door) super().__init__(config_entry, data_update_coordinator, door, unique_id) - self._api = data_update_coordinator.api - self._is_available = True + self._attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE + self._attr_device_class = ( + DEVICE_CLASS_GATE if self.door.gate else DEVICE_CLASS_GARAGE + ) @property def name(self): """Return the name of the door.""" - return self._get_door().name + return self.door.name @property def is_closed(self): """Return true if cover is closed, else False.""" - door_status = self._get_door_status() + door_status = self.door_status if door_status == DoorStatus.OPENED: return False if door_status == DoorStatus.CLOSED: return True - return None - @property - def device_class(self): - """Return the class of this device, from component DEVICE_CLASSES.""" - if self._get_door().gate: - return DEVICE_CLASS_GATE - - return DEVICE_CLASS_GARAGE - - @property - def supported_features(self): - """Flag supported features.""" - return SUPPORT_OPEN | SUPPORT_CLOSE - @property def is_closing(self): """Return if the cover is closing or not.""" - return self._get_door_status() == TransitionDoorStatus.CLOSING + return self.door_status == TransitionDoorStatus.CLOSING @property def is_opening(self): """Return if the cover is opening or not.""" - return self._get_door_status() == TransitionDoorStatus.OPENING + return self.door_status == TransitionDoorStatus.OPENING async def async_open_cover(self, **kwargs): """Open the door.""" - await self._api.async_open_door(self._get_door().door_id) + await self._api.async_open_door(self._door_id) await self.coordinator.async_refresh() async def async_close_cover(self, **kwargs): """Close the door.""" - await self._api.async_close_door(self._get_door().door_id) + await self._api.async_close_door(self._door_id) await self.coordinator.async_refresh() - - @property - def extra_state_attributes(self): - """Return the state attributes.""" - return {"door_id": self._get_door().door_id} - - def _get_door_status(self) -> AbstractDoor: - return self._api.async_get_door_statuses_from_info(self.coordinator.data)[ - self._door.door_id - ] diff --git a/homeassistant/components/gogogate2/sensor.py b/homeassistant/components/gogogate2/sensor.py index 6eb3d823c22..9721f9b8722 100644 --- a/homeassistant/components/gogogate2/sensor.py +++ b/homeassistant/components/gogogate2/sensor.py @@ -49,7 +49,20 @@ async def async_setup_entry( async_add_entities(sensors) -class DoorSensorBattery(GoGoGate2Entity, SensorEntity): +class DoorSensorEntity(GoGoGate2Entity, SensorEntity): + """Base class for door sensor entities.""" + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + attrs = super().extra_state_attributes + door = self.door + if door.sensorid is not None: + attrs["sensor_id"] = door.sensorid + return attrs + + +class DoorSensorBattery(DoorSensorEntity): """Battery sensor entity for gogogate2 door sensor.""" _attr_entity_category = ENTITY_CATEGORY_DIAGNOSTIC @@ -63,38 +76,21 @@ class DoorSensorBattery(GoGoGate2Entity, SensorEntity): """Initialize the object.""" unique_id = sensor_unique_id(config_entry, door, "battery") super().__init__(config_entry, data_update_coordinator, door, unique_id) + self._attr_device_class = DEVICE_CLASS_BATTERY + self._attr_state_class = STATE_CLASS_MEASUREMENT @property def name(self): """Return the name of the door.""" - return f"{self._get_door().name} battery" - - @property - def device_class(self): - """Return the class of this device, from component DEVICE_CLASSES.""" - return DEVICE_CLASS_BATTERY + return f"{self.door.name} battery" @property def native_value(self): """Return the state of the entity.""" - door = self._get_door() - return door.voltage # This is a percentage, not an absolute voltage - - @property - def state_class(self) -> str: - """Return the Measurement State Class.""" - return STATE_CLASS_MEASUREMENT - - @property - def extra_state_attributes(self): - """Return the state attributes.""" - door = self._get_door() - if door.sensorid is not None: - return {"door_id": door.door_id, "sensor_id": door.sensorid} - return None + return self.door.voltage # This is a percentage, not an absolute voltage -class DoorSensorTemperature(GoGoGate2Entity, SensorEntity): +class DoorSensorTemperature(DoorSensorEntity): """Temperature sensor entity for gogogate2 door sensor.""" def __init__( @@ -106,37 +102,16 @@ class DoorSensorTemperature(GoGoGate2Entity, SensorEntity): """Initialize the object.""" unique_id = sensor_unique_id(config_entry, door, "temperature") super().__init__(config_entry, data_update_coordinator, door, unique_id) + self._attr_device_class = DEVICE_CLASS_TEMPERATURE + self._attr_state_class = STATE_CLASS_MEASUREMENT + self._attr_native_unit_of_measurement = TEMP_CELSIUS @property def name(self): """Return the name of the door.""" - return f"{self._get_door().name} temperature" - - @property - def state_class(self) -> str: - """Return the Measurement State Class.""" - return STATE_CLASS_MEASUREMENT - - @property - def device_class(self): - """Return the class of this device, from component DEVICE_CLASSES.""" - return DEVICE_CLASS_TEMPERATURE + return f"{self.door.name} temperature" @property def native_value(self): """Return the state of the entity.""" - door = self._get_door() - return door.temperature - - @property - def native_unit_of_measurement(self): - """Return the unit_of_measurement.""" - return TEMP_CELSIUS - - @property - def extra_state_attributes(self): - """Return the state attributes.""" - door = self._get_door() - if door.sensorid is not None: - return {"door_id": door.door_id, "sensor_id": door.sensorid} - return None + return self.door.temperature