diff --git a/homeassistant/components/hunterdouglas_powerview/button.py b/homeassistant/components/hunterdouglas_powerview/button.py index cb2da3ba8fa..2e0bc1c413a 100644 --- a/homeassistant/components/hunterdouglas_powerview/button.py +++ b/homeassistant/components/hunterdouglas_powerview/button.py @@ -7,7 +7,11 @@ from typing import Any, Final from aiopvapi.resources.shade import BaseShade, factory as PvShade -from homeassistant.components.button import ButtonEntity, ButtonEntityDescription +from homeassistant.components.button import ( + ButtonDeviceClass, + ButtonEntity, + ButtonEntityDescription, +) from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant @@ -36,21 +40,20 @@ class PowerviewButtonDescription( BUTTONS: Final = [ PowerviewButtonDescription( key="calibrate", - name="Calibrate", + translation_key="calibrate", icon="mdi:swap-vertical-circle-outline", entity_category=EntityCategory.DIAGNOSTIC, press_action=lambda shade: shade.calibrate(), ), PowerviewButtonDescription( key="identify", - name="Identify", - icon="mdi:crosshairs-question", + device_class=ButtonDeviceClass.IDENTIFY, entity_category=EntityCategory.DIAGNOSTIC, press_action=lambda shade: shade.jog(), ), PowerviewButtonDescription( key="favorite", - name="Favorite", + translation_key="favorite", icon="mdi:heart", entity_category=EntityCategory.DIAGNOSTIC, press_action=lambda shade: shade.favorite(), @@ -104,7 +107,6 @@ class PowerviewButton(ShadeEntity, ButtonEntity): """Initialize the button entity.""" super().__init__(coordinator, device_info, room_name, shade, name) self.entity_description: PowerviewButtonDescription = description - self._attr_name = f"{self._shade_name} {description.name}" self._attr_unique_id = f"{self._attr_unique_id}_{description.key}" async def async_press(self) -> None: diff --git a/homeassistant/components/hunterdouglas_powerview/cover.py b/homeassistant/components/hunterdouglas_powerview/cover.py index dfb1a7ad967..5cb84658c50 100644 --- a/homeassistant/components/hunterdouglas_powerview/cover.py +++ b/homeassistant/components/hunterdouglas_powerview/cover.py @@ -118,7 +118,11 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity): """Representation of a powerview shade.""" _attr_device_class = CoverDeviceClass.SHADE - _attr_supported_features = CoverEntityFeature(0) + _attr_supported_features = ( + CoverEntityFeature.OPEN + | CoverEntityFeature.CLOSE + | CoverEntityFeature.SET_POSITION + ) def __init__( self, @@ -131,7 +135,6 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._shade: BaseShade = shade - self._attr_name = self._shade_name self._scheduled_transition_update: CALLBACK_TYPE | None = None if self._device_info.model != LEGACY_DEVICE_MODEL: self._attr_supported_features |= CoverEntityFeature.STOP @@ -346,26 +349,14 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity): class PowerViewShade(PowerViewShadeBase): """Represent a standard shade.""" - def __init__( - self, - coordinator: PowerviewShadeUpdateCoordinator, - device_info: PowerviewDeviceInfo, - room_name: str, - shade: BaseShade, - name: str, - ) -> None: - """Initialize the shade.""" - super().__init__(coordinator, device_info, room_name, shade, name) - self._attr_supported_features |= ( - CoverEntityFeature.OPEN - | CoverEntityFeature.CLOSE - | CoverEntityFeature.SET_POSITION - ) + _attr_name = None -class PowerViewShadeWithTiltBase(PowerViewShade): +class PowerViewShadeWithTiltBase(PowerViewShadeBase): """Representation for PowerView shades with tilt capabilities.""" + _attr_name = None + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, @@ -453,9 +444,11 @@ class PowerViewShadeWithTiltOnClosed(PowerViewShadeWithTiltBase): API Class: ShadeBottomUpTiltOnClosed + ShadeBottomUpTiltOnClosed90 Type 1 - Bottom Up w/ 90° Tilt - Shade 44 - a shade thought to have been a firmware issue (type 0 usually dont tilt) + Shade 44 - a shade thought to have been a firmware issue (type 0 usually don't tilt) """ + _attr_name = None + @property def open_position(self) -> PowerviewShadeMove: """Return the open position and required additional positions.""" @@ -570,7 +563,7 @@ class PowerViewShadeTiltOnly(PowerViewShadeWithTiltBase): self._max_tilt = self._shade.shade_limits.tilt_max -class PowerViewShadeTopDown(PowerViewShade): +class PowerViewShadeTopDown(PowerViewShadeBase): """Representation of a shade that lowers from the roof to the floor. These shades are inverted where MAX_POSITION equates to closed and MIN_POSITION is open @@ -579,6 +572,8 @@ class PowerViewShadeTopDown(PowerViewShade): Type 6 - Top Down """ + _attr_name = None + @property def current_cover_position(self) -> int: """Return the current position of cover.""" @@ -594,7 +589,7 @@ class PowerViewShadeTopDown(PowerViewShade): await self._async_set_cover_position(100 - kwargs[ATTR_POSITION]) -class PowerViewShadeDualRailBase(PowerViewShade): +class PowerViewShadeDualRailBase(PowerViewShadeBase): """Representation of a shade with top/down bottom/up capabilities. Base methods shared between the two shades created @@ -613,11 +608,13 @@ class PowerViewShadeDualRailBase(PowerViewShade): class PowerViewShadeTDBUBottom(PowerViewShadeDualRailBase): """Representation of the bottom PowerViewShadeDualRailBase shade. - These shades have top/down bottom up functionality and two entiites. + These shades have top/down bottom up functionality and two entities. Sibling Class: PowerViewShadeTDBUTop API Class: ShadeTopDownBottomUp """ + _attr_translation_key = "bottom" + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, @@ -629,7 +626,6 @@ class PowerViewShadeTDBUBottom(PowerViewShadeDualRailBase): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._attr_unique_id = f"{self._shade.id}_bottom" - self._attr_name = f"{self._shade_name} Bottom" @callback def _clamp_cover_limit(self, target_hass_position: int) -> int: @@ -655,11 +651,13 @@ class PowerViewShadeTDBUBottom(PowerViewShadeDualRailBase): class PowerViewShadeTDBUTop(PowerViewShadeDualRailBase): """Representation of the top PowerViewShadeDualRailBase shade. - These shades have top/down bottom up functionality and two entiites. + These shades have top/down bottom up functionality and two entities. Sibling Class: PowerViewShadeTDBUBottom API Class: ShadeTopDownBottomUp """ + _attr_translation_key = "top" + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, @@ -671,7 +669,6 @@ class PowerViewShadeTDBUTop(PowerViewShadeDualRailBase): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._attr_unique_id = f"{self._shade.id}_top" - self._attr_name = f"{self._shade_name} Top" @property def should_poll(self) -> bool: @@ -711,7 +708,7 @@ class PowerViewShadeTDBUTop(PowerViewShadeDualRailBase): @callback def _clamp_cover_limit(self, target_hass_position: int) -> int: - """Dont allow a cover to go into an impossbile position.""" + """Don't allow a cover to go into an impossbile position.""" cover_bottom = hd_position_to_hass(self.positions.primary, MAX_POSITION) return min(target_hass_position, (100 - cover_bottom)) @@ -730,7 +727,7 @@ class PowerViewShadeTDBUTop(PowerViewShadeDualRailBase): ) -class PowerViewShadeDualOverlappedBase(PowerViewShade): +class PowerViewShadeDualOverlappedBase(PowerViewShadeBase): """Represent a shade that has a front sheer and rear opaque panel. This equates to two shades being controlled by one motor @@ -783,6 +780,8 @@ class PowerViewShadeDualOverlappedCombined(PowerViewShadeDualOverlappedBase): Type 8 - Duolite (front and rear shades) """ + _attr_translation_key = "combined" + # type def __init__( self, @@ -795,7 +794,6 @@ class PowerViewShadeDualOverlappedCombined(PowerViewShadeDualOverlappedBase): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._attr_unique_id = f"{self._shade.id}_combined" - self._attr_name = f"{self._shade_name} Combined" @property def is_closed(self) -> bool: @@ -842,7 +840,7 @@ class PowerViewShadeDualOverlappedCombined(PowerViewShadeDualOverlappedBase): class PowerViewShadeDualOverlappedFront(PowerViewShadeDualOverlappedBase): - """Represent the shade front panel - These have a opaque panel too. + """Represent the shade front panel - These have an opaque panel too. This equates to two shades being controlled by one motor. The front shade must be completely down before the rear shade will move. @@ -857,6 +855,8 @@ class PowerViewShadeDualOverlappedFront(PowerViewShadeDualOverlappedBase): Type 10 - Duolite with 180° Tilt """ + _attr_translation_key = "front" + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, @@ -868,7 +868,6 @@ class PowerViewShadeDualOverlappedFront(PowerViewShadeDualOverlappedBase): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._attr_unique_id = f"{self._shade.id}_front" - self._attr_name = f"{self._shade_name} Front" @property def should_poll(self) -> bool: @@ -906,7 +905,7 @@ class PowerViewShadeDualOverlappedFront(PowerViewShadeDualOverlappedBase): class PowerViewShadeDualOverlappedRear(PowerViewShadeDualOverlappedBase): - """Represent the shade front panel - These have a opaque panel too. + """Represent the shade front panel - These have an opaque panel too. This equates to two shades being controlled by one motor. The front shade must be completely down before the rear shade will move. @@ -921,6 +920,8 @@ class PowerViewShadeDualOverlappedRear(PowerViewShadeDualOverlappedBase): Type 10 - Duolite with 180° Tilt """ + _attr_translation_key = "rear" + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, @@ -932,7 +933,6 @@ class PowerViewShadeDualOverlappedRear(PowerViewShadeDualOverlappedBase): """Initialize the shade.""" super().__init__(coordinator, device_info, room_name, shade, name) self._attr_unique_id = f"{self._shade.id}_rear" - self._attr_name = f"{self._shade_name} Rear" @property def should_poll(self) -> bool: diff --git a/homeassistant/components/hunterdouglas_powerview/entity.py b/homeassistant/components/hunterdouglas_powerview/entity.py index 08f3c749fc5..78f63e16879 100644 --- a/homeassistant/components/hunterdouglas_powerview/entity.py +++ b/homeassistant/components/hunterdouglas_powerview/entity.py @@ -25,6 +25,8 @@ from .shade_data import PowerviewShadeData, PowerviewShadePositions class HDEntity(CoordinatorEntity[PowerviewShadeUpdateCoordinator]): """Base class for hunter douglas entities.""" + _attr_has_entity_name = True + def __init__( self, coordinator: PowerviewShadeUpdateCoordinator, diff --git a/homeassistant/components/hunterdouglas_powerview/select.py b/homeassistant/components/hunterdouglas_powerview/select.py index 7de7d3e8735..37d1193e0e5 100644 --- a/homeassistant/components/hunterdouglas_powerview/select.py +++ b/homeassistant/components/hunterdouglas_powerview/select.py @@ -47,7 +47,7 @@ class PowerviewSelectDescription( DROPDOWNS: Final = [ PowerviewSelectDescription( key="powersource", - name="Power Source", + translation_key="power_source", icon="mdi:power-plug-outline", current_fn=lambda shade: POWER_SUPPLY_TYPE_MAP.get( shade.raw_data.get(ATTR_BATTERY_KIND), None @@ -106,7 +106,6 @@ class PowerViewSelect(ShadeEntity, SelectEntity): """Initialize the select entity.""" super().__init__(coordinator, device_info, room_name, shade, name) self.entity_description: PowerviewSelectDescription = description - self._attr_name = f"{self._shade_name} {description.name}" self._attr_unique_id = f"{self._attr_unique_id}_{description.key}" @property diff --git a/homeassistant/components/hunterdouglas_powerview/sensor.py b/homeassistant/components/hunterdouglas_powerview/sensor.py index b36457324e1..825ca140f14 100644 --- a/homeassistant/components/hunterdouglas_powerview/sensor.py +++ b/homeassistant/components/hunterdouglas_powerview/sensor.py @@ -55,7 +55,6 @@ class PowerviewSensorDescription( SENSORS: Final = [ PowerviewSensorDescription( key="charge", - name="Battery", device_class=SensorDeviceClass.BATTERY, native_unit_of_measurement=PERCENTAGE, native_value_fn=lambda shade: round( @@ -69,7 +68,7 @@ SENSORS: Final = [ ), PowerviewSensorDescription( key="signal", - name="Signal", + translation_key="signal_strength", icon="mdi:signal", native_unit_of_measurement=PERCENTAGE, native_value_fn=lambda shade: round( @@ -129,7 +128,6 @@ class PowerViewSensor(ShadeEntity, SensorEntity): """Initialize the select entity.""" super().__init__(coordinator, device_info, room_name, shade, name) self.entity_description = description - self._attr_name = f"{self._shade_name} {description.name}" self._attr_unique_id = f"{self._attr_unique_id}_{description.key}" self._attr_native_unit_of_measurement = description.native_unit_of_measurement diff --git a/homeassistant/components/hunterdouglas_powerview/strings.json b/homeassistant/components/hunterdouglas_powerview/strings.json index ec26e423e06..7c17788be83 100644 --- a/homeassistant/components/hunterdouglas_powerview/strings.json +++ b/homeassistant/components/hunterdouglas_powerview/strings.json @@ -20,5 +20,42 @@ "abort": { "already_configured": "[%key:common::config_flow::abort::already_configured_device%]" } + }, + "entity": { + "button": { + "calibrate": { + "name": "Calibrate" + }, + "favorite": { + "name": "Favorite" + } + }, + "cover": { + "bottom": { + "name": "Bottom" + }, + "top": { + "name": "Top" + }, + "combined": { + "name": "Combined" + }, + "front": { + "name": "Front" + }, + "rear": { + "name": "Rear" + } + }, + "select": { + "power_source": { + "name": "Power source" + } + }, + "sensor": { + "signal_strength": { + "name": "[%key:component::sensor::entity_component::signal_strength::name%]" + } + } } }