Store Philips TV runtime data in config entry (#116952)

Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
pull/116991/head^2
Maciej Bieniek 2024-05-07 14:10:44 +02:00 committed by GitHub
parent 2cc916db6d
commit 16d86e5d4c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 191 additions and 44 deletions

View File

@ -42,8 +42,10 @@ PLATFORMS = [
LOGGER = logging.getLogger(__name__)
PhilipsTVConfigEntry = ConfigEntry["PhilipsTVDataUpdateCoordinator"]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_setup_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> bool:
"""Set up Philips TV from a config entry."""
system: SystemType | None = entry.data.get(CONF_SYSTEM)
@ -62,8 +64,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
data = {**entry.data, CONF_SYSTEM: actual_system}
hass.config_entries.async_update_entry(entry, data=data)
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = coordinator
entry.runtime_data = coordinator
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@ -72,18 +73,14 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True
async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
async def async_update_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> None:
"""Update options."""
await hass.config_entries.async_reload(entry.entry_id)
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_unload_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> bool:
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enforce-coordinator-module

View File

@ -10,12 +10,10 @@ from homeassistant.components.binary_sensor import (
BinarySensorEntity,
BinarySensorEntityDescription,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
from .entity import PhilipsJsEntity
@ -42,13 +40,11 @@ DESCRIPTIONS = (
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: PhilipsTVConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the configuration entry."""
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][
config_entry.entry_id
]
coordinator = config_entry.runtime_data
if (
coordinator.api.json_feature_supported("recordings", "List")

View File

@ -5,11 +5,9 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import PhilipsTVConfigEntry
TO_REDACT = {
"serialnumber_encrypted",
@ -24,10 +22,10 @@ TO_REDACT = {
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, entry: ConfigEntry
hass: HomeAssistant, entry: PhilipsTVConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
coordinator = entry.runtime_data
api = coordinator.api
return {

View File

@ -16,14 +16,12 @@ from homeassistant.components.light import (
LightEntity,
LightEntityFeature,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.util.color import color_hsv_to_RGB, color_RGB_to_hsv
from . import PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
from .entity import PhilipsJsEntity
EFFECT_PARTITION = ": "
@ -35,11 +33,11 @@ EFFECT_EXPERT_STYLES = {"FOLLOW_AUDIO", "FOLLOW_COLOR", "Lounge light"}
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: PhilipsTVConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the configuration entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
coordinator = config_entry.runtime_data
async_add_entities([PhilipsTVLightEntity(coordinator)])

View File

@ -16,14 +16,12 @@ from homeassistant.components.media_player import (
MediaPlayerState,
MediaType,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.trigger import PluggableAction
from . import LOGGER as _LOGGER, PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import LOGGER as _LOGGER, PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
from .entity import PhilipsJsEntity
from .helpers import async_get_turn_on_trigger
@ -49,11 +47,11 @@ def _inverted(data):
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: PhilipsTVConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the configuration entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
coordinator = config_entry.runtime_data
async_add_entities(
[
PhilipsTVMediaPlayer(

View File

@ -12,24 +12,22 @@ from homeassistant.components.remote import (
DEFAULT_DELAY_SECS,
RemoteEntity,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.trigger import PluggableAction
from . import LOGGER, PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import LOGGER, PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
from .entity import PhilipsJsEntity
from .helpers import async_get_turn_on_trigger
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: PhilipsTVConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the configuration entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id]
coordinator = config_entry.runtime_data
async_add_entities([PhilipsTVRemote(coordinator)])

View File

@ -5,12 +5,10 @@ from __future__ import annotations
from typing import Any
from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import PhilipsTVDataUpdateCoordinator
from .const import DOMAIN
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
from .entity import PhilipsJsEntity
HUE_POWER_OFF = "Off"
@ -19,13 +17,11 @@ HUE_POWER_ON = "On"
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
config_entry: PhilipsTVConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the configuration entry."""
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][
config_entry.entry_id
]
coordinator = config_entry.runtime_data
async_add_entities([PhilipsTVScreenSwitch(coordinator)])

View File

@ -0,0 +1,100 @@
# serializer version: 1
# name: test_entry_diagnostics
dict({
'data': dict({
'ambilight_cached': dict({
}),
'ambilight_current_configuration': None,
'ambilight_measured': None,
'ambilight_mode_raw': 'internal',
'ambilight_modes': list([
'internal',
'manual',
'expert',
'lounge',
]),
'ambilight_power': 'On',
'ambilight_power_raw': dict({
'power': 'On',
}),
'ambilight_processed': None,
'ambilight_styles': dict({
}),
'ambilight_topology': None,
'application': None,
'applications': dict({
}),
'channel': None,
'channel_lists': dict({
'all': dict({
'Channel': list([
]),
'id': 'all',
'installCountry': 'Poland',
'listType': 'MixedSources',
'medium': 'mixed',
'operator': 'None',
'version': 2,
}),
}),
'channels': dict({
}),
'context': dict({
'data': 'NA',
'level1': 'NA',
'level2': 'NA',
'level3': 'NA',
}),
'favorite_lists': dict({
'1': dict({
'channels': list([
]),
'id': '1',
'medium': 'mixed',
'name': 'Favourites 1',
'type': 'MixedSources',
'version': '60',
}),
}),
'on': True,
'powerstate': None,
'screenstate': 'On',
'source_id': None,
'sources': dict({
}),
'system': dict({
'country': 'Sweden',
'menulanguage': 'English',
'model': 'modelname',
'name': 'Philips TV',
'serialnumber': '**REDACTED**',
'softwareversion': 'abcd',
}),
}),
'entry': dict({
'data': dict({
'api_version': 1,
'host': '1.1.1.1',
'system': dict({
'country': 'Sweden',
'menulanguage': 'English',
'model': 'modelname',
'name': 'Philips TV',
'serialnumber': '**REDACTED**',
'softwareversion': 'abcd',
}),
}),
'disabled_by': None,
'domain': 'philips_js',
'minor_version': 1,
'options': dict({
}),
'pref_disable_new_entities': False,
'pref_disable_polling': False,
'source': 'user',
'title': '**REDACTED**',
'unique_id': '**REDACTED**',
'version': 1,
}),
})
# ---

View File

@ -0,0 +1,66 @@
"""Test the Philips TV diagnostics platform."""
from unittest.mock import AsyncMock
from haphilipsjs.typing import ChannelListType, ContextType, FavoriteListType
from syrupy import SnapshotAssertion
from syrupy.filters import props
from homeassistant.core import HomeAssistant
from tests.common import MockConfigEntry
from tests.components.diagnostics import get_diagnostics_for_config_entry
from tests.typing import ClientSessionGenerator
TV_CONTEXT = ContextType(level1="NA", level2="NA", level3="NA", data="NA")
TV_CHANNEL_LISTS = {
"all": ChannelListType(
version=2,
id="all",
listType="MixedSources",
medium="mixed",
operator="None",
installCountry="Poland",
Channel=[],
)
}
TV_FAVORITE_LISTS = {
"1": FavoriteListType(
version="60",
id="1",
type="MixedSources",
medium="mixed",
name="Favourites 1",
channels=[],
)
}
async def test_entry_diagnostics(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
snapshot: SnapshotAssertion,
mock_config_entry: MockConfigEntry,
mock_tv: AsyncMock,
) -> None:
"""Test config entry diagnostics."""
mock_tv.context = TV_CONTEXT
mock_tv.ambilight_topology = None
mock_tv.ambilight_mode_raw = "internal"
mock_tv.ambilight_modes = ["internal", "manual", "expert", "lounge"]
mock_tv.ambilight_power_raw = {"power": "On"}
mock_tv.ambilight_power = "On"
mock_tv.ambilight_measured = None
mock_tv.ambilight_processed = None
mock_tv.screenstate = "On"
mock_tv.channel = None
mock_tv.channel_lists = TV_CHANNEL_LISTS
mock_tv.favorite_lists = TV_FAVORITE_LISTS
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
result = await get_diagnostics_for_config_entry(
hass, hass_client, mock_config_entry
)
assert result == snapshot(exclude=props("entry_id"))