Reduce bond fallback polling interval when BPUP is alive (#90871)
* Reduce bond fallback polling interval when BPUP is alive If push updates are alive we should not check every 10 seconds. * tweak * tweak * coverage * coverage * coverage
This commit is contained in:
parent
8fe597b7c6
commit
59872f1914
4 changed files with 93 additions and 12 deletions
|
@ -17,9 +17,9 @@ from homeassistant.const import (
|
|||
ATTR_SW_VERSION,
|
||||
ATTR_VIA_DEVICE,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import CALLBACK_TYPE, callback
|
||||
from homeassistant.helpers.entity import DeviceInfo, Entity
|
||||
from homeassistant.helpers.event import async_track_time_interval
|
||||
from homeassistant.helpers.event import async_call_later
|
||||
|
||||
from .const import DOMAIN
|
||||
from .utils import BondDevice, BondHub
|
||||
|
@ -27,6 +27,7 @@ from .utils import BondDevice, BondHub
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
_FALLBACK_SCAN_INTERVAL = timedelta(seconds=10)
|
||||
_BPUP_ALIVE_SCAN_INTERVAL = timedelta(seconds=60)
|
||||
|
||||
|
||||
class BondEntity(Entity):
|
||||
|
@ -65,6 +66,7 @@ class BondEntity(Entity):
|
|||
self._attr_name = device.name
|
||||
self._attr_assumed_state = self._hub.is_bridge and not self._device.trust_state
|
||||
self._apply_state()
|
||||
self._bpup_polling_fallback: CALLBACK_TYPE | None = None
|
||||
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
|
@ -100,12 +102,13 @@ class BondEntity(Entity):
|
|||
return device_info
|
||||
|
||||
async def async_update(self) -> None:
|
||||
"""Fetch assumed state of the cover from the hub using API."""
|
||||
"""Perform a manual update from API."""
|
||||
await self._async_update_from_api()
|
||||
|
||||
@callback
|
||||
def _async_update_if_bpup_not_alive(self, now: datetime) -> None:
|
||||
"""Fetch via the API if BPUP is not alive."""
|
||||
self._async_schedule_bpup_alive_or_poll()
|
||||
if (
|
||||
self.hass.is_stopping
|
||||
or self._bpup_subs.alive
|
||||
|
@ -172,16 +175,22 @@ class BondEntity(Entity):
|
|||
"""Subscribe to BPUP and start polling."""
|
||||
await super().async_added_to_hass()
|
||||
self._bpup_subs.subscribe(self._device_id, self._async_bpup_callback)
|
||||
self.async_on_remove(
|
||||
async_track_time_interval(
|
||||
self.hass,
|
||||
self._async_update_if_bpup_not_alive,
|
||||
_FALLBACK_SCAN_INTERVAL,
|
||||
name=f"Bond {self.entity_id} fallback polling",
|
||||
)
|
||||
self._async_schedule_bpup_alive_or_poll()
|
||||
|
||||
@callback
|
||||
def _async_schedule_bpup_alive_or_poll(self) -> None:
|
||||
"""Schedule the BPUP alive or poll."""
|
||||
alive = self._bpup_subs.alive
|
||||
self._bpup_polling_fallback = async_call_later(
|
||||
self.hass,
|
||||
_BPUP_ALIVE_SCAN_INTERVAL if alive else _FALLBACK_SCAN_INTERVAL,
|
||||
self._async_update_if_bpup_not_alive,
|
||||
)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Unsubscribe from BPUP data on remove."""
|
||||
await super().async_will_remove_from_hass()
|
||||
self._bpup_subs.unsubscribe(self._device_id, self._async_bpup_callback)
|
||||
if self._bpup_polling_fallback:
|
||||
self._bpup_polling_fallback()
|
||||
self._bpup_polling_fallback = None
|
||||
|
|
|
@ -127,7 +127,12 @@ def patch_bond_version(
|
|||
return nullcontext()
|
||||
|
||||
if return_value is None:
|
||||
return_value = {"bondid": "ZXXX12345"}
|
||||
return_value = {
|
||||
"bondid": "ZXXX12345",
|
||||
"target": "test-model",
|
||||
"fw_ver": "test-version",
|
||||
"mcu_ver": "test-hw-version",
|
||||
}
|
||||
|
||||
return patch(
|
||||
"homeassistant.components.bond.Bond.version",
|
||||
|
|
|
@ -42,5 +42,12 @@ async def test_diagnostics(
|
|||
"data": {"access_token": "**REDACTED**", "host": "some host"},
|
||||
"title": "Mock Title",
|
||||
},
|
||||
"hub": {"version": {"bondid": "ZXXX12345"}},
|
||||
"hub": {
|
||||
"version": {
|
||||
"bondid": "ZXXX12345",
|
||||
"fw_ver": "test-version",
|
||||
"mcu_ver": "test-hw-version",
|
||||
"target": "test-model",
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -468,3 +468,63 @@ async def test_fan_available(hass: HomeAssistant) -> None:
|
|||
await help_test_entity_available(
|
||||
hass, FAN_DOMAIN, ceiling_fan("name-1"), "fan.name_1"
|
||||
)
|
||||
|
||||
|
||||
async def test_setup_smart_by_bond_fan(hass: HomeAssistant) -> None:
|
||||
"""Test setting up a fan without a hub."""
|
||||
config_entry = await setup_platform(
|
||||
hass,
|
||||
FAN_DOMAIN,
|
||||
ceiling_fan("name-1"),
|
||||
bond_device_id="test-device-id",
|
||||
bond_version={
|
||||
"bondid": "KXXX12345",
|
||||
"target": "test-model",
|
||||
"fw_ver": "test-version",
|
||||
"mcu_ver": "test-hw-version",
|
||||
},
|
||||
)
|
||||
assert hass.states.get("fan.name_1") is not None
|
||||
registry = er.async_get(hass)
|
||||
entry = registry.async_get("fan.name_1")
|
||||
assert entry.device_id is not None
|
||||
device_registry = dr.async_get(hass)
|
||||
device = device_registry.async_get(entry.device_id)
|
||||
assert device is not None
|
||||
assert device.sw_version == "test-version"
|
||||
assert device.manufacturer == "Olibra"
|
||||
assert device.identifiers == {("bond", "KXXX12345", "test-device-id")}
|
||||
assert device.hw_version == "test-hw-version"
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def test_setup_hub_template_fan(hass: HomeAssistant) -> None:
|
||||
"""Test setting up a fan on a hub created from a template."""
|
||||
config_entry = await setup_platform(
|
||||
hass,
|
||||
FAN_DOMAIN,
|
||||
{**ceiling_fan("name-1"), "template": "test-template"},
|
||||
bond_device_id="test-device-id",
|
||||
props={"branding_profile": "test-branding-profile"},
|
||||
bond_version={
|
||||
"bondid": "ZXXX12345",
|
||||
"target": "test-model",
|
||||
"fw_ver": "test-version",
|
||||
"mcu_ver": "test-hw-version",
|
||||
},
|
||||
)
|
||||
assert hass.states.get("fan.name_1") is not None
|
||||
registry = er.async_get(hass)
|
||||
entry = registry.async_get("fan.name_1")
|
||||
assert entry.device_id is not None
|
||||
device_registry = dr.async_get(hass)
|
||||
device = device_registry.async_get(entry.device_id)
|
||||
assert device is not None
|
||||
assert device.sw_version is None
|
||||
assert device.model == "test-branding-profile test-template"
|
||||
assert device.manufacturer == "Olibra"
|
||||
assert device.identifiers == {("bond", "ZXXX12345", "test-device-id")}
|
||||
assert device.hw_version is None
|
||||
await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
|
Loading…
Add table
Reference in a new issue