mirror of
https://github.com/home-assistant/core.git
synced 2025-07-09 22:37:11 +00:00
Refactor Remote class in panasonic_viera (#34911)
This commit is contained in:
parent
bd72ddda3c
commit
4e55fa6c5c
@ -531,7 +531,6 @@ omit =
|
|||||||
homeassistant/components/osramlightify/light.py
|
homeassistant/components/osramlightify/light.py
|
||||||
homeassistant/components/otp/sensor.py
|
homeassistant/components/otp/sensor.py
|
||||||
homeassistant/components/panasonic_bluray/media_player.py
|
homeassistant/components/panasonic_bluray/media_player.py
|
||||||
homeassistant/components/panasonic_viera/__init__.py
|
|
||||||
homeassistant/components/panasonic_viera/media_player.py
|
homeassistant/components/panasonic_viera/media_player.py
|
||||||
homeassistant/components/pandora/media_player.py
|
homeassistant/components/pandora/media_player.py
|
||||||
homeassistant/components/pcal9535a/*
|
homeassistant/components/pcal9535a/*
|
||||||
|
@ -1,13 +1,29 @@
|
|||||||
"""The Panasonic Viera integration."""
|
"""The Panasonic Viera integration."""
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from functools import partial
|
||||||
|
import logging
|
||||||
|
from urllib.request import URLError
|
||||||
|
|
||||||
|
from panasonic_viera import EncryptionRequired, Keys, RemoteControl, SOAPError
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT
|
from homeassistant.config_entries import SOURCE_IMPORT
|
||||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT
|
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.script import Script
|
||||||
|
|
||||||
from .const import CONF_ON_ACTION, DEFAULT_NAME, DEFAULT_PORT, DOMAIN
|
from .const import (
|
||||||
|
ATTR_REMOTE,
|
||||||
|
CONF_APP_ID,
|
||||||
|
CONF_ENCRYPTION_KEY,
|
||||||
|
CONF_ON_ACTION,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DEFAULT_PORT,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.Schema(
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
{
|
{
|
||||||
@ -28,7 +44,7 @@ CONFIG_SCHEMA = vol.Schema(
|
|||||||
extra=vol.ALLOW_EXTRA,
|
extra=vol.ALLOW_EXTRA,
|
||||||
)
|
)
|
||||||
|
|
||||||
PLATFORMS = ["media_player"]
|
PLATFORMS = [MEDIA_PLAYER_DOMAIN]
|
||||||
|
|
||||||
|
|
||||||
async def async_setup(hass, config):
|
async def async_setup(hass, config):
|
||||||
@ -49,6 +65,27 @@ async def async_setup(hass, config):
|
|||||||
async def async_setup_entry(hass, config_entry):
|
async def async_setup_entry(hass, config_entry):
|
||||||
"""Set up Panasonic Viera from a config entry."""
|
"""Set up Panasonic Viera from a config entry."""
|
||||||
|
|
||||||
|
panasonic_viera_data = hass.data.setdefault(DOMAIN, {})
|
||||||
|
|
||||||
|
config = config_entry.data
|
||||||
|
|
||||||
|
host = config[CONF_HOST]
|
||||||
|
port = config[CONF_PORT]
|
||||||
|
|
||||||
|
on_action = config[CONF_ON_ACTION]
|
||||||
|
if on_action is not None:
|
||||||
|
on_action = Script(hass, on_action)
|
||||||
|
|
||||||
|
params = {}
|
||||||
|
if CONF_APP_ID in config and CONF_ENCRYPTION_KEY in config:
|
||||||
|
params["app_id"] = config[CONF_APP_ID]
|
||||||
|
params["encryption_key"] = config[CONF_ENCRYPTION_KEY]
|
||||||
|
|
||||||
|
remote = Remote(hass, host, port, on_action, **params)
|
||||||
|
await remote.async_create_remote_control(during_setup=True)
|
||||||
|
|
||||||
|
panasonic_viera_data[config_entry.entry_id] = {ATTR_REMOTE: remote}
|
||||||
|
|
||||||
for component in PLATFORMS:
|
for component in PLATFORMS:
|
||||||
hass.async_create_task(
|
hass.async_create_task(
|
||||||
hass.config_entries.async_forward_entry_setup(config_entry, component)
|
hass.config_entries.async_forward_entry_setup(config_entry, component)
|
||||||
@ -59,7 +96,7 @@ async def async_setup_entry(hass, config_entry):
|
|||||||
|
|
||||||
async def async_unload_entry(hass, config_entry):
|
async def async_unload_entry(hass, config_entry):
|
||||||
"""Unload a config entry."""
|
"""Unload a config entry."""
|
||||||
return all(
|
unload_ok = all(
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
*[
|
*[
|
||||||
hass.config_entries.async_forward_entry_unload(config_entry, component)
|
hass.config_entries.async_forward_entry_unload(config_entry, component)
|
||||||
@ -67,3 +104,135 @@ async def async_unload_entry(hass, config_entry):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if unload_ok:
|
||||||
|
hass.data[DOMAIN].pop(config_entry.entry_id)
|
||||||
|
|
||||||
|
return unload_ok
|
||||||
|
|
||||||
|
|
||||||
|
class Remote:
|
||||||
|
"""The Remote class. It stores the TV properties and the remote control connection itself."""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self, hass, host, port, on_action=None, app_id=None, encryption_key=None,
|
||||||
|
):
|
||||||
|
"""Initialize the Remote class."""
|
||||||
|
self._hass = hass
|
||||||
|
|
||||||
|
self._host = host
|
||||||
|
self._port = port
|
||||||
|
|
||||||
|
self._on_action = on_action
|
||||||
|
|
||||||
|
self._app_id = app_id
|
||||||
|
self._encryption_key = encryption_key
|
||||||
|
|
||||||
|
self.state = None
|
||||||
|
self.available = False
|
||||||
|
self.volume = 0
|
||||||
|
self.muted = False
|
||||||
|
self.playing = True
|
||||||
|
|
||||||
|
self._control = None
|
||||||
|
|
||||||
|
async def async_create_remote_control(self, during_setup=False):
|
||||||
|
"""Create remote control."""
|
||||||
|
control_existed = self._control is not None
|
||||||
|
try:
|
||||||
|
params = {}
|
||||||
|
if self._app_id and self._encryption_key:
|
||||||
|
params["app_id"] = self._app_id
|
||||||
|
params["encryption_key"] = self._encryption_key
|
||||||
|
|
||||||
|
self._control = await self._hass.async_add_executor_job(
|
||||||
|
partial(RemoteControl, self._host, self._port, **params)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.state = STATE_ON
|
||||||
|
self.available = True
|
||||||
|
except (TimeoutError, URLError, SOAPError, OSError) as err:
|
||||||
|
if control_existed or during_setup:
|
||||||
|
_LOGGER.debug("Could not establish remote connection: %s", err)
|
||||||
|
|
||||||
|
self._control = None
|
||||||
|
self.state = STATE_OFF
|
||||||
|
self.available = self._on_action is not None
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
if control_existed or during_setup:
|
||||||
|
_LOGGER.exception("An unknown error occurred: %s", err)
|
||||||
|
self._control = None
|
||||||
|
self.state = STATE_OFF
|
||||||
|
self.available = self._on_action is not None
|
||||||
|
|
||||||
|
async def async_update(self):
|
||||||
|
"""Update device data."""
|
||||||
|
if self._control is None:
|
||||||
|
await self.async_create_remote_control()
|
||||||
|
return
|
||||||
|
|
||||||
|
await self._handle_errors(self._update)
|
||||||
|
|
||||||
|
def _update(self):
|
||||||
|
"""Retrieve the latest data."""
|
||||||
|
self.muted = self._control.get_mute()
|
||||||
|
self.volume = self._control.get_volume() / 100
|
||||||
|
|
||||||
|
self.state = STATE_ON
|
||||||
|
self.available = True
|
||||||
|
|
||||||
|
async def async_send_key(self, key):
|
||||||
|
"""Send a key to the TV and handle exceptions."""
|
||||||
|
try:
|
||||||
|
key = getattr(Keys, key)
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
key = getattr(key, "value", key)
|
||||||
|
|
||||||
|
await self._handle_errors(self._control.send_key, key)
|
||||||
|
|
||||||
|
async def async_turn_on(self):
|
||||||
|
"""Turn on the TV."""
|
||||||
|
if self._on_action is not None:
|
||||||
|
await self._on_action.async_run()
|
||||||
|
self.state = STATE_ON
|
||||||
|
elif self.state != STATE_ON:
|
||||||
|
await self.async_send_key(Keys.power)
|
||||||
|
self.state = STATE_ON
|
||||||
|
|
||||||
|
async def async_turn_off(self):
|
||||||
|
"""Turn off the TV."""
|
||||||
|
if self.state != STATE_OFF:
|
||||||
|
await self.async_send_key(Keys.power)
|
||||||
|
self.state = STATE_OFF
|
||||||
|
await self.async_update()
|
||||||
|
|
||||||
|
async def async_set_mute(self, enable):
|
||||||
|
"""Set mute based on 'enable'."""
|
||||||
|
await self._handle_errors(self._control.set_mute, enable)
|
||||||
|
|
||||||
|
async def async_set_volume(self, volume):
|
||||||
|
"""Set volume level, range 0..1."""
|
||||||
|
volume = int(volume * 100)
|
||||||
|
await self._handle_errors(self._control.set_volume, volume)
|
||||||
|
|
||||||
|
async def async_play_media(self, media_type, media_id):
|
||||||
|
"""Play media."""
|
||||||
|
_LOGGER.debug("Play media: %s (%s)", media_id, media_type)
|
||||||
|
await self._handle_errors(self._control.open_webpage, media_id)
|
||||||
|
|
||||||
|
async def _handle_errors(self, func, *args):
|
||||||
|
"""Handle errors from func, set available and reconnect if needed."""
|
||||||
|
try:
|
||||||
|
return await self._hass.async_add_executor_job(func, *args)
|
||||||
|
except EncryptionRequired:
|
||||||
|
_LOGGER.error(
|
||||||
|
"The connection couldn't be encrypted. Please reconfigure your TV"
|
||||||
|
)
|
||||||
|
except (TimeoutError, URLError, SOAPError, OSError):
|
||||||
|
self.state = STATE_OFF
|
||||||
|
self.available = self._on_action is not None
|
||||||
|
await self.async_create_remote_control()
|
||||||
|
except Exception as err: # pylint: disable=broad-except
|
||||||
|
_LOGGER.exception("An unknown error occurred: %s", err)
|
||||||
|
self.state = STATE_OFF
|
||||||
|
self.available = self._on_action is not None
|
||||||
|
@ -10,6 +10,8 @@ CONF_ENCRYPTION_KEY = "encryption_key"
|
|||||||
DEFAULT_NAME = "Panasonic Viera TV"
|
DEFAULT_NAME = "Panasonic Viera TV"
|
||||||
DEFAULT_PORT = 55000
|
DEFAULT_PORT = 55000
|
||||||
|
|
||||||
|
ATTR_REMOTE = "remote"
|
||||||
|
|
||||||
ERROR_NOT_CONNECTED = "not_connected"
|
ERROR_NOT_CONNECTED = "not_connected"
|
||||||
ERROR_INVALID_PIN_CODE = "invalid_pin_code"
|
ERROR_INVALID_PIN_CODE = "invalid_pin_code"
|
||||||
|
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
"""Support for interface with a Panasonic Viera TV."""
|
"""Media player support for Panasonic Viera TV."""
|
||||||
from functools import partial
|
|
||||||
import logging
|
import logging
|
||||||
from urllib.request import URLError
|
|
||||||
|
|
||||||
from panasonic_viera import EncryptionRequired, Keys, RemoteControl, SOAPError
|
from panasonic_viera import Keys
|
||||||
|
|
||||||
from homeassistant.components.media_player import MediaPlayerEntity
|
from homeassistant.components.media_player import MediaPlayerEntity
|
||||||
from homeassistant.components.media_player.const import (
|
from homeassistant.components.media_player.const import (
|
||||||
@ -20,10 +18,9 @@ from homeassistant.components.media_player.const import (
|
|||||||
SUPPORT_VOLUME_SET,
|
SUPPORT_VOLUME_SET,
|
||||||
SUPPORT_VOLUME_STEP,
|
SUPPORT_VOLUME_STEP,
|
||||||
)
|
)
|
||||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON
|
from homeassistant.const import CONF_NAME
|
||||||
from homeassistant.helpers.script import Script
|
|
||||||
|
|
||||||
from .const import CONF_APP_ID, CONF_ENCRYPTION_KEY, CONF_ON_ACTION
|
from .const import ATTR_REMOTE, DOMAIN
|
||||||
|
|
||||||
SUPPORT_VIERATV = (
|
SUPPORT_VIERATV = (
|
||||||
SUPPORT_PAUSE
|
SUPPORT_PAUSE
|
||||||
@ -47,42 +44,25 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||||||
|
|
||||||
config = config_entry.data
|
config = config_entry.data
|
||||||
|
|
||||||
host = config[CONF_HOST]
|
remote = hass.data[DOMAIN][config_entry.entry_id][ATTR_REMOTE]
|
||||||
port = config[CONF_PORT]
|
|
||||||
name = config[CONF_NAME]
|
name = config[CONF_NAME]
|
||||||
|
|
||||||
on_action = config[CONF_ON_ACTION]
|
tv_device = PanasonicVieraTVEntity(remote, name)
|
||||||
if on_action is not None:
|
|
||||||
on_action = Script(hass, on_action)
|
|
||||||
|
|
||||||
params = {}
|
|
||||||
if CONF_APP_ID in config and CONF_ENCRYPTION_KEY in config:
|
|
||||||
params["app_id"] = config[CONF_APP_ID]
|
|
||||||
params["encryption_key"] = config[CONF_ENCRYPTION_KEY]
|
|
||||||
|
|
||||||
remote = Remote(hass, host, port, on_action, **params)
|
|
||||||
await remote.async_create_remote_control(during_setup=True)
|
|
||||||
|
|
||||||
tv_device = PanasonicVieraTVDevice(remote, name)
|
|
||||||
|
|
||||||
async_add_entities([tv_device])
|
async_add_entities([tv_device])
|
||||||
|
|
||||||
|
|
||||||
class PanasonicVieraTVDevice(MediaPlayerEntity):
|
class PanasonicVieraTVEntity(MediaPlayerEntity):
|
||||||
"""Representation of a Panasonic Viera TV."""
|
"""Representation of a Panasonic Viera TV."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, remote, name, uuid=None):
|
||||||
self, remote, name, uuid=None,
|
"""Initialize the entity."""
|
||||||
):
|
|
||||||
"""Initialize the Panasonic device."""
|
|
||||||
# Save a reference to the imported class
|
|
||||||
self._remote = remote
|
self._remote = remote
|
||||||
self._name = name
|
self._name = name
|
||||||
self._uuid = uuid
|
self._uuid = uuid
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def unique_id(self) -> str:
|
def unique_id(self):
|
||||||
"""Return the unique ID of this Viera TV."""
|
"""Return the unique ID of the device."""
|
||||||
return self._uuid
|
return self._uuid
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -97,7 +77,7 @@ class PanasonicVieraTVDevice(MediaPlayerEntity):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self):
|
def available(self):
|
||||||
"""Return if True the device is available."""
|
"""Return True if the device is available."""
|
||||||
return self._remote.available
|
return self._remote.available
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -176,125 +156,8 @@ class PanasonicVieraTVDevice(MediaPlayerEntity):
|
|||||||
|
|
||||||
async def async_play_media(self, media_type, media_id, **kwargs):
|
async def async_play_media(self, media_type, media_id, **kwargs):
|
||||||
"""Play media."""
|
"""Play media."""
|
||||||
await self._remote.async_play_media(media_type, media_id)
|
|
||||||
|
|
||||||
|
|
||||||
class Remote:
|
|
||||||
"""The Remote class. It stores the TV properties and the remote control connection itself."""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self, hass, host, port, on_action=None, app_id=None, encryption_key=None,
|
|
||||||
):
|
|
||||||
"""Initialize the Remote class."""
|
|
||||||
self._hass = hass
|
|
||||||
|
|
||||||
self._host = host
|
|
||||||
self._port = port
|
|
||||||
|
|
||||||
self._on_action = on_action
|
|
||||||
|
|
||||||
self._app_id = app_id
|
|
||||||
self._encryption_key = encryption_key
|
|
||||||
|
|
||||||
self.state = None
|
|
||||||
self.available = False
|
|
||||||
self.volume = 0
|
|
||||||
self.muted = False
|
|
||||||
self.playing = True
|
|
||||||
|
|
||||||
self._control = None
|
|
||||||
|
|
||||||
async def async_create_remote_control(self, during_setup=False):
|
|
||||||
"""Create remote control."""
|
|
||||||
control_existed = self._control is not None
|
|
||||||
try:
|
|
||||||
params = {}
|
|
||||||
if self._app_id and self._encryption_key:
|
|
||||||
params["app_id"] = self._app_id
|
|
||||||
params["encryption_key"] = self._encryption_key
|
|
||||||
|
|
||||||
self._control = await self._hass.async_add_executor_job(
|
|
||||||
partial(RemoteControl, self._host, self._port, **params)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.state = STATE_ON
|
|
||||||
self.available = True
|
|
||||||
except (TimeoutError, URLError, SOAPError, OSError) as err:
|
|
||||||
if control_existed or during_setup:
|
|
||||||
_LOGGER.error("Could not establish remote connection: %s", err)
|
|
||||||
|
|
||||||
self._control = None
|
|
||||||
self.state = STATE_OFF
|
|
||||||
self.available = self._on_action is not None
|
|
||||||
except Exception as err: # pylint: disable=broad-except
|
|
||||||
if control_existed or during_setup:
|
|
||||||
_LOGGER.exception("An unknown error occurred: %s", err)
|
|
||||||
self._control = None
|
|
||||||
self.state = STATE_OFF
|
|
||||||
self.available = self._on_action is not None
|
|
||||||
|
|
||||||
async def async_update(self):
|
|
||||||
"""Update device data."""
|
|
||||||
if self._control is None:
|
|
||||||
await self.async_create_remote_control()
|
|
||||||
return
|
|
||||||
|
|
||||||
await self._handle_errors(self._update)
|
|
||||||
|
|
||||||
async def _update(self):
|
|
||||||
"""Retrieve the latest data."""
|
|
||||||
self.muted = self._control.get_mute()
|
|
||||||
self.volume = self._control.get_volume() / 100
|
|
||||||
|
|
||||||
self.state = STATE_ON
|
|
||||||
self.available = True
|
|
||||||
|
|
||||||
async def async_send_key(self, key):
|
|
||||||
"""Send a key to the TV and handle exceptions."""
|
|
||||||
await self._handle_errors(self._control.send_key, key)
|
|
||||||
|
|
||||||
async def async_turn_on(self):
|
|
||||||
"""Turn on the TV."""
|
|
||||||
if self._on_action is not None:
|
|
||||||
await self._on_action.async_run()
|
|
||||||
self.state = STATE_ON
|
|
||||||
elif self.state != STATE_ON:
|
|
||||||
await self.async_send_key(Keys.power)
|
|
||||||
self.state = STATE_ON
|
|
||||||
|
|
||||||
async def async_turn_off(self):
|
|
||||||
"""Turn off the TV."""
|
|
||||||
if self.state != STATE_OFF:
|
|
||||||
await self.async_send_key(Keys.power)
|
|
||||||
self.state = STATE_OFF
|
|
||||||
await self.async_update()
|
|
||||||
|
|
||||||
async def async_set_mute(self, enable):
|
|
||||||
"""Set mute based on 'enable'."""
|
|
||||||
await self._handle_errors(self._control.set_mute, enable)
|
|
||||||
|
|
||||||
async def async_set_volume(self, volume):
|
|
||||||
"""Set volume level, range 0..1."""
|
|
||||||
volume = int(volume * 100)
|
|
||||||
await self._handle_errors(self._control.set_volume, volume)
|
|
||||||
|
|
||||||
async def async_play_media(self, media_type, media_id):
|
|
||||||
"""Play media."""
|
|
||||||
_LOGGER.debug("Play media: %s (%s)", media_id, media_type)
|
|
||||||
|
|
||||||
if media_type != MEDIA_TYPE_URL:
|
if media_type != MEDIA_TYPE_URL:
|
||||||
_LOGGER.warning("Unsupported media_type: %s", media_type)
|
_LOGGER.warning("Unsupported media_type: %s", media_type)
|
||||||
return
|
return
|
||||||
|
|
||||||
await self._handle_errors(self._control.open_webpage, media_id)
|
await self._remote.async_play_media(media_type, media_id)
|
||||||
|
|
||||||
async def _handle_errors(self, func, *args):
|
|
||||||
"""Handle errors from func, set available and reconnect if needed."""
|
|
||||||
try:
|
|
||||||
await self._hass.async_add_executor_job(func, *args)
|
|
||||||
except EncryptionRequired:
|
|
||||||
_LOGGER.error("The connection couldn't be encrypted")
|
|
||||||
except (TimeoutError, URLError, SOAPError, OSError):
|
|
||||||
self.state = STATE_OFF
|
|
||||||
self.available = self._on_action is not None
|
|
||||||
await self.async_create_remote_control()
|
|
||||||
|
123
tests/components/panasonic_viera/test_init.py
Normal file
123
tests/components/panasonic_viera/test_init.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
"""Test the Panasonic Viera setup process."""
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
from asynctest import patch
|
||||||
|
|
||||||
|
from homeassistant.components.panasonic_viera.const import (
|
||||||
|
CONF_APP_ID,
|
||||||
|
CONF_ENCRYPTION_KEY,
|
||||||
|
CONF_ON_ACTION,
|
||||||
|
DEFAULT_NAME,
|
||||||
|
DEFAULT_PORT,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
|
from homeassistant.config_entries import ENTRY_STATE_NOT_LOADED
|
||||||
|
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT
|
||||||
|
from homeassistant.setup import async_setup_component
|
||||||
|
|
||||||
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
MOCK_CONFIG_DATA = {
|
||||||
|
CONF_HOST: "0.0.0.0",
|
||||||
|
CONF_NAME: DEFAULT_NAME,
|
||||||
|
CONF_PORT: DEFAULT_PORT,
|
||||||
|
CONF_ON_ACTION: None,
|
||||||
|
}
|
||||||
|
|
||||||
|
MOCK_ENCRYPTION_DATA = {
|
||||||
|
CONF_APP_ID: "mock-app-id",
|
||||||
|
CONF_ENCRYPTION_KEY: "mock-encryption-key",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_mock_remote():
|
||||||
|
"""Return a mock remote."""
|
||||||
|
mock_remote = Mock()
|
||||||
|
|
||||||
|
async def async_create_remote_control(during_setup=False):
|
||||||
|
return
|
||||||
|
|
||||||
|
mock_remote.async_create_remote_control = async_create_remote_control
|
||||||
|
|
||||||
|
return mock_remote
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_entry_encrypted(hass):
|
||||||
|
"""Test setup with encrypted config entry."""
|
||||||
|
mock_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN,
|
||||||
|
unique_id=MOCK_CONFIG_DATA[CONF_HOST],
|
||||||
|
data={**MOCK_CONFIG_DATA, **MOCK_ENCRYPTION_DATA},
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
mock_remote = get_mock_remote()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.panasonic_viera.Remote", return_value=mock_remote,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("media_player.panasonic_viera_tv")
|
||||||
|
|
||||||
|
assert state
|
||||||
|
assert state.name == DEFAULT_NAME
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_entry_unencrypted(hass):
|
||||||
|
"""Test setup with unencrypted config entry."""
|
||||||
|
mock_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, unique_id=MOCK_CONFIG_DATA[CONF_HOST], data=MOCK_CONFIG_DATA,
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
mock_remote = get_mock_remote()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.panasonic_viera.Remote", return_value=mock_remote,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("media_player.panasonic_viera_tv")
|
||||||
|
|
||||||
|
assert state
|
||||||
|
assert state.name == DEFAULT_NAME
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_config_flow_initiated(hass):
|
||||||
|
"""Test if config flow is initiated in setup."""
|
||||||
|
assert (
|
||||||
|
await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_HOST: "0.0.0.0"}},)
|
||||||
|
is True
|
||||||
|
)
|
||||||
|
|
||||||
|
assert len(hass.config_entries.flow.async_progress()) == 1
|
||||||
|
|
||||||
|
|
||||||
|
async def test_setup_unload_entry(hass):
|
||||||
|
"""Test if config entry is unloaded."""
|
||||||
|
mock_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, unique_id=MOCK_CONFIG_DATA[CONF_HOST], data=MOCK_CONFIG_DATA
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
mock_remote = get_mock_remote()
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.panasonic_viera.Remote", return_value=mock_remote,
|
||||||
|
):
|
||||||
|
await hass.config_entries.async_setup(mock_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
await hass.config_entries.async_unload(mock_entry.entry_id)
|
||||||
|
|
||||||
|
assert mock_entry.state == ENTRY_STATE_NOT_LOADED
|
||||||
|
|
||||||
|
state = hass.states.get("media_player.panasonic_viera_tv")
|
||||||
|
|
||||||
|
assert state is None
|
Loading…
x
Reference in New Issue
Block a user