mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 00:37:53 +00:00
Fix Hydrawise sensor availability (#118669)
Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
parent
f1e6375406
commit
0084d6c5bd
@ -24,13 +24,17 @@ class HydrawiseBinarySensorEntityDescription(BinarySensorEntityDescription):
|
||||
"""Describes Hydrawise binary sensor."""
|
||||
|
||||
value_fn: Callable[[HydrawiseBinarySensor], bool | None]
|
||||
always_available: bool = False
|
||||
|
||||
|
||||
CONTROLLER_BINARY_SENSORS: tuple[HydrawiseBinarySensorEntityDescription, ...] = (
|
||||
HydrawiseBinarySensorEntityDescription(
|
||||
key="status",
|
||||
device_class=BinarySensorDeviceClass.CONNECTIVITY,
|
||||
value_fn=lambda status_sensor: status_sensor.coordinator.last_update_success,
|
||||
value_fn=lambda status_sensor: status_sensor.coordinator.last_update_success
|
||||
and status_sensor.controller.online,
|
||||
# Connectivtiy sensor is always available
|
||||
always_available=True,
|
||||
),
|
||||
)
|
||||
|
||||
@ -98,3 +102,10 @@ class HydrawiseBinarySensor(HydrawiseEntity, BinarySensorEntity):
|
||||
def _update_attrs(self) -> None:
|
||||
"""Update state attributes."""
|
||||
self._attr_is_on = self.entity_description.value_fn(self)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Set the entity availability."""
|
||||
if self.entity_description.always_available:
|
||||
return True
|
||||
return super().available
|
||||
|
@ -70,3 +70,8 @@ class HydrawiseEntity(CoordinatorEntity[HydrawiseDataUpdateCoordinator]):
|
||||
self.controller = self.coordinator.data.controllers[self.controller.id]
|
||||
self._update_attrs()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Set the entity availability."""
|
||||
return super().available and self.controller.online
|
||||
|
@ -6,10 +6,11 @@ from unittest.mock import AsyncMock, patch
|
||||
|
||||
from aiohttp import ClientError
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from pydrawise.schema import Controller
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.hydrawise.const import SCAN_INTERVAL
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.const import STATE_OFF, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
@ -47,4 +48,23 @@ async def test_update_data_fails(
|
||||
|
||||
connectivity = hass.states.get("binary_sensor.home_controller_connectivity")
|
||||
assert connectivity is not None
|
||||
assert connectivity.state == "unavailable"
|
||||
assert connectivity.state == STATE_OFF
|
||||
|
||||
|
||||
async def test_controller_offline(
|
||||
hass: HomeAssistant,
|
||||
mock_added_config_entry: MockConfigEntry,
|
||||
mock_pydrawise: AsyncMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
controller: Controller,
|
||||
) -> None:
|
||||
"""Test the binary_sensor for the controller being online."""
|
||||
# Make the coordinator refresh data.
|
||||
controller.online = False
|
||||
freezer.tick(SCAN_INTERVAL + timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
connectivity = hass.states.get("binary_sensor.home_controller_connectivity")
|
||||
assert connectivity
|
||||
assert connectivity.state == STATE_OFF
|
||||
|
65
tests/components/hydrawise/test_entity_availability.py
Normal file
65
tests/components/hydrawise/test_entity_availability.py
Normal file
@ -0,0 +1,65 @@
|
||||
"""Test entity availability."""
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from aiohttp import ClientError
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from pydrawise.schema import Controller
|
||||
|
||||
from homeassistant.components.hydrawise.const import SCAN_INTERVAL
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import STATE_OFF, STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
_SPECIAL_ENTITIES = {"binary_sensor.home_controller_connectivity": STATE_OFF}
|
||||
|
||||
|
||||
async def test_controller_offline(
|
||||
hass: HomeAssistant,
|
||||
mock_add_config_entry: Callable[[], Awaitable[MockConfigEntry]],
|
||||
entity_registry: er.EntityRegistry,
|
||||
controller: Controller,
|
||||
) -> None:
|
||||
"""Test availability for sensors when controller is offline."""
|
||||
controller.online = False
|
||||
config_entry = await mock_add_config_entry()
|
||||
_test_availability(hass, config_entry, entity_registry)
|
||||
|
||||
|
||||
async def test_api_offline(
|
||||
hass: HomeAssistant,
|
||||
mock_add_config_entry: Callable[[], Awaitable[MockConfigEntry]],
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_pydrawise: AsyncMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test availability of sensors when API call fails."""
|
||||
config_entry = await mock_add_config_entry()
|
||||
mock_pydrawise.get_user.reset_mock(return_value=True)
|
||||
mock_pydrawise.get_user.side_effect = ClientError
|
||||
freezer.tick(SCAN_INTERVAL + timedelta(seconds=30))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
_test_availability(hass, config_entry, entity_registry)
|
||||
|
||||
|
||||
def _test_availability(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
) -> None:
|
||||
entity_entries = er.async_entries_for_config_entry(
|
||||
entity_registry, config_entry.entry_id
|
||||
)
|
||||
assert entity_entries
|
||||
for entity_entry in entity_entries:
|
||||
state = hass.states.get(entity_entry.entity_id)
|
||||
assert state, f"State not found for {entity_entry.entity_id}"
|
||||
assert state.state == _SPECIAL_ENTITIES.get(
|
||||
entity_entry.entity_id, STATE_UNAVAILABLE
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user