Add go2rtc recommended version (#130508)
This commit is contained in:
parent
0ac00ef092
commit
2eaaadd736
7 changed files with 94 additions and 11 deletions
|
@ -90,7 +90,7 @@ repos:
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
language: script
|
language: script
|
||||||
types: [text]
|
types: [text]
|
||||||
files: ^(script/hassfest/metadata\.py|homeassistant/const\.py$|pyproject\.toml)$
|
files: ^(script/hassfest/metadata\.py|homeassistant/const\.py$|pyproject\.toml|homeassistant/components/go2rtc/const\.py)$
|
||||||
- id: hassfest-mypy-config
|
- id: hassfest-mypy-config
|
||||||
name: hassfest-mypy-config
|
name: hassfest-mypy-config
|
||||||
entry: script/run-in-env.sh python3 -m script.hassfest -p mypy_config
|
entry: script/run-in-env.sh python3 -m script.hassfest -p mypy_config
|
||||||
|
|
|
@ -4,6 +4,7 @@ import logging
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from aiohttp.client_exceptions import ClientConnectionError, ServerConnectionError
|
from aiohttp.client_exceptions import ClientConnectionError, ServerConnectionError
|
||||||
|
from awesomeversion import AwesomeVersion
|
||||||
from go2rtc_client import Go2RtcRestClient
|
from go2rtc_client import Go2RtcRestClient
|
||||||
from go2rtc_client.exceptions import Go2RtcClientError, Go2RtcVersionError
|
from go2rtc_client.exceptions import Go2RtcClientError, Go2RtcVersionError
|
||||||
from go2rtc_client.ws import (
|
from go2rtc_client.ws import (
|
||||||
|
@ -32,13 +33,23 @@ from homeassistant.config_entries import SOURCE_SYSTEM, ConfigEntry
|
||||||
from homeassistant.const import CONF_URL, EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import CONF_URL, EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.core import Event, HomeAssistant, callback
|
from homeassistant.core import Event, HomeAssistant, callback
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import config_validation as cv, discovery_flow
|
from homeassistant.helpers import (
|
||||||
|
config_validation as cv,
|
||||||
|
discovery_flow,
|
||||||
|
issue_registry as ir,
|
||||||
|
)
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.util.hass_dict import HassKey
|
from homeassistant.util.hass_dict import HassKey
|
||||||
from homeassistant.util.package import is_docker_env
|
from homeassistant.util.package import is_docker_env
|
||||||
|
|
||||||
from .const import CONF_DEBUG_UI, DEBUG_UI_URL_MESSAGE, DOMAIN, HA_MANAGED_URL
|
from .const import (
|
||||||
|
CONF_DEBUG_UI,
|
||||||
|
DEBUG_UI_URL_MESSAGE,
|
||||||
|
DOMAIN,
|
||||||
|
HA_MANAGED_URL,
|
||||||
|
RECOMMENDED_VERSION,
|
||||||
|
)
|
||||||
from .server import Server
|
from .server import Server
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
@ -147,7 +158,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
# Validate the server URL
|
# Validate the server URL
|
||||||
try:
|
try:
|
||||||
client = Go2RtcRestClient(async_get_clientsession(hass), url)
|
client = Go2RtcRestClient(async_get_clientsession(hass), url)
|
||||||
await client.validate_server_version()
|
version = await client.validate_server_version()
|
||||||
|
if version < AwesomeVersion(RECOMMENDED_VERSION):
|
||||||
|
ir.async_create_issue(
|
||||||
|
hass,
|
||||||
|
DOMAIN,
|
||||||
|
"recommended_version",
|
||||||
|
is_fixable=False,
|
||||||
|
is_persistent=False,
|
||||||
|
severity=ir.IssueSeverity.WARNING,
|
||||||
|
translation_key="recommended_version",
|
||||||
|
translation_placeholders={
|
||||||
|
"recommended_version": RECOMMENDED_VERSION,
|
||||||
|
"current_version": str(version),
|
||||||
|
},
|
||||||
|
)
|
||||||
except Go2RtcClientError as err:
|
except Go2RtcClientError as err:
|
||||||
if isinstance(err.__cause__, _RETRYABLE_ERRORS):
|
if isinstance(err.__cause__, _RETRYABLE_ERRORS):
|
||||||
raise ConfigEntryNotReady(
|
raise ConfigEntryNotReady(
|
||||||
|
|
|
@ -6,3 +6,4 @@ CONF_DEBUG_UI = "debug_ui"
|
||||||
DEBUG_UI_URL_MESSAGE = "Url and debug_ui cannot be set at the same time."
|
DEBUG_UI_URL_MESSAGE = "Url and debug_ui cannot be set at the same time."
|
||||||
HA_MANAGED_API_PORT = 11984
|
HA_MANAGED_API_PORT = 11984
|
||||||
HA_MANAGED_URL = f"http://localhost:{HA_MANAGED_API_PORT}/"
|
HA_MANAGED_URL = f"http://localhost:{HA_MANAGED_API_PORT}/"
|
||||||
|
RECOMMENDED_VERSION = "1.9.7"
|
||||||
|
|
8
homeassistant/components/go2rtc/strings.json
Normal file
8
homeassistant/components/go2rtc/strings.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"issues": {
|
||||||
|
"recommended_version": {
|
||||||
|
"title": "Outdated go2rtc server detected",
|
||||||
|
"description": "We detected that you are using an outdated go2rtc server version. For the best experience, we recommend updating the go2rtc server to version `{recommended_version}`.\nCurrently you are using version `{current_version}`."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from homeassistant import core
|
from homeassistant import core
|
||||||
|
from homeassistant.components.go2rtc.const import RECOMMENDED_VERSION as GO2RTC_VERSION
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.util import executor, thread
|
from homeassistant.util import executor, thread
|
||||||
from script.gen_requirements_all import gather_recursive_requirements
|
from script.gen_requirements_all import gather_recursive_requirements
|
||||||
|
@ -112,8 +113,6 @@ LABEL "com.github.actions.icon"="terminal"
|
||||||
LABEL "com.github.actions.color"="gray-dark"
|
LABEL "com.github.actions.color"="gray-dark"
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_GO2RTC_VERSION = "1.9.7"
|
|
||||||
|
|
||||||
|
|
||||||
def _get_package_versions(file: Path, packages: set[str]) -> dict[str, str]:
|
def _get_package_versions(file: Path, packages: set[str]) -> dict[str, str]:
|
||||||
package_versions: dict[str, str] = {}
|
package_versions: dict[str, str] = {}
|
||||||
|
@ -197,7 +196,7 @@ def _generate_files(config: Config) -> list[File]:
|
||||||
DOCKERFILE_TEMPLATE.format(
|
DOCKERFILE_TEMPLATE.format(
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
**package_versions,
|
**package_versions,
|
||||||
go2rtc=_GO2RTC_VERSION,
|
go2rtc=GO2RTC_VERSION,
|
||||||
),
|
),
|
||||||
config.root / "Dockerfile",
|
config.root / "Dockerfile",
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
from collections.abc import Generator
|
from collections.abc import Generator
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
|
from awesomeversion import AwesomeVersion
|
||||||
from go2rtc_client.rest import _StreamClient, _WebRTCClient
|
from go2rtc_client.rest import _StreamClient, _WebRTCClient
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.go2rtc.const import RECOMMENDED_VERSION
|
||||||
from homeassistant.components.go2rtc.server import Server
|
from homeassistant.components.go2rtc.server import Server
|
||||||
|
|
||||||
GO2RTC_PATH = "homeassistant.components.go2rtc"
|
GO2RTC_PATH = "homeassistant.components.go2rtc"
|
||||||
|
@ -23,7 +25,9 @@ def rest_client() -> Generator[AsyncMock]:
|
||||||
client = mock_client.return_value
|
client = mock_client.return_value
|
||||||
client.streams = streams = Mock(spec_set=_StreamClient)
|
client.streams = streams = Mock(spec_set=_StreamClient)
|
||||||
streams.list.return_value = {}
|
streams.list.return_value = {}
|
||||||
client.validate_server_version = AsyncMock()
|
client.validate_server_version = AsyncMock(
|
||||||
|
return_value=AwesomeVersion(RECOMMENDED_VERSION)
|
||||||
|
)
|
||||||
client.webrtc = Mock(spec_set=_WebRTCClient)
|
client.webrtc = Mock(spec_set=_WebRTCClient)
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ from typing import NamedTuple
|
||||||
from unittest.mock import AsyncMock, Mock, patch
|
from unittest.mock import AsyncMock, Mock, patch
|
||||||
|
|
||||||
from aiohttp.client_exceptions import ClientConnectionError, ServerConnectionError
|
from aiohttp.client_exceptions import ClientConnectionError, ServerConnectionError
|
||||||
|
from awesomeversion import AwesomeVersion
|
||||||
from go2rtc_client import Stream
|
from go2rtc_client import Stream
|
||||||
from go2rtc_client.exceptions import Go2RtcClientError, Go2RtcVersionError
|
from go2rtc_client.exceptions import Go2RtcClientError, Go2RtcVersionError
|
||||||
from go2rtc_client.models import Producer
|
from go2rtc_client.models import Producer
|
||||||
|
@ -36,10 +37,12 @@ from homeassistant.components.go2rtc.const import (
|
||||||
CONF_DEBUG_UI,
|
CONF_DEBUG_UI,
|
||||||
DEBUG_UI_URL_MESSAGE,
|
DEBUG_UI_URL_MESSAGE,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
RECOMMENDED_VERSION,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow
|
from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow
|
||||||
from homeassistant.const import CONF_URL
|
from homeassistant.const import CONF_URL
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers import issue_registry as ir
|
||||||
from homeassistant.helpers.typing import ConfigType
|
from homeassistant.helpers.typing import ConfigType
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
@ -199,6 +202,7 @@ async def init_test_integration(
|
||||||
|
|
||||||
async def _test_setup_and_signaling(
|
async def _test_setup_and_signaling(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
issue_registry: ir.IssueRegistry,
|
||||||
rest_client: AsyncMock,
|
rest_client: AsyncMock,
|
||||||
ws_client: Mock,
|
ws_client: Mock,
|
||||||
config: ConfigType,
|
config: ConfigType,
|
||||||
|
@ -211,6 +215,7 @@ async def _test_setup_and_signaling(
|
||||||
|
|
||||||
assert await async_setup_component(hass, DOMAIN, config)
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
await hass.async_block_till_done(wait_background_tasks=True)
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
assert issue_registry.async_get_issue(DOMAIN, "recommended_version") is None
|
||||||
config_entries = hass.config_entries.async_entries(DOMAIN)
|
config_entries = hass.config_entries.async_entries(DOMAIN)
|
||||||
assert len(config_entries) == 1
|
assert len(config_entries) == 1
|
||||||
assert config_entries[0].state == ConfigEntryState.LOADED
|
assert config_entries[0].state == ConfigEntryState.LOADED
|
||||||
|
@ -306,6 +311,7 @@ async def _test_setup_and_signaling(
|
||||||
@pytest.mark.parametrize("has_go2rtc_entry", [True, False])
|
@pytest.mark.parametrize("has_go2rtc_entry", [True, False])
|
||||||
async def test_setup_go_binary(
|
async def test_setup_go_binary(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
issue_registry: ir.IssueRegistry,
|
||||||
rest_client: AsyncMock,
|
rest_client: AsyncMock,
|
||||||
ws_client: Mock,
|
ws_client: Mock,
|
||||||
server: AsyncMock,
|
server: AsyncMock,
|
||||||
|
@ -324,7 +330,13 @@ async def test_setup_go_binary(
|
||||||
server_start.assert_called_once()
|
server_start.assert_called_once()
|
||||||
|
|
||||||
await _test_setup_and_signaling(
|
await _test_setup_and_signaling(
|
||||||
hass, rest_client, ws_client, config, after_setup, init_test_integration
|
hass,
|
||||||
|
issue_registry,
|
||||||
|
rest_client,
|
||||||
|
ws_client,
|
||||||
|
config,
|
||||||
|
after_setup,
|
||||||
|
init_test_integration,
|
||||||
)
|
)
|
||||||
|
|
||||||
await hass.async_stop()
|
await hass.async_stop()
|
||||||
|
@ -340,8 +352,9 @@ async def test_setup_go_binary(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("has_go2rtc_entry", [True, False])
|
@pytest.mark.parametrize("has_go2rtc_entry", [True, False])
|
||||||
async def test_setup_go(
|
async def test_setup(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
issue_registry: ir.IssueRegistry,
|
||||||
rest_client: AsyncMock,
|
rest_client: AsyncMock,
|
||||||
ws_client: Mock,
|
ws_client: Mock,
|
||||||
server: Mock,
|
server: Mock,
|
||||||
|
@ -359,7 +372,13 @@ async def test_setup_go(
|
||||||
server.assert_not_called()
|
server.assert_not_called()
|
||||||
|
|
||||||
await _test_setup_and_signaling(
|
await _test_setup_and_signaling(
|
||||||
hass, rest_client, ws_client, config, after_setup, init_test_integration
|
hass,
|
||||||
|
issue_registry,
|
||||||
|
rest_client,
|
||||||
|
ws_client,
|
||||||
|
config,
|
||||||
|
after_setup,
|
||||||
|
init_test_integration,
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_get_binary.assert_not_called()
|
mock_get_binary.assert_not_called()
|
||||||
|
@ -711,3 +730,30 @@ async def test_config_entry_remove(hass: HomeAssistant) -> None:
|
||||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 1
|
||||||
assert not await hass.config_entries.async_setup(config_entry.entry_id)
|
assert not await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
assert len(hass.config_entries.async_entries(DOMAIN)) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("config", [{DOMAIN: {CONF_URL: "http://localhost:1984"}}])
|
||||||
|
@pytest.mark.usefixtures("server")
|
||||||
|
async def test_setup_with_recommended_version_repair(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
issue_registry: ir.IssueRegistry,
|
||||||
|
rest_client: AsyncMock,
|
||||||
|
config: ConfigType,
|
||||||
|
) -> None:
|
||||||
|
"""Test setup integration entry fails."""
|
||||||
|
rest_client.validate_server_version.return_value = AwesomeVersion("1.9.5")
|
||||||
|
assert await async_setup_component(hass, DOMAIN, config)
|
||||||
|
await hass.async_block_till_done(wait_background_tasks=True)
|
||||||
|
|
||||||
|
# Verify the issue is created
|
||||||
|
issue = issue_registry.async_get_issue(DOMAIN, "recommended_version")
|
||||||
|
assert issue
|
||||||
|
assert issue.is_fixable is False
|
||||||
|
assert issue.is_persistent is False
|
||||||
|
assert issue.severity == ir.IssueSeverity.WARNING
|
||||||
|
assert issue.issue_id == "recommended_version"
|
||||||
|
assert issue.translation_key == "recommended_version"
|
||||||
|
assert issue.translation_placeholders == {
|
||||||
|
"recommended_version": RECOMMENDED_VERSION,
|
||||||
|
"current_version": "1.9.5",
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue