Store Philips TV runtime data in config entry (#116952)
Co-authored-by: Maciej Bieniek <478555+bieniu@users.noreply.github.com>
This commit is contained in:
parent
2cc916db6d
commit
16d86e5d4c
9 changed files with 191 additions and 44 deletions
|
@ -42,8 +42,10 @@ PLATFORMS = [
|
||||||
|
|
||||||
LOGGER = logging.getLogger(__name__)
|
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."""
|
"""Set up Philips TV from a config entry."""
|
||||||
|
|
||||||
system: SystemType | None = entry.data.get(CONF_SYSTEM)
|
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}
|
data = {**entry.data, CONF_SYSTEM: actual_system}
|
||||||
hass.config_entries.async_update_entry(entry, data=data)
|
hass.config_entries.async_update_entry(entry, data=data)
|
||||||
|
|
||||||
hass.data.setdefault(DOMAIN, {})
|
entry.runtime_data = coordinator
|
||||||
hass.data[DOMAIN][entry.entry_id] = coordinator
|
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
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
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_update_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
async def async_update_entry(hass: HomeAssistant, entry: PhilipsTVConfigEntry) -> None:
|
||||||
"""Update options."""
|
"""Update options."""
|
||||||
await hass.config_entries.async_reload(entry.entry_id)
|
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 a config entry."""
|
||||||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
return await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||||
if unload_ok:
|
|
||||||
hass.data[DOMAIN].pop(entry.entry_id)
|
|
||||||
|
|
||||||
return unload_ok
|
|
||||||
|
|
||||||
|
|
||||||
class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enforce-coordinator-module
|
class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): # pylint: disable=hass-enforce-coordinator-module
|
||||||
|
|
|
@ -10,12 +10,10 @@ from homeassistant.components.binary_sensor import (
|
||||||
BinarySensorEntity,
|
BinarySensorEntity,
|
||||||
BinarySensorEntityDescription,
|
BinarySensorEntityDescription,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import PhilipsTVDataUpdateCoordinator
|
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
|
||||||
from .const import DOMAIN
|
|
||||||
from .entity import PhilipsJsEntity
|
from .entity import PhilipsJsEntity
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,13 +40,11 @@ DESCRIPTIONS = (
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: PhilipsTVConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the configuration entry."""
|
"""Set up the configuration entry."""
|
||||||
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][
|
coordinator = config_entry.runtime_data
|
||||||
config_entry.entry_id
|
|
||||||
]
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
coordinator.api.json_feature_supported("recordings", "List")
|
coordinator.api.json_feature_supported("recordings", "List")
|
||||||
|
|
|
@ -5,11 +5,9 @@ from __future__ import annotations
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.diagnostics import async_redact_data
|
from homeassistant.components.diagnostics import async_redact_data
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import PhilipsTVDataUpdateCoordinator
|
from . import PhilipsTVConfigEntry
|
||||||
from .const import DOMAIN
|
|
||||||
|
|
||||||
TO_REDACT = {
|
TO_REDACT = {
|
||||||
"serialnumber_encrypted",
|
"serialnumber_encrypted",
|
||||||
|
@ -24,10 +22,10 @@ TO_REDACT = {
|
||||||
|
|
||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
hass: HomeAssistant, entry: ConfigEntry
|
hass: HomeAssistant, entry: PhilipsTVConfigEntry
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
"""Return diagnostics for a config entry."""
|
"""Return diagnostics for a config entry."""
|
||||||
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id]
|
coordinator = entry.runtime_data
|
||||||
api = coordinator.api
|
api = coordinator.api
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -16,14 +16,12 @@ from homeassistant.components.light import (
|
||||||
LightEntity,
|
LightEntity,
|
||||||
LightEntityFeature,
|
LightEntityFeature,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.util.color import color_hsv_to_RGB, color_RGB_to_hsv
|
from homeassistant.util.color import color_hsv_to_RGB, color_RGB_to_hsv
|
||||||
|
|
||||||
from . import PhilipsTVDataUpdateCoordinator
|
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
|
||||||
from .const import DOMAIN
|
|
||||||
from .entity import PhilipsJsEntity
|
from .entity import PhilipsJsEntity
|
||||||
|
|
||||||
EFFECT_PARTITION = ": "
|
EFFECT_PARTITION = ": "
|
||||||
|
@ -35,11 +33,11 @@ EFFECT_EXPERT_STYLES = {"FOLLOW_AUDIO", "FOLLOW_COLOR", "Lounge light"}
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: PhilipsTVConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the configuration entry."""
|
"""Set up the configuration entry."""
|
||||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = config_entry.runtime_data
|
||||||
async_add_entities([PhilipsTVLightEntity(coordinator)])
|
async_add_entities([PhilipsTVLightEntity(coordinator)])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -16,14 +16,12 @@ from homeassistant.components.media_player import (
|
||||||
MediaPlayerState,
|
MediaPlayerState,
|
||||||
MediaType,
|
MediaType,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.trigger import PluggableAction
|
from homeassistant.helpers.trigger import PluggableAction
|
||||||
|
|
||||||
from . import LOGGER as _LOGGER, PhilipsTVDataUpdateCoordinator
|
from . import LOGGER as _LOGGER, PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
|
||||||
from .const import DOMAIN
|
|
||||||
from .entity import PhilipsJsEntity
|
from .entity import PhilipsJsEntity
|
||||||
from .helpers import async_get_turn_on_trigger
|
from .helpers import async_get_turn_on_trigger
|
||||||
|
|
||||||
|
@ -49,11 +47,11 @@ def _inverted(data):
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: PhilipsTVConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the configuration entry."""
|
"""Set up the configuration entry."""
|
||||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = config_entry.runtime_data
|
||||||
async_add_entities(
|
async_add_entities(
|
||||||
[
|
[
|
||||||
PhilipsTVMediaPlayer(
|
PhilipsTVMediaPlayer(
|
||||||
|
|
|
@ -12,24 +12,22 @@ from homeassistant.components.remote import (
|
||||||
DEFAULT_DELAY_SECS,
|
DEFAULT_DELAY_SECS,
|
||||||
RemoteEntity,
|
RemoteEntity,
|
||||||
)
|
)
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.trigger import PluggableAction
|
from homeassistant.helpers.trigger import PluggableAction
|
||||||
|
|
||||||
from . import LOGGER, PhilipsTVDataUpdateCoordinator
|
from . import LOGGER, PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
|
||||||
from .const import DOMAIN
|
|
||||||
from .entity import PhilipsJsEntity
|
from .entity import PhilipsJsEntity
|
||||||
from .helpers import async_get_turn_on_trigger
|
from .helpers import async_get_turn_on_trigger
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: PhilipsTVConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the configuration entry."""
|
"""Set up the configuration entry."""
|
||||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
coordinator = config_entry.runtime_data
|
||||||
async_add_entities([PhilipsTVRemote(coordinator)])
|
async_add_entities([PhilipsTVRemote(coordinator)])
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,10 @@ from __future__ import annotations
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from homeassistant.components.switch import SwitchEntity
|
from homeassistant.components.switch import SwitchEntity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import PhilipsTVDataUpdateCoordinator
|
from . import PhilipsTVConfigEntry, PhilipsTVDataUpdateCoordinator
|
||||||
from .const import DOMAIN
|
|
||||||
from .entity import PhilipsJsEntity
|
from .entity import PhilipsJsEntity
|
||||||
|
|
||||||
HUE_POWER_OFF = "Off"
|
HUE_POWER_OFF = "Off"
|
||||||
|
@ -19,13 +17,11 @@ HUE_POWER_ON = "On"
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
config_entry: ConfigEntry,
|
config_entry: PhilipsTVConfigEntry,
|
||||||
async_add_entities: AddEntitiesCallback,
|
async_add_entities: AddEntitiesCallback,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Set up the configuration entry."""
|
"""Set up the configuration entry."""
|
||||||
coordinator: PhilipsTVDataUpdateCoordinator = hass.data[DOMAIN][
|
coordinator = config_entry.runtime_data
|
||||||
config_entry.entry_id
|
|
||||||
]
|
|
||||||
|
|
||||||
async_add_entities([PhilipsTVScreenSwitch(coordinator)])
|
async_add_entities([PhilipsTVScreenSwitch(coordinator)])
|
||||||
|
|
||||||
|
|
100
tests/components/philips_js/snapshots/test_diagnostics.ambr
Normal file
100
tests/components/philips_js/snapshots/test_diagnostics.ambr
Normal 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,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
# ---
|
66
tests/components/philips_js/test_diagnostics.py
Normal file
66
tests/components/philips_js/test_diagnostics.py
Normal 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"))
|
Loading…
Add table
Reference in a new issue