parent
f285b6099a
commit
a816348616
|
@ -512,6 +512,7 @@ omit =
|
|||
homeassistant/components/hunterdouglas_powerview/cover.py
|
||||
homeassistant/components/hunterdouglas_powerview/diagnostics.py
|
||||
homeassistant/components/hunterdouglas_powerview/entity.py
|
||||
homeassistant/components/hunterdouglas_powerview/model.py
|
||||
homeassistant/components/hunterdouglas_powerview/scene.py
|
||||
homeassistant/components/hunterdouglas_powerview/sensor.py
|
||||
homeassistant/components/hunterdouglas_powerview/shade_data.py
|
||||
|
|
|
@ -19,29 +19,14 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from .const import (
|
||||
API_PATH_FWVERSION,
|
||||
COORDINATOR,
|
||||
DEFAULT_LEGACY_MAINPROCESSOR,
|
||||
DEVICE_FIRMWARE,
|
||||
DEVICE_INFO,
|
||||
DEVICE_MAC_ADDRESS,
|
||||
DEVICE_MODEL,
|
||||
DEVICE_NAME,
|
||||
DEVICE_REVISION,
|
||||
DEVICE_SERIAL_NUMBER,
|
||||
DOMAIN,
|
||||
FIRMWARE,
|
||||
FIRMWARE_MAINPROCESSOR,
|
||||
FIRMWARE_NAME,
|
||||
FIRMWARE_REVISION,
|
||||
HUB_EXCEPTIONS,
|
||||
HUB_NAME,
|
||||
MAC_ADDRESS_IN_USERDATA,
|
||||
PV_API,
|
||||
PV_HUB_ADDRESS,
|
||||
PV_ROOM_DATA,
|
||||
PV_SCENE_DATA,
|
||||
PV_SHADE_DATA,
|
||||
PV_SHADES,
|
||||
ROOM_DATA,
|
||||
SCENE_DATA,
|
||||
SERIAL_NUMBER_IN_USERDATA,
|
||||
|
@ -49,6 +34,7 @@ from .const import (
|
|||
USER_DATA,
|
||||
)
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
from .model import PowerviewDeviceInfo, PowerviewEntryData
|
||||
from .shade_data import PowerviewShadeData
|
||||
from .util import async_map_data_by_id
|
||||
|
||||
|
@ -72,8 +58,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
|
||||
try:
|
||||
async with async_timeout.timeout(10):
|
||||
device_info = await async_get_device_info(pv_request)
|
||||
device_info[PV_HUB_ADDRESS] = hub_address
|
||||
device_info = await async_get_device_info(pv_request, hub_address)
|
||||
|
||||
async with async_timeout.timeout(10):
|
||||
rooms = Rooms(pv_request)
|
||||
|
@ -102,22 +87,23 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||
# populate raw shade data into the coordinator for diagnostics
|
||||
coordinator.data.store_group_data(shade_entries[SHADE_DATA])
|
||||
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = {
|
||||
PV_API: pv_request,
|
||||
PV_ROOM_DATA: room_data,
|
||||
PV_SCENE_DATA: scene_data,
|
||||
PV_SHADES: shades,
|
||||
PV_SHADE_DATA: shade_data,
|
||||
COORDINATOR: coordinator,
|
||||
DEVICE_INFO: device_info,
|
||||
}
|
||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = PowerviewEntryData(
|
||||
api=pv_request,
|
||||
room_data=room_data,
|
||||
scene_data=scene_data,
|
||||
shade_data=shade_data,
|
||||
coordinator=coordinator,
|
||||
device_info=device_info,
|
||||
)
|
||||
|
||||
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_get_device_info(pv_request):
|
||||
async def async_get_device_info(
|
||||
pv_request: AioRequest, hub_address: str
|
||||
) -> PowerviewDeviceInfo:
|
||||
"""Determine device info."""
|
||||
userdata = UserData(pv_request)
|
||||
resources = await userdata.get_resources()
|
||||
|
@ -135,14 +121,14 @@ async def async_get_device_info(pv_request):
|
|||
else:
|
||||
main_processor_info = DEFAULT_LEGACY_MAINPROCESSOR
|
||||
|
||||
return {
|
||||
DEVICE_NAME: base64_to_unicode(userdata_data[HUB_NAME]),
|
||||
DEVICE_MAC_ADDRESS: userdata_data[MAC_ADDRESS_IN_USERDATA],
|
||||
DEVICE_SERIAL_NUMBER: userdata_data[SERIAL_NUMBER_IN_USERDATA],
|
||||
DEVICE_REVISION: main_processor_info[FIRMWARE_REVISION],
|
||||
DEVICE_FIRMWARE: main_processor_info,
|
||||
DEVICE_MODEL: main_processor_info[FIRMWARE_NAME],
|
||||
}
|
||||
return PowerviewDeviceInfo(
|
||||
name=base64_to_unicode(userdata_data[HUB_NAME]),
|
||||
mac_address=userdata_data[MAC_ADDRESS_IN_USERDATA],
|
||||
serial_number=userdata_data[SERIAL_NUMBER_IN_USERDATA],
|
||||
firmware=main_processor_info,
|
||||
model=main_processor_info[FIRMWARE_NAME],
|
||||
hub_address=hub_address,
|
||||
)
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
|
|
|
@ -13,18 +13,10 @@ from homeassistant.core import HomeAssistant
|
|||
from homeassistant.helpers.entity import EntityCategory
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import (
|
||||
COORDINATOR,
|
||||
DEVICE_INFO,
|
||||
DOMAIN,
|
||||
PV_API,
|
||||
PV_ROOM_DATA,
|
||||
PV_SHADE_DATA,
|
||||
ROOM_ID_IN_SHADE,
|
||||
ROOM_NAME_UNICODE,
|
||||
)
|
||||
from .const import DOMAIN, ROOM_ID_IN_SHADE, ROOM_NAME_UNICODE
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
from .entity import ShadeEntity
|
||||
from .model import PowerviewDeviceInfo, PowerviewEntryData
|
||||
|
||||
|
||||
@dataclass
|
||||
|
@ -66,25 +58,20 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Set up the hunter douglas advanced feature buttons."""
|
||||
|
||||
pv_data = hass.data[DOMAIN][entry.entry_id]
|
||||
room_data: dict[str | int, Any] = pv_data[PV_ROOM_DATA]
|
||||
shade_data = pv_data[PV_SHADE_DATA]
|
||||
pv_request = pv_data[PV_API]
|
||||
coordinator: PowerviewShadeUpdateCoordinator = pv_data[COORDINATOR]
|
||||
device_info: dict[str, Any] = pv_data[DEVICE_INFO]
|
||||
pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
entities: list[ButtonEntity] = []
|
||||
for raw_shade in shade_data.values():
|
||||
shade: BaseShade = PvShade(raw_shade, pv_request)
|
||||
for raw_shade in pv_entry.shade_data.values():
|
||||
shade: BaseShade = PvShade(raw_shade, pv_entry.api)
|
||||
name_before_refresh = shade.name
|
||||
room_id = shade.raw_data.get(ROOM_ID_IN_SHADE)
|
||||
room_name = room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
room_name = pv_entry.room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
|
||||
for description in BUTTONS:
|
||||
entities.append(
|
||||
PowerviewButton(
|
||||
coordinator,
|
||||
device_info,
|
||||
pv_entry.coordinator,
|
||||
pv_entry.device_info,
|
||||
room_name,
|
||||
shade,
|
||||
name_before_refresh,
|
||||
|
@ -101,7 +88,7 @@ class PowerviewButton(ShadeEntity, ButtonEntity):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
|
|
@ -14,7 +14,7 @@ from homeassistant.data_entry_flow import FlowResult
|
|||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from . import async_get_device_info
|
||||
from .const import DEVICE_NAME, DEVICE_SERIAL_NUMBER, DOMAIN, HUB_EXCEPTIONS
|
||||
from .const import DOMAIN, HUB_EXCEPTIONS
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -35,14 +35,14 @@ async def validate_input(hass: core.HomeAssistant, hub_address: str) -> dict[str
|
|||
|
||||
try:
|
||||
async with async_timeout.timeout(10):
|
||||
device_info = await async_get_device_info(pv_request)
|
||||
device_info = await async_get_device_info(pv_request, hub_address)
|
||||
except HUB_EXCEPTIONS as err:
|
||||
raise CannotConnect from err
|
||||
|
||||
# Return info that you want to store in the config entry.
|
||||
return {
|
||||
"title": device_info[DEVICE_NAME],
|
||||
"unique_id": device_info[DEVICE_SERIAL_NUMBER],
|
||||
"title": device_info.name,
|
||||
"unique_id": device_info.serial_number,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,13 +27,9 @@ FIRMWARE_REVISION = "revision"
|
|||
FIRMWARE_SUB_REVISION = "subRevision"
|
||||
FIRMWARE_BUILD = "build"
|
||||
|
||||
DEVICE_NAME = "device_name"
|
||||
DEVICE_MAC_ADDRESS = "device_mac_address"
|
||||
DEVICE_SERIAL_NUMBER = "device_serial_number"
|
||||
DEVICE_REVISION = "device_revision"
|
||||
DEVICE_INFO = "device_info"
|
||||
DEVICE_MODEL = "device_model"
|
||||
DEVICE_FIRMWARE = "device_firmware"
|
||||
REDACT_MAC_ADDRESS = "mac_address"
|
||||
REDACT_SERIAL_NUMBER = "serial_number"
|
||||
REDACT_HUB_ADDRESS = "hub_address"
|
||||
|
||||
SCENE_NAME = "name"
|
||||
SCENE_ID = "id"
|
||||
|
@ -52,15 +48,6 @@ SHADE_BATTERY_LEVEL_MAX = 200
|
|||
|
||||
STATE_ATTRIBUTE_ROOM_NAME = "roomName"
|
||||
|
||||
PV_API = "pv_api"
|
||||
PV_HUB = "pv_hub"
|
||||
PV_HUB_ADDRESS = "pv_hub_address"
|
||||
PV_SHADES = "pv_shades"
|
||||
PV_SCENE_DATA = "pv_scene_data"
|
||||
PV_SHADE_DATA = "pv_shade_data"
|
||||
PV_ROOM_DATA = "pv_room_data"
|
||||
COORDINATOR = "coordinator"
|
||||
|
||||
HUB_EXCEPTIONS = (
|
||||
ServerDisconnectedError,
|
||||
asyncio.TimeoutError,
|
||||
|
|
|
@ -38,23 +38,18 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from .const import (
|
||||
COORDINATOR,
|
||||
DEVICE_INFO,
|
||||
DEVICE_MODEL,
|
||||
DOMAIN,
|
||||
LEGACY_DEVICE_MODEL,
|
||||
POS_KIND_PRIMARY,
|
||||
POS_KIND_SECONDARY,
|
||||
POS_KIND_VANE,
|
||||
PV_API,
|
||||
PV_ROOM_DATA,
|
||||
PV_SHADE_DATA,
|
||||
ROOM_ID_IN_SHADE,
|
||||
ROOM_NAME_UNICODE,
|
||||
STATE_ATTRIBUTE_ROOM_NAME,
|
||||
)
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
from .entity import ShadeEntity
|
||||
from .model import PowerviewDeviceInfo, PowerviewEntryData
|
||||
from .shade_data import PowerviewShadeMove
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
@ -83,18 +78,14 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Set up the hunter douglas shades."""
|
||||
|
||||
pv_data = hass.data[DOMAIN][entry.entry_id]
|
||||
room_data: dict[str | int, Any] = pv_data[PV_ROOM_DATA]
|
||||
shade_data = pv_data[PV_SHADE_DATA]
|
||||
pv_request = pv_data[PV_API]
|
||||
coordinator: PowerviewShadeUpdateCoordinator = pv_data[COORDINATOR]
|
||||
device_info: dict[str, Any] = pv_data[DEVICE_INFO]
|
||||
pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]
|
||||
coordinator: PowerviewShadeUpdateCoordinator = pv_entry.coordinator
|
||||
|
||||
entities: list[ShadeEntity] = []
|
||||
for raw_shade in shade_data.values():
|
||||
for raw_shade in pv_entry.shade_data.values():
|
||||
# The shade may be out of sync with the hub
|
||||
# so we force a refresh when we add it if possible
|
||||
shade: BaseShade = PvShade(raw_shade, pv_request)
|
||||
shade: BaseShade = PvShade(raw_shade, pv_entry.api)
|
||||
name_before_refresh = shade.name
|
||||
with suppress(asyncio.TimeoutError):
|
||||
async with async_timeout.timeout(1):
|
||||
|
@ -108,10 +99,10 @@ async def async_setup_entry(
|
|||
continue
|
||||
coordinator.data.update_shade_positions(shade.raw_data)
|
||||
room_id = shade.raw_data.get(ROOM_ID_IN_SHADE)
|
||||
room_name = room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
room_name = pv_entry.room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
entities.extend(
|
||||
create_powerview_shade_entity(
|
||||
coordinator, device_info, room_name, shade, name_before_refresh
|
||||
coordinator, pv_entry.device_info, room_name, shade, name_before_refresh
|
||||
)
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
@ -119,7 +110,7 @@ async def async_setup_entry(
|
|||
|
||||
def create_powerview_shade_entity(
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name_before_refresh: str,
|
||||
|
@ -161,7 +152,7 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
@ -171,7 +162,7 @@ class PowerViewShadeBase(ShadeEntity, CoverEntity):
|
|||
self._shade: BaseShade = shade
|
||||
self._attr_name = self._shade_name
|
||||
self._scheduled_transition_update: CALLBACK_TYPE | None = None
|
||||
if self._device_info[DEVICE_MODEL] != LEGACY_DEVICE_MODEL:
|
||||
if self._device_info.model != LEGACY_DEVICE_MODEL:
|
||||
self._attr_supported_features |= CoverEntityFeature.STOP
|
||||
self._forced_resync = None
|
||||
|
||||
|
@ -387,7 +378,7 @@ class PowerViewShade(PowerViewShadeBase):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
@ -418,7 +409,7 @@ class PowerViewShadeTDBUBottom(PowerViewShadeTDBU):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
@ -455,7 +446,7 @@ class PowerViewShadeTDBUTop(PowerViewShadeTDBU):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
@ -514,7 +505,7 @@ class PowerViewShadeWithTilt(PowerViewShade):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
name: str,
|
||||
|
@ -526,7 +517,7 @@ class PowerViewShadeWithTilt(PowerViewShade):
|
|||
| CoverEntityFeature.CLOSE_TILT
|
||||
| CoverEntityFeature.SET_TILT_POSITION
|
||||
)
|
||||
if self._device_info[DEVICE_MODEL] != LEGACY_DEVICE_MODEL:
|
||||
if self._device_info.model != LEGACY_DEVICE_MODEL:
|
||||
self._attr_supported_features |= CoverEntityFeature.STOP_TILT
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
"""Diagnostics support for Powerview Hunter Douglas."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import asdict
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import attr
|
||||
|
@ -12,24 +14,19 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.device_registry import DeviceEntry
|
||||
|
||||
from .const import (
|
||||
COORDINATOR,
|
||||
DEVICE_INFO,
|
||||
DEVICE_MAC_ADDRESS,
|
||||
DEVICE_SERIAL_NUMBER,
|
||||
DOMAIN,
|
||||
PV_HUB_ADDRESS,
|
||||
)
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
from .const import DOMAIN, REDACT_HUB_ADDRESS, REDACT_MAC_ADDRESS, REDACT_SERIAL_NUMBER
|
||||
from .model import PowerviewEntryData
|
||||
|
||||
REDACT_CONFIG = {
|
||||
CONF_HOST,
|
||||
DEVICE_MAC_ADDRESS,
|
||||
DEVICE_SERIAL_NUMBER,
|
||||
PV_HUB_ADDRESS,
|
||||
REDACT_HUB_ADDRESS,
|
||||
REDACT_MAC_ADDRESS,
|
||||
REDACT_SERIAL_NUMBER,
|
||||
ATTR_CONFIGURATION_URL,
|
||||
}
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, entry: ConfigEntry
|
||||
|
@ -70,10 +67,9 @@ def _async_get_diagnostics(
|
|||
entry: ConfigEntry,
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
pv_data = hass.data[DOMAIN][entry.entry_id]
|
||||
coordinator: PowerviewShadeUpdateCoordinator = pv_data[COORDINATOR]
|
||||
shade_data = coordinator.data.get_all_raw_data()
|
||||
hub_info = async_redact_data(pv_data[DEVICE_INFO], REDACT_CONFIG)
|
||||
pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]
|
||||
shade_data = pv_entry.coordinator.data.get_all_raw_data()
|
||||
hub_info = async_redact_data(asdict(pv_entry.device_info), REDACT_CONFIG)
|
||||
return {"hub_info": hub_info, "shade_data": shade_data}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
"""The powerview integration base entity."""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from aiopvapi.resources.shade import ATTR_TYPE, BaseShade
|
||||
|
||||
from homeassistant.const import ATTR_MODEL, ATTR_SW_VERSION
|
||||
|
@ -12,20 +10,15 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
|||
from .const import (
|
||||
ATTR_BATTERY_KIND,
|
||||
BATTERY_KIND_HARDWIRED,
|
||||
DEVICE_FIRMWARE,
|
||||
DEVICE_MAC_ADDRESS,
|
||||
DEVICE_MODEL,
|
||||
DEVICE_NAME,
|
||||
DEVICE_SERIAL_NUMBER,
|
||||
DOMAIN,
|
||||
FIRMWARE,
|
||||
FIRMWARE_BUILD,
|
||||
FIRMWARE_REVISION,
|
||||
FIRMWARE_SUB_REVISION,
|
||||
MANUFACTURER,
|
||||
PV_HUB_ADDRESS,
|
||||
)
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
from .model import PowerviewDeviceInfo
|
||||
from .shade_data import PowerviewShadeData, PowerviewShadePositions
|
||||
|
||||
|
||||
|
@ -35,7 +28,7 @@ class HDEntity(CoordinatorEntity[PowerviewShadeUpdateCoordinator]):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
unique_id: str,
|
||||
) -> None:
|
||||
|
@ -43,7 +36,6 @@ class HDEntity(CoordinatorEntity[PowerviewShadeUpdateCoordinator]):
|
|||
super().__init__(coordinator)
|
||||
self._room_name = room_name
|
||||
self._attr_unique_id = unique_id
|
||||
self._hub_address = device_info[PV_HUB_ADDRESS]
|
||||
self._device_info = device_info
|
||||
|
||||
@property
|
||||
|
@ -54,19 +46,17 @@ class HDEntity(CoordinatorEntity[PowerviewShadeUpdateCoordinator]):
|
|||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return the device_info of the device."""
|
||||
firmware = self._device_info[DEVICE_FIRMWARE]
|
||||
firmware = self._device_info.firmware
|
||||
sw_version = f"{firmware[FIRMWARE_REVISION]}.{firmware[FIRMWARE_SUB_REVISION]}.{firmware[FIRMWARE_BUILD]}"
|
||||
return DeviceInfo(
|
||||
connections={
|
||||
(dr.CONNECTION_NETWORK_MAC, self._device_info[DEVICE_MAC_ADDRESS])
|
||||
},
|
||||
identifiers={(DOMAIN, self._device_info[DEVICE_SERIAL_NUMBER])},
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, self._device_info.mac_address)},
|
||||
identifiers={(DOMAIN, self._device_info.serial_number)},
|
||||
manufacturer=MANUFACTURER,
|
||||
model=self._device_info[DEVICE_MODEL],
|
||||
name=self._device_info[DEVICE_NAME],
|
||||
model=self._device_info.model,
|
||||
name=self._device_info.name,
|
||||
suggested_area=self._room_name,
|
||||
sw_version=sw_version,
|
||||
configuration_url=f"http://{self._hub_address}/api/shades",
|
||||
configuration_url=f"http://{self._device_info.hub_address}/api/shades",
|
||||
)
|
||||
|
||||
|
||||
|
@ -76,7 +66,7 @@ class ShadeEntity(HDEntity):
|
|||
def __init__(
|
||||
self,
|
||||
coordinator: PowerviewShadeUpdateCoordinator,
|
||||
device_info: dict[str, Any],
|
||||
device_info: PowerviewDeviceInfo,
|
||||
room_name: str,
|
||||
shade: BaseShade,
|
||||
shade_name: str,
|
||||
|
@ -104,8 +94,8 @@ class ShadeEntity(HDEntity):
|
|||
suggested_area=self._room_name,
|
||||
manufacturer=MANUFACTURER,
|
||||
model=str(self._shade.raw_data[ATTR_TYPE]),
|
||||
via_device=(DOMAIN, self._device_info[DEVICE_SERIAL_NUMBER]),
|
||||
configuration_url=f"http://{self._hub_address}/api/shades/{self._shade.id}",
|
||||
via_device=(DOMAIN, self._device_info.serial_number),
|
||||
configuration_url=f"http://{self._device_info.hub_address}/api/shades/{self._shade.id}",
|
||||
)
|
||||
|
||||
for shade in self._shade.shade_types:
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
"""Define Hunter Douglas data models."""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
from aiopvapi.helpers.aiorequest import AioRequest
|
||||
|
||||
from .coordinator import PowerviewShadeUpdateCoordinator
|
||||
|
||||
|
||||
@dataclass
|
||||
class PowerviewEntryData:
|
||||
"""Define class for main domain information."""
|
||||
|
||||
api: AioRequest
|
||||
room_data: dict[str, Any]
|
||||
scene_data: dict[str, Any]
|
||||
shade_data: dict[str, Any]
|
||||
coordinator: PowerviewShadeUpdateCoordinator
|
||||
device_info: PowerviewDeviceInfo
|
||||
|
||||
|
||||
@dataclass
|
||||
class PowerviewDeviceInfo:
|
||||
"""Define class for device information."""
|
||||
|
||||
name: str
|
||||
mac_address: str
|
||||
serial_number: str
|
||||
firmware: dict[str, Any]
|
||||
model: str
|
||||
hub_address: str
|
|
@ -10,17 +10,9 @@ from homeassistant.config_entries import ConfigEntry
|
|||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import (
|
||||
COORDINATOR,
|
||||
DEVICE_INFO,
|
||||
DOMAIN,
|
||||
PV_API,
|
||||
PV_ROOM_DATA,
|
||||
PV_SCENE_DATA,
|
||||
ROOM_NAME_UNICODE,
|
||||
STATE_ATTRIBUTE_ROOM_NAME,
|
||||
)
|
||||
from .const import DOMAIN, ROOM_NAME_UNICODE, STATE_ATTRIBUTE_ROOM_NAME
|
||||
from .entity import HDEntity
|
||||
from .model import PowerviewEntryData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -28,18 +20,15 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Set up powerview scene entries."""
|
||||
|
||||
pv_data = hass.data[DOMAIN][entry.entry_id]
|
||||
room_data = pv_data[PV_ROOM_DATA]
|
||||
scene_data = pv_data[PV_SCENE_DATA]
|
||||
pv_request = pv_data[PV_API]
|
||||
coordinator = pv_data[COORDINATOR]
|
||||
device_info = pv_data[DEVICE_INFO]
|
||||
pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
pvscenes = []
|
||||
for raw_scene in scene_data.values():
|
||||
scene = PvScene(raw_scene, pv_request)
|
||||
room_name = room_data.get(scene.room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
pvscenes.append(PowerViewScene(coordinator, device_info, room_name, scene))
|
||||
for raw_scene in pv_entry.scene_data.values():
|
||||
scene = PvScene(raw_scene, pv_entry.api)
|
||||
room_name = pv_entry.room_data.get(scene.room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
pvscenes.append(
|
||||
PowerViewScene(pv_entry.coordinator, pv_entry.device_info, room_name, scene)
|
||||
)
|
||||
async_add_entities(pvscenes)
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Support for hunterdouglass_powerview sensors."""
|
||||
from aiopvapi.resources.shade import factory as PvShade
|
||||
from aiopvapi.resources.shade import BaseShade, factory as PvShade
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
|
@ -13,18 +13,14 @@ from homeassistant.helpers.entity import EntityCategory
|
|||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import (
|
||||
COORDINATOR,
|
||||
DEVICE_INFO,
|
||||
DOMAIN,
|
||||
PV_API,
|
||||
PV_ROOM_DATA,
|
||||
PV_SHADE_DATA,
|
||||
ROOM_ID_IN_SHADE,
|
||||
ROOM_NAME_UNICODE,
|
||||
SHADE_BATTERY_LEVEL,
|
||||
SHADE_BATTERY_LEVEL_MAX,
|
||||
)
|
||||
from .entity import ShadeEntity
|
||||
from .model import PowerviewEntryData
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
|
@ -32,24 +28,23 @@ async def async_setup_entry(
|
|||
) -> None:
|
||||
"""Set up the hunter douglas shades sensors."""
|
||||
|
||||
pv_data = hass.data[DOMAIN][entry.entry_id]
|
||||
room_data = pv_data[PV_ROOM_DATA]
|
||||
shade_data = pv_data[PV_SHADE_DATA]
|
||||
pv_request = pv_data[PV_API]
|
||||
coordinator = pv_data[COORDINATOR]
|
||||
device_info = pv_data[DEVICE_INFO]
|
||||
pv_entry: PowerviewEntryData = hass.data[DOMAIN][entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for raw_shade in shade_data.values():
|
||||
shade = PvShade(raw_shade, pv_request)
|
||||
for raw_shade in pv_entry.shade_data.values():
|
||||
shade: BaseShade = PvShade(raw_shade, pv_entry.api)
|
||||
if SHADE_BATTERY_LEVEL not in shade.raw_data:
|
||||
continue
|
||||
name_before_refresh = shade.name
|
||||
room_id = shade.raw_data.get(ROOM_ID_IN_SHADE)
|
||||
room_name = room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
room_name = pv_entry.room_data.get(room_id, {}).get(ROOM_NAME_UNICODE, "")
|
||||
entities.append(
|
||||
PowerViewShadeBatterySensor(
|
||||
coordinator, device_info, room_name, shade, name_before_refresh
|
||||
pv_entry.coordinator,
|
||||
pv_entry.device_info,
|
||||
room_name,
|
||||
shade,
|
||||
name_before_refresh,
|
||||
)
|
||||
)
|
||||
async_add_entities(entities)
|
||||
|
|
Loading…
Reference in New Issue