Reduce bond startup time (#73506)

This commit is contained in:
J. Nick Koston 2022-06-14 20:30:59 -10:00 committed by GitHub
parent c64b108789
commit 1e956bc52f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 54 additions and 46 deletions

View file

@ -287,10 +287,10 @@ class BondButtonEntity(BondEntity, ButtonEntity):
description: BondButtonEntityDescription,
) -> None:
"""Init Bond button."""
self.entity_description = description
super().__init__(
hub, device, bpup_subs, description.name, description.key.lower()
)
self.entity_description = description
async def async_press(self, **kwargs: Any) -> None:
"""Press the button."""
@ -302,5 +302,5 @@ class BondButtonEntity(BondEntity, ButtonEntity):
action = Action(self.entity_description.key)
await self._hub.bond.action(self._device.device_id, action)
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
"""Apply the state."""

View file

@ -13,7 +13,6 @@ from homeassistant.components.cover import (
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import BPUP_SUBS, DOMAIN, HUB
@ -40,14 +39,11 @@ async def async_setup_entry(
data = hass.data[DOMAIN][entry.entry_id]
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
covers: list[Entity] = [
async_add_entities(
BondCover(hub, device, bpup_subs)
for device in hub.devices
if device.type == DeviceType.MOTORIZED_SHADES
]
async_add_entities(covers, True)
)
class BondCover(BondEntity, CoverEntity):
@ -78,7 +74,8 @@ class BondCover(BondEntity, CoverEntity):
supported_features |= CoverEntityFeature.STOP_TILT
self._attr_supported_features = supported_features
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
cover_open = state.get("open")
self._attr_is_closed = None if cover_open is None else cover_open == 0
if (bond_position := state.get("position")) is not None:

View file

@ -64,6 +64,8 @@ class BondEntity(Entity):
self._attr_name = f"{device.name} {sub_device_name}"
else:
self._attr_name = device.name
self._attr_assumed_state = self._hub.is_bridge and not self._device.trust_state
self._apply_state()
@property
def device_info(self) -> DeviceInfo:
@ -137,10 +139,9 @@ class BondEntity(Entity):
self._attr_available = False
else:
self._async_state_callback(state)
self._attr_assumed_state = self._hub.is_bridge and not self._device.trust_state
@abstractmethod
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
raise NotImplementedError
@callback
@ -153,7 +154,8 @@ class BondEntity(Entity):
_LOGGER.debug(
"Device state for %s (%s) is:\n%s", self.name, self.entity_id, state
)
self._apply_state(state)
self._device.state = state
self._apply_state()
@callback
def _async_bpup_callback(self, json_msg: dict) -> None:

View file

@ -19,7 +19,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.percentage import (
int_states_in_range,
@ -46,20 +45,17 @@ async def async_setup_entry(
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
platform = entity_platform.async_get_current_platform()
fans: list[Entity] = [
BondFan(hub, device, bpup_subs)
for device in hub.devices
if DeviceType.is_fan(device.type)
]
platform.async_register_entity_service(
SERVICE_SET_FAN_SPEED_TRACKED_STATE,
{vol.Required("speed"): vol.All(vol.Number(scale=0), vol.Range(0, 100))},
"async_set_speed_belief",
)
async_add_entities(fans, True)
async_add_entities(
BondFan(hub, device, bpup_subs)
for device in hub.devices
if DeviceType.is_fan(device.type)
)
class BondFan(BondEntity, FanEntity):
@ -69,15 +65,15 @@ class BondFan(BondEntity, FanEntity):
self, hub: BondHub, device: BondDevice, bpup_subs: BPUPSubscriptions
) -> None:
"""Create HA entity representing Bond fan."""
super().__init__(hub, device, bpup_subs)
self._power: bool | None = None
self._speed: int | None = None
self._direction: int | None = None
super().__init__(hub, device, bpup_subs)
if self._device.has_action(Action.BREEZE_ON):
self._attr_preset_modes = [PRESET_MODE_BREEZE]
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
self._power = state.get("power")
self._speed = state.get("speed")
self._direction = state.get("direction")

View file

@ -115,7 +115,6 @@ async def async_setup_entry(
async_add_entities(
fan_lights + fan_up_lights + fan_down_lights + fireplaces + fp_lights + lights,
True,
)
@ -170,7 +169,8 @@ class BondLight(BondBaseLight, BondEntity, LightEntity):
self._attr_color_mode = ColorMode.BRIGHTNESS
self._attr_supported_color_modes = {ColorMode.BRIGHTNESS}
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
self._attr_is_on = state.get("light") == 1
brightness = state.get("brightness")
self._attr_brightness = round(brightness * 255 / 100) if brightness else None
@ -227,7 +227,8 @@ class BondLight(BondBaseLight, BondEntity, LightEntity):
class BondDownLight(BondBaseLight, BondEntity, LightEntity):
"""Representation of a Bond light."""
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
self._attr_is_on = bool(state.get("down_light") and state.get("light"))
async def async_turn_on(self, **kwargs: Any) -> None:
@ -246,7 +247,8 @@ class BondDownLight(BondBaseLight, BondEntity, LightEntity):
class BondUpLight(BondBaseLight, BondEntity, LightEntity):
"""Representation of a Bond light."""
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
self._attr_is_on = bool(state.get("up_light") and state.get("light"))
async def async_turn_on(self, **kwargs: Any) -> None:
@ -268,7 +270,8 @@ class BondFireplace(BondEntity, LightEntity):
_attr_color_mode = ColorMode.BRIGHTNESS
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
def _apply_state(self, state: dict) -> None:
def _apply_state(self) -> None:
state = self._device.state
power = state.get("power")
flame = state.get("flame")
self._attr_is_on = power == 1

View file

@ -12,7 +12,6 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import (
@ -36,27 +35,24 @@ async def async_setup_entry(
hub: BondHub = data[HUB]
bpup_subs: BPUPSubscriptions = data[BPUP_SUBS]
platform = entity_platform.async_get_current_platform()
switches: list[Entity] = [
BondSwitch(hub, device, bpup_subs)
for device in hub.devices
if DeviceType.is_generic(device.type)
]
platform.async_register_entity_service(
SERVICE_SET_POWER_TRACKED_STATE,
{vol.Required(ATTR_POWER_STATE): cv.boolean},
"async_set_power_belief",
)
async_add_entities(switches, True)
async_add_entities(
BondSwitch(hub, device, bpup_subs)
for device in hub.devices
if DeviceType.is_generic(device.type)
)
class BondSwitch(BondEntity, SwitchEntity):
"""Representation of a Bond generic device."""
def _apply_state(self, state: dict) -> None:
self._attr_is_on = state.get("power") == 1
def _apply_state(self) -> None:
self._attr_is_on = self._device.state.get("power") == 1
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""

View file

@ -20,11 +20,16 @@ class BondDevice:
"""Helper device class to hold ID and attributes together."""
def __init__(
self, device_id: str, attrs: dict[str, Any], props: dict[str, Any]
self,
device_id: str,
attrs: dict[str, Any],
props: dict[str, Any],
state: dict[str, Any],
) -> None:
"""Create a helper device from ID and attributes returned by API."""
self.device_id = device_id
self.props = props
self.state = state
self._attrs = attrs or {}
self._supported_actions: set[str] = set(self._attrs.get("actions", []))
@ -34,6 +39,7 @@ class BondDevice:
"device_id": self.device_id,
"props": self.props,
"attrs": self._attrs,
"state": self.state,
}.__repr__()
@property
@ -150,7 +156,11 @@ class BondHub:
break
setup_device_ids.append(device_id)
tasks.extend(
[self.bond.device(device_id), self.bond.device_properties(device_id)]
[
self.bond.device(device_id),
self.bond.device_properties(device_id),
self.bond.device_state(device_id),
]
)
responses = await gather_with_concurrency(MAX_REQUESTS, *tasks)
@ -158,10 +168,13 @@ class BondHub:
for device_id in setup_device_ids:
self._devices.append(
BondDevice(
device_id, responses[response_idx], responses[response_idx + 1]
device_id,
responses[response_idx],
responses[response_idx + 1],
responses[response_idx + 2],
)
)
response_idx += 2
response_idx += 3
_LOGGER.debug("Discovered Bond devices: %s", self._devices)
try:

View file

@ -18,6 +18,7 @@ from .common import (
patch_bond_device,
patch_bond_device_ids,
patch_bond_device_properties,
patch_bond_device_state,
patch_bond_token,
patch_bond_version,
)
@ -38,7 +39,7 @@ async def test_user_form(hass: core.HomeAssistant):
return_value={"bondid": "ZXXX12345"}
), patch_bond_device_ids(
return_value=["f6776c11", "f6776c12"]
), patch_bond_bridge(), patch_bond_device_properties(), patch_bond_device(), _patch_async_setup_entry() as mock_setup_entry:
), patch_bond_bridge(), patch_bond_device_properties(), patch_bond_device(), patch_bond_device_state(), _patch_async_setup_entry() as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},
@ -73,7 +74,7 @@ async def test_user_form_with_non_bridge(hass: core.HomeAssistant):
}
), patch_bond_bridge(
return_value={}
), _patch_async_setup_entry() as mock_setup_entry:
), patch_bond_device_state(), _patch_async_setup_entry() as mock_setup_entry:
result2 = await hass.config_entries.flow.async_configure(
result["flow_id"],
{CONF_HOST: "some host", CONF_ACCESS_TOKEN: "test-token"},