mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 07:37:34 +00:00
Home Connect entities availability based on the connected state of the appliance (#136951)
* Base the entity availability on the connected state of the appliance * cache `ha_id` Co-authored-by: Martin Hjelmare <marhje52@gmail.com> * Inlcude coordinator `available` property at entity Co-authored-by: Martin Hjelmare <marhje52@gmail.com> --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
efcfd97d1b
commit
63ab13681a
@ -121,9 +121,10 @@ class HomeConnectCoordinator(
|
|||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
async for event_message in self.client.stream_all_events():
|
async for event_message in self.client.stream_all_events():
|
||||||
|
event_message_ha_id = event_message.ha_id
|
||||||
match event_message.type:
|
match event_message.type:
|
||||||
case EventType.STATUS:
|
case EventType.STATUS:
|
||||||
statuses = self.data[event_message.ha_id].status
|
statuses = self.data[event_message_ha_id].status
|
||||||
for event in event_message.data.items:
|
for event in event_message.data.items:
|
||||||
status_key = StatusKey(event.key)
|
status_key = StatusKey(event.key)
|
||||||
if status_key in statuses:
|
if status_key in statuses:
|
||||||
@ -134,10 +135,11 @@ class HomeConnectCoordinator(
|
|||||||
raw_key=status_key.value,
|
raw_key=status_key.value,
|
||||||
value=event.value,
|
value=event.value,
|
||||||
)
|
)
|
||||||
|
self._call_event_listener(event_message)
|
||||||
|
|
||||||
case EventType.NOTIFY:
|
case EventType.NOTIFY:
|
||||||
settings = self.data[event_message.ha_id].settings
|
settings = self.data[event_message_ha_id].settings
|
||||||
events = self.data[event_message.ha_id].events
|
events = self.data[event_message_ha_id].events
|
||||||
for event in event_message.data.items:
|
for event in event_message.data.items:
|
||||||
if event.key in SettingKey:
|
if event.key in SettingKey:
|
||||||
setting_key = SettingKey(event.key)
|
setting_key = SettingKey(event.key)
|
||||||
@ -151,13 +153,25 @@ class HomeConnectCoordinator(
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
events[event.key] = event
|
events[event.key] = event
|
||||||
|
self._call_event_listener(event_message)
|
||||||
|
|
||||||
case EventType.EVENT:
|
case EventType.EVENT:
|
||||||
events = self.data[event_message.ha_id].events
|
events = self.data[event_message_ha_id].events
|
||||||
for event in event_message.data.items:
|
for event in event_message.data.items:
|
||||||
events[event.key] = event
|
events[event.key] = event
|
||||||
|
self._call_event_listener(event_message)
|
||||||
|
|
||||||
self._call_event_listener(event_message)
|
case EventType.CONNECTED:
|
||||||
|
self.data[event_message_ha_id].info.connected = True
|
||||||
|
self._call_all_event_listeners_for_appliance(
|
||||||
|
event_message_ha_id
|
||||||
|
)
|
||||||
|
|
||||||
|
case EventType.DISCONNECTED:
|
||||||
|
self.data[event_message_ha_id].info.connected = False
|
||||||
|
self._call_all_event_listeners_for_appliance(
|
||||||
|
event_message_ha_id
|
||||||
|
)
|
||||||
|
|
||||||
except (EventStreamInterruptedError, HomeConnectRequestError) as error:
|
except (EventStreamInterruptedError, HomeConnectRequestError) as error:
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
@ -186,6 +200,12 @@ class HomeConnectCoordinator(
|
|||||||
):
|
):
|
||||||
listener()
|
listener()
|
||||||
|
|
||||||
|
@callback
|
||||||
|
def _call_all_event_listeners_for_appliance(self, ha_id: str):
|
||||||
|
for listener, context in self._listeners.values():
|
||||||
|
if isinstance(context, tuple) and context[0] == ha_id:
|
||||||
|
listener()
|
||||||
|
|
||||||
async def _async_update_data(self) -> dict[str, HomeConnectApplianceData]:
|
async def _async_update_data(self) -> dict[str, HomeConnectApplianceData]:
|
||||||
"""Fetch data from Home Connect."""
|
"""Fetch data from Home Connect."""
|
||||||
try:
|
try:
|
||||||
|
@ -56,3 +56,10 @@ class HomeConnectEntity(CoordinatorEntity[HomeConnectCoordinator]):
|
|||||||
def bsh_key(self) -> str:
|
def bsh_key(self) -> str:
|
||||||
"""Return the BSH key."""
|
"""Return the BSH key."""
|
||||||
return self.entity_description.key
|
return self.entity_description.key
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return True if entity is available."""
|
||||||
|
return (
|
||||||
|
self.appliance.info.connected and self._attr_available and super().available
|
||||||
|
)
|
||||||
|
@ -18,7 +18,13 @@ from homeassistant.components.home_connect.const import (
|
|||||||
)
|
)
|
||||||
from homeassistant.components.script import scripts_with_entity
|
from homeassistant.components.script import scripts_with_entity
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNKNOWN, Platform
|
from homeassistant.const import (
|
||||||
|
STATE_OFF,
|
||||||
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
|
STATE_UNKNOWN,
|
||||||
|
Platform,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
import homeassistant.helpers.issue_registry as ir
|
import homeassistant.helpers.issue_registry as ir
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
@ -44,6 +50,59 @@ async def test_binary_sensors(
|
|||||||
assert config_entry.state == ConfigEntryState.LOADED
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
async def test_binary_sensors_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if binary sensor entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"binary_sensor.washer_door",
|
||||||
|
"binary_sensor.washer_remote_control",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("value", "expected"),
|
("value", "expected"),
|
||||||
[
|
[
|
||||||
|
@ -27,6 +27,7 @@ from homeassistant.const import (
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -55,6 +56,59 @@ async def test_light(
|
|||||||
assert config_entry.state == ConfigEntryState.LOADED
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("appliance_ha_id", ["Hood"], indirect=True)
|
||||||
|
async def test_light_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if light entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"light.hood_functional_light",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
(
|
(
|
||||||
"entity_id",
|
"entity_id",
|
||||||
|
@ -4,7 +4,14 @@ from collections.abc import Awaitable, Callable
|
|||||||
import random
|
import random
|
||||||
from unittest.mock import AsyncMock, MagicMock
|
from unittest.mock import AsyncMock, MagicMock
|
||||||
|
|
||||||
from aiohomeconnect.model import ArrayOfSettings, GetSetting, SettingKey
|
from aiohomeconnect.model import (
|
||||||
|
ArrayOfEvents,
|
||||||
|
ArrayOfSettings,
|
||||||
|
EventMessage,
|
||||||
|
EventType,
|
||||||
|
GetSetting,
|
||||||
|
SettingKey,
|
||||||
|
)
|
||||||
from aiohomeconnect.model.error import HomeConnectError
|
from aiohomeconnect.model.error import HomeConnectError
|
||||||
from aiohomeconnect.model.setting import SettingConstraints
|
from aiohomeconnect.model.setting import SettingConstraints
|
||||||
import pytest
|
import pytest
|
||||||
@ -17,7 +24,7 @@ from homeassistant.components.number import (
|
|||||||
SERVICE_SET_VALUE,
|
SERVICE_SET_VALUE,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, Platform
|
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
@ -42,6 +49,64 @@ async def test_number(
|
|||||||
assert config_entry.state is ConfigEntryState.LOADED
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("appliance_ha_id", ["FridgeFreezer"], indirect=True)
|
||||||
|
async def test_number_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if number entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
f"{NUMBER_DOMAIN.lower()}.fridgefreezer_refrigerator_temperature",
|
||||||
|
]
|
||||||
|
|
||||||
|
client.get_setting.side_effect = None
|
||||||
|
# Setting constrains are not needed for this test
|
||||||
|
# so we rise an error to easily test the availability
|
||||||
|
client.get_setting = AsyncMock(side_effect=HomeConnectError())
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("appliance_ha_id", ["FridgeFreezer"], indirect=True)
|
@pytest.mark.parametrize("appliance_ha_id", ["FridgeFreezer"], indirect=True)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
(
|
(
|
||||||
|
@ -29,6 +29,7 @@ from homeassistant.config_entries import ConfigEntryState
|
|||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ENTITY_ID,
|
ATTR_ENTITY_ID,
|
||||||
SERVICE_SELECT_OPTION,
|
SERVICE_SELECT_OPTION,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
STATE_UNKNOWN,
|
STATE_UNKNOWN,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
@ -57,6 +58,58 @@ async def test_select(
|
|||||||
assert config_entry.state is ConfigEntryState.LOADED
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
async def test_select_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if select entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"select.washer_active_program",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
async def test_filter_programs(
|
async def test_filter_programs(
|
||||||
config_entry: MockConfigEntry,
|
config_entry: MockConfigEntry,
|
||||||
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
@ -24,7 +24,7 @@ from homeassistant.components.home_connect.const import (
|
|||||||
BSH_EVENT_PRESENT_STATE_PRESENT,
|
BSH_EVENT_PRESENT_STATE_PRESENT,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
@ -94,6 +94,60 @@ async def test_sensors(
|
|||||||
assert config_entry.state == ConfigEntryState.LOADED
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("appliance_ha_id", [TEST_HC_APP], indirect=True)
|
||||||
|
async def test_sensor_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if sensor entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"sensor.dishwasher_operation_state",
|
||||||
|
"sensor.dishwasher_salt_nearly_empty",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
# Appliance_ha_id program sequence with a delayed start.
|
# Appliance_ha_id program sequence with a delayed start.
|
||||||
PROGRAM_SEQUENCE_EVENTS = (
|
PROGRAM_SEQUENCE_EVENTS = (
|
||||||
EVENT_PROG_DELAYED_START,
|
EVENT_PROG_DELAYED_START,
|
||||||
|
@ -36,6 +36,7 @@ from homeassistant.const import (
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
STATE_OFF,
|
STATE_OFF,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
|
STATE_UNAVAILABLE,
|
||||||
Platform,
|
Platform,
|
||||||
)
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
@ -65,6 +66,61 @@ async def test_switches(
|
|||||||
assert config_entry.state == ConfigEntryState.LOADED
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("appliance_ha_id", ["Dishwasher"], indirect=True)
|
||||||
|
async def test_switch_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if switch entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"switch.dishwasher_power",
|
||||||
|
"switch.dishwasher_child_lock",
|
||||||
|
"switch.dishwasher_program_eco50",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
(
|
(
|
||||||
"entity_id",
|
"entity_id",
|
||||||
|
@ -4,13 +4,14 @@ from collections.abc import Awaitable, Callable
|
|||||||
from datetime import time
|
from datetime import time
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
from aiohomeconnect.model import ArrayOfSettings, GetSetting, SettingKey
|
from aiohomeconnect.model import ArrayOfSettings, EventMessage, GetSetting, SettingKey
|
||||||
from aiohomeconnect.model.error import HomeConnectError
|
from aiohomeconnect.model.error import HomeConnectError
|
||||||
|
from aiohomeconnect.model.event import ArrayOfEvents, EventType
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.time import DOMAIN as TIME_DOMAIN, SERVICE_SET_VALUE
|
from homeassistant.components.time import DOMAIN as TIME_DOMAIN, SERVICE_SET_VALUE
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TIME, Platform
|
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TIME, STATE_UNAVAILABLE, Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
|
|
||||||
@ -35,6 +36,59 @@ async def test_time(
|
|||||||
assert config_entry.state is ConfigEntryState.LOADED
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("appliance_ha_id", ["Oven"], indirect=True)
|
||||||
|
async def test_time_entity_availabilty(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: MockConfigEntry,
|
||||||
|
integration_setup: Callable[[MagicMock], Awaitable[bool]],
|
||||||
|
setup_credentials: None,
|
||||||
|
client: MagicMock,
|
||||||
|
appliance_ha_id: str,
|
||||||
|
) -> None:
|
||||||
|
"""Test if time entities availability are based on the appliance connection state."""
|
||||||
|
entity_ids = [
|
||||||
|
"time.oven_alarm_clock",
|
||||||
|
]
|
||||||
|
assert config_entry.state == ConfigEntryState.NOT_LOADED
|
||||||
|
assert await integration_setup(client)
|
||||||
|
assert config_entry.state == ConfigEntryState.LOADED
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.DISCONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
assert hass.states.is_state(entity_id, STATE_UNAVAILABLE)
|
||||||
|
|
||||||
|
await client.add_events(
|
||||||
|
[
|
||||||
|
EventMessage(
|
||||||
|
appliance_ha_id,
|
||||||
|
EventType.CONNECTED,
|
||||||
|
ArrayOfEvents([]),
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
for entity_id in entity_ids:
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state
|
||||||
|
assert state.state != STATE_UNAVAILABLE
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("appliance_ha_id", ["Oven"], indirect=True)
|
@pytest.mark.parametrize("appliance_ha_id", ["Oven"], indirect=True)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("entity_id", "setting_key"),
|
("entity_id", "setting_key"),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user