mirror of
https://github.com/home-assistant/core.git
synced 2025-04-28 11:17:53 +00:00

* Add Matter update entities for devices with OTA requestor Matter devices which support the OTA requestor cluster can receive updates from a OTA provider. The Home Assistant Python Matter Server implements such an OTA provider now. Add update entities for devices which support the OTA requestor cluster and check for available updates. Allow the user to update the firmware. The update progress will be read directly from the devices' OTA requestor cluster. * Update homeassistant/components/matter/update.py Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com> * Bump python-matter-server to 6.3.0 This includes models and commands required for device firmware updates. * Fix tests by including the new bluetooth_enabled field * Add update entity tests * Fix update entity test * Update entity picture docstring * Add note about reasons for progress state change update * Enable polling for update entities by default Matter entities don't enable polling any longer. Enable polling for update entities by default. * Add comment about why Update entities are polled --------- Co-authored-by: TheJulianJES <TheJulianJES@users.noreply.github.com>
246 lines
7.5 KiB
Python
246 lines
7.5 KiB
Python
"""Provide common fixtures."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
from collections.abc import AsyncGenerator, Generator
|
|
from unittest.mock import AsyncMock, MagicMock, patch
|
|
|
|
from matter_server.client.models.node import MatterNode
|
|
from matter_server.common.const import SCHEMA_VERSION
|
|
from matter_server.common.models import ServerInfoMessage
|
|
import pytest
|
|
|
|
from homeassistant.core import HomeAssistant
|
|
|
|
from .common import setup_integration_with_node_fixture
|
|
|
|
from tests.common import MockConfigEntry
|
|
|
|
MOCK_FABRIC_ID = 12341234
|
|
MOCK_COMPR_FABRIC_ID = 1234
|
|
|
|
|
|
@pytest.fixture(name="matter_client")
|
|
async def matter_client_fixture() -> AsyncGenerator[MagicMock]:
|
|
"""Fixture for a Matter client."""
|
|
with patch(
|
|
"homeassistant.components.matter.MatterClient", autospec=True
|
|
) as client_class:
|
|
client = client_class.return_value
|
|
|
|
async def connect() -> None:
|
|
"""Mock connect."""
|
|
await asyncio.sleep(0)
|
|
|
|
async def listen(init_ready: asyncio.Event | None) -> None:
|
|
"""Mock listen."""
|
|
if init_ready is not None:
|
|
init_ready.set()
|
|
listen_block = asyncio.Event()
|
|
await listen_block.wait()
|
|
pytest.fail("Listen was not cancelled!")
|
|
|
|
client.connect = AsyncMock(side_effect=connect)
|
|
client.start_listening = AsyncMock(side_effect=listen)
|
|
client.server_info = ServerInfoMessage(
|
|
fabric_id=MOCK_FABRIC_ID,
|
|
compressed_fabric_id=MOCK_COMPR_FABRIC_ID,
|
|
schema_version=1,
|
|
sdk_version="2022.11.1",
|
|
wifi_credentials_set=True,
|
|
thread_credentials_set=True,
|
|
min_supported_schema_version=SCHEMA_VERSION,
|
|
bluetooth_enabled=False,
|
|
)
|
|
|
|
yield client
|
|
|
|
|
|
@pytest.fixture(name="integration")
|
|
async def integration_fixture(
|
|
hass: HomeAssistant, matter_client: MagicMock
|
|
) -> MockConfigEntry:
|
|
"""Set up the Matter integration."""
|
|
entry = MockConfigEntry(domain="matter", data={"url": "ws://localhost:5580/ws"})
|
|
entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
return entry
|
|
|
|
|
|
@pytest.fixture(name="create_backup")
|
|
def create_backup_fixture() -> Generator[AsyncMock]:
|
|
"""Mock Supervisor create backup of add-on."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_create_backup"
|
|
) as create_backup:
|
|
yield create_backup
|
|
|
|
|
|
@pytest.fixture(name="addon_store_info")
|
|
def addon_store_info_fixture() -> Generator[AsyncMock]:
|
|
"""Mock Supervisor add-on store info."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_get_addon_store_info"
|
|
) as addon_store_info:
|
|
addon_store_info.return_value = {
|
|
"available": False,
|
|
"installed": None,
|
|
"state": None,
|
|
"version": "1.0.0",
|
|
}
|
|
yield addon_store_info
|
|
|
|
|
|
@pytest.fixture(name="addon_info")
|
|
def addon_info_fixture() -> Generator[AsyncMock]:
|
|
"""Mock Supervisor add-on info."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_get_addon_info",
|
|
) as addon_info:
|
|
addon_info.return_value = {
|
|
"available": False,
|
|
"hostname": None,
|
|
"options": {},
|
|
"state": None,
|
|
"update_available": False,
|
|
"version": None,
|
|
}
|
|
yield addon_info
|
|
|
|
|
|
@pytest.fixture(name="addon_not_installed")
|
|
def addon_not_installed_fixture(
|
|
addon_store_info: AsyncMock, addon_info: AsyncMock
|
|
) -> AsyncMock:
|
|
"""Mock add-on not installed."""
|
|
addon_store_info.return_value["available"] = True
|
|
return addon_info
|
|
|
|
|
|
@pytest.fixture(name="addon_installed")
|
|
def addon_installed_fixture(
|
|
addon_store_info: AsyncMock, addon_info: AsyncMock
|
|
) -> AsyncMock:
|
|
"""Mock add-on already installed but not running."""
|
|
addon_store_info.return_value = {
|
|
"available": True,
|
|
"installed": "1.0.0",
|
|
"state": "stopped",
|
|
"version": "1.0.0",
|
|
}
|
|
addon_info.return_value["available"] = True
|
|
addon_info.return_value["hostname"] = "core-matter-server"
|
|
addon_info.return_value["state"] = "stopped"
|
|
addon_info.return_value["version"] = "1.0.0"
|
|
return addon_info
|
|
|
|
|
|
@pytest.fixture(name="addon_running")
|
|
def addon_running_fixture(
|
|
addon_store_info: AsyncMock, addon_info: AsyncMock
|
|
) -> AsyncMock:
|
|
"""Mock add-on already running."""
|
|
addon_store_info.return_value = {
|
|
"available": True,
|
|
"installed": "1.0.0",
|
|
"state": "started",
|
|
"version": "1.0.0",
|
|
}
|
|
addon_info.return_value["available"] = True
|
|
addon_info.return_value["hostname"] = "core-matter-server"
|
|
addon_info.return_value["state"] = "started"
|
|
addon_info.return_value["version"] = "1.0.0"
|
|
return addon_info
|
|
|
|
|
|
@pytest.fixture(name="install_addon")
|
|
def install_addon_fixture(
|
|
addon_store_info: AsyncMock, addon_info: AsyncMock
|
|
) -> Generator[AsyncMock]:
|
|
"""Mock install add-on."""
|
|
|
|
async def install_addon_side_effect(hass: HomeAssistant, slug: str) -> None:
|
|
"""Mock install add-on."""
|
|
addon_store_info.return_value = {
|
|
"available": True,
|
|
"installed": "1.0.0",
|
|
"state": "stopped",
|
|
"version": "1.0.0",
|
|
}
|
|
addon_info.return_value["available"] = True
|
|
addon_info.return_value["state"] = "stopped"
|
|
addon_info.return_value["version"] = "1.0.0"
|
|
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_install_addon"
|
|
) as install_addon:
|
|
install_addon.side_effect = install_addon_side_effect
|
|
yield install_addon
|
|
|
|
|
|
@pytest.fixture(name="start_addon")
|
|
def start_addon_fixture() -> Generator[AsyncMock]:
|
|
"""Mock start add-on."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_start_addon"
|
|
) as start_addon:
|
|
yield start_addon
|
|
|
|
|
|
@pytest.fixture(name="stop_addon")
|
|
def stop_addon_fixture() -> Generator[AsyncMock]:
|
|
"""Mock stop add-on."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_stop_addon"
|
|
) as stop_addon:
|
|
yield stop_addon
|
|
|
|
|
|
@pytest.fixture(name="uninstall_addon")
|
|
def uninstall_addon_fixture() -> Generator[AsyncMock]:
|
|
"""Mock uninstall add-on."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_uninstall_addon"
|
|
) as uninstall_addon:
|
|
yield uninstall_addon
|
|
|
|
|
|
@pytest.fixture(name="update_addon")
|
|
def update_addon_fixture() -> Generator[AsyncMock]:
|
|
"""Mock update add-on."""
|
|
with patch(
|
|
"homeassistant.components.hassio.addon_manager.async_update_addon"
|
|
) as update_addon:
|
|
yield update_addon
|
|
|
|
|
|
@pytest.fixture(name="door_lock")
|
|
async def door_lock_fixture(
|
|
hass: HomeAssistant, matter_client: MagicMock
|
|
) -> MatterNode:
|
|
"""Fixture for a door lock node."""
|
|
return await setup_integration_with_node_fixture(hass, "door-lock", matter_client)
|
|
|
|
|
|
@pytest.fixture(name="door_lock_with_unbolt")
|
|
async def door_lock_with_unbolt_fixture(
|
|
hass: HomeAssistant, matter_client: MagicMock
|
|
) -> MatterNode:
|
|
"""Fixture for a door lock node with unbolt feature."""
|
|
return await setup_integration_with_node_fixture(
|
|
hass, "door-lock-with-unbolt", matter_client
|
|
)
|
|
|
|
|
|
@pytest.fixture(name="eve_contact_sensor_node")
|
|
async def eve_contact_sensor_node_fixture(
|
|
hass: HomeAssistant, matter_client: MagicMock
|
|
) -> MatterNode:
|
|
"""Fixture for a contact sensor node."""
|
|
return await setup_integration_with_node_fixture(
|
|
hass, "eve-contact-sensor", matter_client
|
|
)
|