From 73bbfc7a2d7e85229da8a22c719e8a8d064dcd49 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Mon, 17 Jul 2023 13:05:58 +0200 Subject: [PATCH] Add base entity to philips js (#96756) * Create superclass for philips js * Move device info creation to coordinator --- .../components/philips_js/__init__.py | 14 +++++++++++ homeassistant/components/philips_js/entity.py | 20 +++++++++++++++ homeassistant/components/philips_js/light.py | 18 ++----------- .../components/philips_js/media_player.py | 17 ++----------- homeassistant/components/philips_js/remote.py | 16 ++---------- homeassistant/components/philips_js/switch.py | 25 +++---------------- 6 files changed, 44 insertions(+), 66 deletions(-) create mode 100644 homeassistant/components/philips_js/entity.py diff --git a/homeassistant/components/philips_js/__init__.py b/homeassistant/components/philips_js/__init__.py index 55ac33d198f..8ecc8a0e8c4 100644 --- a/homeassistant/components/philips_js/__init__.py +++ b/homeassistant/components/philips_js/__init__.py @@ -21,6 +21,7 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryAuthFailed from homeassistant.helpers.debounce import Debouncer +from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator from .const import CONF_ALLOW_NOTIFY, CONF_SYSTEM, DOMAIN @@ -101,6 +102,19 @@ class PhilipsTVDataUpdateCoordinator(DataUpdateCoordinator[None]): ), ) + @property + def device_info(self) -> DeviceInfo: + """Return device info.""" + return DeviceInfo( + identifiers={ + (DOMAIN, self.unique_id), + }, + manufacturer="Philips", + model=self.system.get("model"), + name=self.system["name"], + sw_version=self.system.get("softwareversion"), + ) + @property def system(self) -> SystemType: """Return the system descriptor.""" diff --git a/homeassistant/components/philips_js/entity.py b/homeassistant/components/philips_js/entity.py new file mode 100644 index 00000000000..c2645974f49 --- /dev/null +++ b/homeassistant/components/philips_js/entity.py @@ -0,0 +1,20 @@ +"""Base Philips js entity.""" +from __future__ import annotations + +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from . import PhilipsTVDataUpdateCoordinator + + +class PhilipsJsEntity(CoordinatorEntity[PhilipsTVDataUpdateCoordinator]): + """Base Philips js entity.""" + + _attr_has_entity_name = True + + def __init__( + self, + coordinator: PhilipsTVDataUpdateCoordinator, + ) -> None: + """Initialize light.""" + super().__init__(coordinator) + self._attr_device_info = coordinator.device_info diff --git a/homeassistant/components/philips_js/light.py b/homeassistant/components/philips_js/light.py index 8df88ff923a..9795b2303f1 100644 --- a/homeassistant/components/philips_js/light.py +++ b/homeassistant/components/philips_js/light.py @@ -18,13 +18,12 @@ from homeassistant.components.light import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util.color import color_hsv_to_RGB, color_RGB_to_hsv from . import PhilipsTVDataUpdateCoordinator from .const import DOMAIN +from .entity import PhilipsJsEntity EFFECT_PARTITION = ": " EFFECT_MODE = "Mode" @@ -134,13 +133,9 @@ def _average_pixels(data): return 0.0, 0.0, 0.0 -class PhilipsTVLightEntity( - CoordinatorEntity[PhilipsTVDataUpdateCoordinator], LightEntity -): +class PhilipsTVLightEntity(PhilipsJsEntity, LightEntity): """Representation of a Philips TV exposing the JointSpace API.""" - _attr_has_entity_name = True - def __init__( self, coordinator: PhilipsTVDataUpdateCoordinator, @@ -158,15 +153,6 @@ class PhilipsTVLightEntity( self._attr_name = "Ambilight" self._attr_unique_id = coordinator.unique_id self._attr_icon = "mdi:television-ambient-light" - self._attr_device_info = DeviceInfo( - identifiers={ - (DOMAIN, self._attr_unique_id), - }, - manufacturer="Philips", - model=coordinator.system.get("model"), - name=coordinator.system["name"], - sw_version=coordinator.system.get("softwareversion"), - ) self._update_from_coordinator() diff --git a/homeassistant/components/philips_js/media_player.py b/homeassistant/components/philips_js/media_player.py index bdd55bb2dad..6ee70b03d54 100644 --- a/homeassistant/components/philips_js/media_player.py +++ b/homeassistant/components/philips_js/media_player.py @@ -18,13 +18,12 @@ from homeassistant.components.media_player import ( from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.trigger import PluggableAction -from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import LOGGER as _LOGGER, PhilipsTVDataUpdateCoordinator from .const import DOMAIN +from .entity import PhilipsJsEntity from .helpers import async_get_turn_on_trigger SUPPORT_PHILIPS_JS = ( @@ -63,13 +62,10 @@ async def async_setup_entry( ) -class PhilipsTVMediaPlayer( - CoordinatorEntity[PhilipsTVDataUpdateCoordinator], MediaPlayerEntity -): +class PhilipsTVMediaPlayer(PhilipsJsEntity, MediaPlayerEntity): """Representation of a Philips TV exposing the JointSpace API.""" _attr_device_class = MediaPlayerDeviceClass.TV - _attr_has_entity_name = True _attr_name = None def __init__( @@ -80,15 +76,6 @@ class PhilipsTVMediaPlayer( self._tv = coordinator.api self._sources: dict[str, str] = {} self._attr_unique_id = coordinator.unique_id - self._attr_device_info = DeviceInfo( - identifiers={ - (DOMAIN, coordinator.unique_id), - }, - manufacturer="Philips", - model=coordinator.system.get("model"), - sw_version=coordinator.system.get("softwareversion"), - name=coordinator.system["name"], - ) self._attr_state = MediaPlayerState.OFF self._turn_on = PluggableAction(self.async_write_ha_state) diff --git a/homeassistant/components/philips_js/remote.py b/homeassistant/components/philips_js/remote.py index 0aa61979eb2..55e84e88599 100644 --- a/homeassistant/components/philips_js/remote.py +++ b/homeassistant/components/philips_js/remote.py @@ -13,13 +13,12 @@ from homeassistant.components.remote import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.trigger import PluggableAction -from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import LOGGER, PhilipsTVDataUpdateCoordinator from .const import DOMAIN +from .entity import PhilipsJsEntity from .helpers import async_get_turn_on_trigger @@ -33,11 +32,9 @@ async def async_setup_entry( async_add_entities([PhilipsTVRemote(coordinator)]) -class PhilipsTVRemote(CoordinatorEntity[PhilipsTVDataUpdateCoordinator], RemoteEntity): +class PhilipsTVRemote(PhilipsJsEntity, RemoteEntity): """Device that sends commands.""" - _attr_has_entity_name = True - def __init__( self, coordinator: PhilipsTVDataUpdateCoordinator, @@ -47,15 +44,6 @@ class PhilipsTVRemote(CoordinatorEntity[PhilipsTVDataUpdateCoordinator], RemoteE self._tv = coordinator.api self._attr_name = "Remote" self._attr_unique_id = coordinator.unique_id - self._attr_device_info = DeviceInfo( - identifiers={ - (DOMAIN, coordinator.unique_id), - }, - manufacturer="Philips", - model=coordinator.system.get("model"), - name=coordinator.system["name"], - sw_version=coordinator.system.get("softwareversion"), - ) self._turn_on = PluggableAction(self.async_write_ha_state) async def async_added_to_hass(self) -> None: diff --git a/homeassistant/components/philips_js/switch.py b/homeassistant/components/philips_js/switch.py index b66fd3296d9..a950e606566 100644 --- a/homeassistant/components/philips_js/switch.py +++ b/homeassistant/components/philips_js/switch.py @@ -6,12 +6,11 @@ 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 import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.update_coordinator import CoordinatorEntity from . import PhilipsTVDataUpdateCoordinator from .const import DOMAIN +from .entity import PhilipsJsEntity HUE_POWER_OFF = "Off" HUE_POWER_ON = "On" @@ -33,13 +32,9 @@ async def async_setup_entry( async_add_entities([PhilipsTVAmbilightHueSwitch(coordinator)]) -class PhilipsTVScreenSwitch( - CoordinatorEntity[PhilipsTVDataUpdateCoordinator], SwitchEntity -): +class PhilipsTVScreenSwitch(PhilipsJsEntity, SwitchEntity): """A Philips TV screen state switch.""" - _attr_has_entity_name = True - def __init__( self, coordinator: PhilipsTVDataUpdateCoordinator, @@ -51,11 +46,6 @@ class PhilipsTVScreenSwitch( self._attr_name = "Screen state" self._attr_icon = "mdi:television-shimmer" self._attr_unique_id = f"{coordinator.unique_id}_screenstate" - self._attr_device_info = DeviceInfo( - identifiers={ - (DOMAIN, coordinator.unique_id), - } - ) @property def available(self) -> bool: @@ -80,9 +70,7 @@ class PhilipsTVScreenSwitch( await self.coordinator.api.setScreenState("Off") -class PhilipsTVAmbilightHueSwitch( - CoordinatorEntity[PhilipsTVDataUpdateCoordinator], SwitchEntity -): +class PhilipsTVAmbilightHueSwitch(PhilipsJsEntity, SwitchEntity): """A Philips TV Ambi+Hue switch.""" def __init__( @@ -93,14 +81,9 @@ class PhilipsTVAmbilightHueSwitch( super().__init__(coordinator) - self._attr_name = f"{coordinator.system['name']} Ambilight+Hue" + self._attr_name = "Ambilight+Hue" self._attr_icon = "mdi:television-ambient-light" self._attr_unique_id = f"{coordinator.unique_id}_ambi_hue" - self._attr_device_info = DeviceInfo( - identifiers={ - (DOMAIN, coordinator.unique_id), - } - ) @property def available(self) -> bool: