Address feedback to Overkiz integration (round 2) (#63036)

* Address feedback in multiple files

* Add missing return statement

* Improve sensor descriptions

* Improve typing

* Move to new device registry

* Disable RSSI sensor by default

* Improve typing
pull/63078/head
Mick Vleeshouwer 2021-12-30 06:22:35 -08:00 committed by GitHub
parent 52ca06c750
commit 8599ddf51e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 30 additions and 33 deletions

View File

@ -41,7 +41,7 @@ class HomeAssistantOverkizData:
"""Overkiz data stored in the Home Assistant data object."""
coordinator: OverkizDataUpdateCoordinator
platforms: dict[Platform, Device | Scenario]
platforms: defaultdict[Platform, list[Device | Scenario]]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
@ -74,9 +74,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
raise ConfigEntryNotReady("Failed to connect") from exception
except MaintenanceException as exception:
raise ConfigEntryNotReady("Server is down for maintenance") from exception
except Exception as exception: # pylint: disable=broad-except
_LOGGER.exception(exception)
return False
coordinator = OverkizDataUpdateCoordinator(
hass,
@ -98,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
)
coordinator.update_interval = UPDATE_INTERVAL_ALL_ASSUMED_STATE
platforms: dict[Platform, Device | Scenario] = defaultdict(list)
platforms: defaultdict[Platform, list[Device | Scenario]] = defaultdict(list)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = HomeAssistantOverkizData(
coordinator=coordinator,
@ -121,7 +118,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.config_entries.async_setup_platforms(entry, PLATFORMS)
device_registry = await dr.async_get_registry(hass)
device_registry = dr.async_get(hass)
for gateway in setup.gateways:
_LOGGER.debug("Added gateway (%s)", gateway)

View File

@ -46,7 +46,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz button from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[ButtonEntity] = []

View File

@ -19,6 +19,7 @@ from homeassistant import config_entries
from homeassistant.components import dhcp
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from .const import CONF_HUB, DEFAULT_HUB, DOMAIN
@ -35,9 +36,13 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
server = SUPPORTED_SERVERS[user_input[CONF_HUB]]
session = async_get_clientsession(self.hass)
async with OverkizClient(
username=username, password=password, server=server
username=username,
password=password,
server=server,
session=session,
) as client:
await client.login()

View File

@ -19,7 +19,7 @@ from pyoverkiz.exceptions import (
from pyoverkiz.models import DataType, Device, Place, State
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
from .const import DOMAIN, UPDATE_INTERVAL
@ -97,9 +97,6 @@ class OverkizDataUpdateCoordinator(DataUpdateCoordinator):
raise UpdateFailed("Too many requests, try again later.") from exception
return self.devices
except Exception as exception:
_LOGGER.debug(exception)
raise UpdateFailed(exception) from exception
for event in events:
_LOGGER.debug(event)
@ -123,7 +120,7 @@ class OverkizDataUpdateCoordinator(DataUpdateCoordinator):
elif event.name == EventName.DEVICE_REMOVED:
base_device_url, *_ = event.device_url.split("#")
registry = await device_registry.async_get_registry(self.hass)
registry = dr.async_get(self.hass)
if registered_device := registry.async_get_device(
{(DOMAIN, base_device_url)}
@ -176,7 +173,7 @@ class OverkizDataUpdateCoordinator(DataUpdateCoordinator):
cast_to_python = DATA_TYPE_TO_PYTHON[data_type]
return cast_to_python(state.value)
def places_to_area(self, place):
def places_to_area(self, place: Place) -> dict[str, str]:
"""Convert places with sub_places to a flat dictionary."""
areas = {}
if isinstance(place, Place):

View File

@ -74,7 +74,7 @@ class OverkizEntity(CoordinatorEntity):
),
hw_version=self.device.controllable_name,
suggested_area=self.coordinator.areas[self.device.place_oid],
via_device=self.executor.get_gateway_id(),
via_device=(DOMAIN, self.executor.get_gateway_id()),
configuration_url=self.coordinator.client.server.configuration_url,
)

View File

@ -37,7 +37,7 @@ class OverkizExecutor:
"""Return True if a command exists in a list of commands."""
return self.select_command(*commands) is not None
def select_state(self, *states) -> str | None:
def select_state(self, *states: str) -> str | None:
"""Select first existing active state in a list of states."""
for state in states:
if current_state := self.device.states[state]:
@ -49,7 +49,7 @@ class OverkizExecutor:
"""Return True if a state exists in self."""
return self.select_state(*states) is not None
def select_attribute(self, *attributes) -> str | None:
def select_attribute(self, *attributes: str) -> str | None:
"""Select first existing active state in a list of states."""
for attribute in attributes:
if current_attribute := self.device.attributes[attribute]:
@ -57,7 +57,7 @@ class OverkizExecutor:
return None
async def async_execute_command(self, command_name: str, *args: Any):
async def async_execute_command(self, command_name: str, *args: Any) -> None:
"""Execute device command in async context."""
try:
exec_id = await self.coordinator.client.execute_command(
@ -118,11 +118,11 @@ class OverkizExecutor:
return False
async def async_cancel_execution(self, exec_id: str):
async def async_cancel_execution(self, exec_id: str) -> None:
"""Cancel running execution via execution id."""
await self.coordinator.client.cancel_command(exec_id)
def get_gateway_id(self):
def get_gateway_id(self) -> str:
"""
Retrieve gateway id from device url.

View File

@ -28,7 +28,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz lights from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]

View File

@ -20,7 +20,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz locks from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]

View File

@ -54,7 +54,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz number from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[OverkizNumber] = []
@ -89,12 +89,12 @@ class OverkizNumber(OverkizDescriptiveEntity, NumberEntity):
entity_description: OverkizNumberDescription
@property
def value(self) -> float:
def value(self) -> float | None:
"""Return the entity value to represent the entity state."""
if state := self.device.states.get(self.entity_description.key):
return state.value
return 0
return None
async def async_set_value(self, value: float) -> None:
"""Set new value."""

View File

@ -20,7 +20,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz scenes from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]

View File

@ -28,6 +28,7 @@ from homeassistant.const import (
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType
from . import HomeAssistantOverkizData
from .const import DOMAIN, IGNORED_OVERKIZ_DEVICES
@ -54,7 +55,6 @@ SENSOR_DESCRIPTIONS: list[OverkizSensorDescription] = [
OverkizSensorDescription(
key=OverkizState.CORE_BATTERY,
name="Battery",
device_class=SensorDeviceClass.BATTERY,
native_value=lambda value: str(value).capitalize(),
entity_category=EntityCategory.DIAGNOSTIC,
),
@ -66,6 +66,7 @@ SENSOR_DESCRIPTIONS: list[OverkizSensorDescription] = [
state_class=SensorStateClass.MEASUREMENT,
native_value=lambda value: round(float(value)),
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
),
OverkizSensorDescription(
key=OverkizState.CORE_EXPECTED_NUMBER_OF_SHOWER,
@ -126,7 +127,6 @@ SENSOR_DESCRIPTIONS: list[OverkizSensorDescription] = [
OverkizSensorDescription(
key=OverkizState.CORE_FOSSIL_ENERGY_CONSUMPTION,
name="Fossil Energy Consumption",
device_class=SensorDeviceClass.ENERGY,
),
OverkizSensorDescription(
key=OverkizState.CORE_GAS_CONSUMPTION,
@ -292,7 +292,6 @@ SENSOR_DESCRIPTIONS: list[OverkizSensorDescription] = [
key=OverkizState.CORE_SUN_ENERGY,
name="Sun Energy",
native_value=lambda value: round(float(value), 2),
device_class=SensorDeviceClass.ENERGY,
icon="mdi:solar-power",
state_class=SensorStateClass.MEASUREMENT,
),
@ -330,7 +329,6 @@ SENSOR_DESCRIPTIONS: list[OverkizSensorDescription] = [
name="Discrete RSSI Level",
entity_registry_enabled_default=False,
native_value=lambda value: str(value).capitalize(),
device_class=SensorDeviceClass.SIGNAL_STRENGTH,
entity_category=EntityCategory.DIAGNOSTIC,
),
# DomesticHotWaterProduction/WaterHeatingSystem
@ -349,7 +347,7 @@ async def async_setup_entry(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
):
) -> None:
"""Set up the Overkiz sensors from a config entry."""
data: HomeAssistantOverkizData = hass.data[DOMAIN][entry.entry_id]
entities: list[SensorEntity] = []
@ -392,7 +390,7 @@ class OverkizStateSensor(OverkizDescriptiveEntity, SensorEntity):
entity_description: OverkizSensorDescription
@property
def native_value(self):
def native_value(self) -> StateType:
"""Return the value of the sensor."""
state = self.device.states.get(self.entity_description.key)
@ -420,7 +418,7 @@ class OverkizHomeKitSetupCodeSensor(OverkizEntity, SensorEntity):
self._attr_name = "HomeKit Setup Code"
@property
def native_value(self):
def native_value(self) -> str:
"""Return the value of the sensor."""
return self.device.attributes.get(OverkizAttribute.HOMEKIT_SETUP_CODE).value