Skip to content

Commit

Permalink
Add number platform to powerview to control velocity on gen 3 hubs (h…
Browse files Browse the repository at this point in the history
…ome-assistant#110724)

Co-authored-by: J. Nick Koston <nick@koston.org>
  • Loading branch information
kingy444 and bdraco authored Feb 17, 2024
1 parent 4aafe14 commit 6e2f64f
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 0 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ omit =
homeassistant/components/hunterdouglas_powerview/coordinator.py
homeassistant/components/hunterdouglas_powerview/cover.py
homeassistant/components/hunterdouglas_powerview/entity.py
homeassistant/components/hunterdouglas_powerview/number.py
homeassistant/components/hunterdouglas_powerview/select.py
homeassistant/components/hunterdouglas_powerview/sensor.py
homeassistant/components/hunterdouglas_powerview/shade_data.py
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
PLATFORMS = [
Platform.BUTTON,
Platform.COVER,
Platform.NUMBER,
Platform.SCENE,
Platform.SELECT,
Platform.SENSOR,
Expand Down
116 changes: 116 additions & 0 deletions homeassistant/components/hunterdouglas_powerview/number.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
"""Support for hunterdouglas_powerview numbers."""

from collections.abc import Callable
from dataclasses import dataclass
import logging
from typing import Final

from aiopvapi.helpers.constants import ATTR_NAME, MOTION_VELOCITY
from aiopvapi.resources.shade import BaseShade, ShadePosition

from homeassistant.components.number import (
NumberEntityDescription,
NumberMode,
RestoreNumber,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import DOMAIN
from .coordinator import PowerviewShadeUpdateCoordinator
from .entity import ShadeEntity
from .model import PowerviewDeviceInfo, PowerviewEntryData

_LOGGER = logging.getLogger(__name__)


@dataclass(frozen=True, kw_only=True)
class PowerviewNumberDescription(NumberEntityDescription):
"""Class to describe a Number entity."""

create_entity_fn: Callable[[BaseShade], bool]
store_value_fn: Callable[[PowerviewShadeUpdateCoordinator, int, float | None], None]
entity_category: EntityCategory = EntityCategory.CONFIG


def store_velocity(
coordinator: PowerviewShadeUpdateCoordinator,
shade_id: int,
value: float | None,
) -> None:
"""Store the desired shade velocity in the coordinator."""
coordinator.data.update_shade_velocity(shade_id, ShadePosition(velocity=value))


NUMBERS: Final = (
PowerviewNumberDescription(
key="velocity",
name="Velocity",
mode=NumberMode.SLIDER,
icon="mdi:speedometer",
create_entity_fn=lambda shade: shade.is_supported(MOTION_VELOCITY),
store_value_fn=store_velocity,
),
)


async def async_setup_entry(
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
) -> None:
"""Set up the hunter douglas number entities."""

pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]

entities: list[PowerViewNumber] = []
for shade in pv_entry.shade_data.values():
room_name = getattr(pv_entry.room_data.get(shade.room_id), ATTR_NAME, "")
for description in NUMBERS:
if description.create_entity_fn(shade):
entities.append(
PowerViewNumber(
pv_entry.coordinator,
pv_entry.device_info,
room_name,
shade,
shade.name,
description,
)
)

async_add_entities(entities)


class PowerViewNumber(ShadeEntity, RestoreNumber):
"""Representation of a number entity."""

entity_description: PowerviewNumberDescription

def __init__(
self,
coordinator: PowerviewShadeUpdateCoordinator,
device_info: PowerviewDeviceInfo,
room_name: str,
shade: BaseShade,
name: str,
description: PowerviewNumberDescription,
) -> None:
"""Initialize the number entity."""
super().__init__(coordinator, device_info, room_name, shade, name)
self.entity_description = description
self._attr_unique_id = f"{self._attr_unique_id}_{description.key}"

def set_native_value(self, value: float) -> None:
"""Update the current value."""
self._attr_native_value = value
self.entity_description.store_value_fn(self.coordinator, self._shade.id, value)
self.async_write_ha_state()

async def async_added_to_hass(self) -> None:
"""Restore last state."""
await super().async_added_to_hass()
last_number_data = await self.async_get_last_number_data()
value = last_number_data.native_value if last_number_data is not None else 0
self._attr_native_value = value
self.entity_description.store_value_fn(self.coordinator, self._shade.id, value)

0 comments on commit 6e2f64f

Please sign in to comment.