From 41c52a6f83425f6d01e7690fc3e5ef5f3af0743f Mon Sep 17 00:00:00 2001 From: joogps Date: Fri, 23 Oct 2020 14:29:41 +0000 Subject: [PATCH 1/6] Adding remote control support --- .../components/panasonic_viera/__init__.py | 3 +- .../panasonic_viera/media_player.py | 6 +- .../components/panasonic_viera/remote.py | 87 +++++++++++++++++++ tests/components/panasonic_viera/test_init.py | 66 +++++++++----- 4 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 homeassistant/components/panasonic_viera/remote.py diff --git a/homeassistant/components/panasonic_viera/__init__.py b/homeassistant/components/panasonic_viera/__init__.py index 8ebf5c8c4b1320..e2a79ae827881a 100644 --- a/homeassistant/components/panasonic_viera/__init__.py +++ b/homeassistant/components/panasonic_viera/__init__.py @@ -8,6 +8,7 @@ import voluptuous as vol from homeassistant.components.media_player.const import DOMAIN as MEDIA_PLAYER_DOMAIN +from homeassistant.components.remote import DOMAIN as REMOTE_DOMAIN from homeassistant.config_entries import SOURCE_IMPORT from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PORT, STATE_OFF, STATE_ON import homeassistant.helpers.config_validation as cv @@ -46,7 +47,7 @@ extra=vol.ALLOW_EXTRA, ) -PLATFORMS = [MEDIA_PLAYER_DOMAIN] +PLATFORMS = [MEDIA_PLAYER_DOMAIN, REMOTE_DOMAIN] async def async_setup(hass, config): diff --git a/homeassistant/components/panasonic_viera/media_player.py b/homeassistant/components/panasonic_viera/media_player.py index 316385f7d969fc..5aa5fccdf24091 100644 --- a/homeassistant/components/panasonic_viera/media_player.py +++ b/homeassistant/components/panasonic_viera/media_player.py @@ -71,9 +71,9 @@ def __init__(self, remote, name, device_info): @property def unique_id(self) -> str: """Return the unique ID of the device.""" - if self._device_info is not None: - return self._device_info[ATTR_UDN] - return None + if self._device_info is None: + return None + return self._device_info[ATTR_UDN] @property def device_info(self): diff --git a/homeassistant/components/panasonic_viera/remote.py b/homeassistant/components/panasonic_viera/remote.py new file mode 100644 index 00000000000000..8af9ddec60c301 --- /dev/null +++ b/homeassistant/components/panasonic_viera/remote.py @@ -0,0 +1,87 @@ +"""Remote control support for Panasonic Viera TV.""" +import logging + +from homeassistant.components.remote import RemoteEntity +from homeassistant.const import CONF_NAME, STATE_ON + +from .const import ( + ATTR_DEVICE_INFO, + ATTR_MANUFACTURER, + ATTR_MODEL_NUMBER, + ATTR_REMOTE, + ATTR_UDN, + DOMAIN, +) + +_LOGGER = logging.getLogger(__name__) + + +async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up Panasonic Viera TV Remote from a config entry.""" + + config = config_entry.data + + remote = hass.data[DOMAIN][config_entry.entry_id][ATTR_REMOTE] + name = config[CONF_NAME] + device_info = config[ATTR_DEVICE_INFO] + + remote_device = PanasonicVieraRemoteEntity(remote, name, device_info) + async_add_entities([remote_device]) + + +class PanasonicVieraRemoteEntity(RemoteEntity): + """Representation of a Panasonic Viera TV Remote.""" + + def __init__(self, remote, name, device_info): + """Initialize the entity.""" + # Save a reference to the imported class + self._remote = remote + self._name = name + self._device_info = device_info + + @property + def unique_id(self): + """Return the unique ID of the device.""" + if self._device_info is None: + return None + return self._device_info[ATTR_UDN] + + @property + def device_info(self): + """Return device specific attributes.""" + if self._device_info is None: + return None + return { + "name": self._name, + "identifiers": {(DOMAIN, self._device_info[ATTR_UDN])}, + "manufacturer": self._device_info[ATTR_MANUFACTURER], + "model": self._device_info[ATTR_MODEL_NUMBER], + } + + @property + def name(self): + """Return the name of the device.""" + return self._name + + @property + def available(self): + """Return True if the device is available.""" + return self._remote.available + + @property + def is_on(self): + """Return true if device is on.""" + return self._remote.state == STATE_ON + + async def async_turn_on(self, **kwargs): + """Turn the device on.""" + await self._remote.async_turn_on() + + async def async_turn_off(self, **kwargs): + """Turn the device off.""" + await self._remote.async_turn_off() + + async def async_send_command(self, command, **kwargs): + """Send a command to one device.""" + for cmd in command: + await self._remote.async_send_key(cmd) diff --git a/tests/components/panasonic_viera/test_init.py b/tests/components/panasonic_viera/test_init.py index 70b8db656e1e86..741a1bf8127049 100644 --- a/tests/components/panasonic_viera/test_init.py +++ b/tests/components/panasonic_viera/test_init.py @@ -75,10 +75,14 @@ async def test_setup_entry_encrypted(hass): 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") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") - assert state - assert state.name == DEFAULT_NAME + assert state_tv + assert state_tv.name == DEFAULT_NAME + + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_entry_encrypted_missing_device_info(hass): @@ -103,10 +107,14 @@ async def test_setup_entry_encrypted_missing_device_info(hass): assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN] - state = hass.states.get("media_player.panasonic_viera_tv") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") + + assert state_tv + assert state_tv.name == DEFAULT_NAME - assert state - assert state.name == DEFAULT_NAME + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_entry_encrypted_missing_device_info_none(hass): @@ -131,10 +139,14 @@ async def test_setup_entry_encrypted_missing_device_info_none(hass): assert mock_entry.data[ATTR_DEVICE_INFO] is None assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST] - state = hass.states.get("media_player.panasonic_viera_tv") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") + + assert state_tv + assert state_tv.name == DEFAULT_NAME - assert state - assert state.name == DEFAULT_NAME + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_entry_unencrypted(hass): @@ -156,10 +168,14 @@ async def test_setup_entry_unencrypted(hass): 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") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") - assert state - assert state.name == DEFAULT_NAME + assert state_tv + assert state_tv.name == DEFAULT_NAME + + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_entry_unencrypted_missing_device_info(hass): @@ -184,10 +200,14 @@ async def test_setup_entry_unencrypted_missing_device_info(hass): assert mock_entry.data[ATTR_DEVICE_INFO] == MOCK_DEVICE_INFO assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN] - state = hass.states.get("media_player.panasonic_viera_tv") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") + + assert state_tv + assert state_tv.name == DEFAULT_NAME - assert state - assert state.name == DEFAULT_NAME + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_entry_unencrypted_missing_device_info_none(hass): @@ -212,10 +232,14 @@ async def test_setup_entry_unencrypted_missing_device_info_none(hass): assert mock_entry.data[ATTR_DEVICE_INFO] is None assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST] - state = hass.states.get("media_player.panasonic_viera_tv") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") + + assert state_tv + assert state_tv.name == DEFAULT_NAME - assert state - assert state.name == DEFAULT_NAME + assert state_remote + assert state_remote.name == DEFAULT_NAME async def test_setup_config_flow_initiated(hass): @@ -253,6 +277,8 @@ async def test_setup_unload_entry(hass): assert mock_entry.state == ENTRY_STATE_NOT_LOADED - state = hass.states.get("media_player.panasonic_viera_tv") + state_tv = hass.states.get("media_player.panasonic_viera_tv") + state_remote = hass.states.get("media_player.panasonic_viera_remote") - assert state is None + assert state_tv is None + assert state_remote is None From a39f65d755f2b3fe911d8712ce91f15e9900fca9 Mon Sep 17 00:00:00 2001 From: joogps Date: Fri, 23 Oct 2020 12:24:12 -0300 Subject: [PATCH 2/6] Fixing device info attributes --- .../components/panasonic_viera/__init__.py | 4 +++- .../components/panasonic_viera/const.py | 3 +++ .../panasonic_viera/media_player.py | 8 +++++-- .../components/panasonic_viera/remote.py | 10 ++++++--- .../panasonic_viera/test_config_flow.py | 22 ++++++++++--------- tests/components/panasonic_viera/test_init.py | 6 +++-- 6 files changed, 35 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/panasonic_viera/__init__.py b/homeassistant/components/panasonic_viera/__init__.py index e2a79ae827881a..0297ded6cfba1e 100644 --- a/homeassistant/components/panasonic_viera/__init__.py +++ b/homeassistant/components/panasonic_viera/__init__.py @@ -246,7 +246,9 @@ async def async_get_device_info(self): """Return device info.""" if self._control is None: return None - return await self._handle_errors(self._control.get_device_info) + device_info = await self._handle_errors(self._control.get_device_info) + _LOGGER.debug("Fetched device info: %s", str(device_info)) + return device_info async def _handle_errors(self, func, *args): """Handle errors from func, set available and reconnect if needed.""" diff --git a/homeassistant/components/panasonic_viera/const.py b/homeassistant/components/panasonic_viera/const.py index 36b61360441538..a2e3fc2eece594 100644 --- a/homeassistant/components/panasonic_viera/const.py +++ b/homeassistant/components/panasonic_viera/const.py @@ -18,4 +18,7 @@ ATTR_MODEL_NUMBER = "modelNumber" ATTR_UDN = "UDN" +DEFAULT_MANUFACTURER = "Panasonic" +DEFAULT_MODEL_NUMBER = "Panasonic Viera" + ERROR_INVALID_PIN_CODE = "invalid_pin_code" diff --git a/homeassistant/components/panasonic_viera/media_player.py b/homeassistant/components/panasonic_viera/media_player.py index 5aa5fccdf24091..04eceabbfbb866 100644 --- a/homeassistant/components/panasonic_viera/media_player.py +++ b/homeassistant/components/panasonic_viera/media_player.py @@ -26,6 +26,8 @@ ATTR_MODEL_NUMBER, ATTR_REMOTE, ATTR_UDN, + DEFAULT_MANUFACTURER, + DEFAULT_MODEL_NUMBER, DOMAIN, ) @@ -83,8 +85,10 @@ def device_info(self): return { "name": self._name, "identifiers": {(DOMAIN, self._device_info[ATTR_UDN])}, - "manufacturer": self._device_info[ATTR_MANUFACTURER], - "model": self._device_info[ATTR_MODEL_NUMBER], + "manufacturer": self._device_info.get( + ATTR_MANUFACTURER, DEFAULT_MANUFACTURER + ), + "model": self._device_info.get(ATTR_MODEL_NUMBER, DEFAULT_MODEL_NUMBER), } @property diff --git a/homeassistant/components/panasonic_viera/remote.py b/homeassistant/components/panasonic_viera/remote.py index 8af9ddec60c301..527c56d18d209d 100644 --- a/homeassistant/components/panasonic_viera/remote.py +++ b/homeassistant/components/panasonic_viera/remote.py @@ -10,6 +10,8 @@ ATTR_MODEL_NUMBER, ATTR_REMOTE, ATTR_UDN, + DEFAULT_MANUFACTURER, + DEFAULT_MODEL_NUMBER, DOMAIN, ) @@ -44,7 +46,7 @@ def unique_id(self): """Return the unique ID of the device.""" if self._device_info is None: return None - return self._device_info[ATTR_UDN] + return self._device_info.get(ATTR_UDN) @property def device_info(self): @@ -54,8 +56,10 @@ def device_info(self): return { "name": self._name, "identifiers": {(DOMAIN, self._device_info[ATTR_UDN])}, - "manufacturer": self._device_info[ATTR_MANUFACTURER], - "model": self._device_info[ATTR_MODEL_NUMBER], + "manufacturer": self._device_info.get( + ATTR_MANUFACTURER, DEFAULT_MANUFACTURER + ), + "model": self._device_info.get(ATTR_MODEL_NUMBER, DEFAULT_MODEL_NUMBER), } @property diff --git a/tests/components/panasonic_viera/test_config_flow.py b/tests/components/panasonic_viera/test_config_flow.py index f3d1f1cc8f112a..dc61f2c08e0d19 100644 --- a/tests/components/panasonic_viera/test_config_flow.py +++ b/tests/components/panasonic_viera/test_config_flow.py @@ -12,6 +12,8 @@ CONF_APP_ID, CONF_ENCRYPTION_KEY, CONF_ON_ACTION, + DEFAULT_MANUFACTURER, + DEFAULT_MODEL_NUMBER, DEFAULT_NAME, DEFAULT_PORT, DOMAIN, @@ -42,8 +44,8 @@ def get_mock_remote( app_id=None, encryption_key=None, name=DEFAULT_NAME, - manufacturer="mock-manufacturer", - model_number="mock-model-number", + manufacturer=DEFAULT_MANUFACTURER, + model_number=DEFAULT_MODEL_NUMBER, unique_id="mock-unique-id", ): """Return a mock remote.""" @@ -110,8 +112,8 @@ async def test_flow_non_encrypted(hass): CONF_ON_ACTION: None, ATTR_DEVICE_INFO: { ATTR_FRIENDLY_NAME: DEFAULT_NAME, - ATTR_MANUFACTURER: "mock-manufacturer", - ATTR_MODEL_NUMBER: "mock-model-number", + ATTR_MANUFACTURER: DEFAULT_MANUFACTURER, + ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER, ATTR_UDN: "mock-unique-id", }, } @@ -208,8 +210,8 @@ async def test_flow_encrypted_valid_pin_code(hass): CONF_ENCRYPTION_KEY: "test-encryption-key", ATTR_DEVICE_INFO: { ATTR_FRIENDLY_NAME: DEFAULT_NAME, - ATTR_MANUFACTURER: "mock-manufacturer", - ATTR_MODEL_NUMBER: "mock-model-number", + ATTR_MANUFACTURER: DEFAULT_MANUFACTURER, + ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER, ATTR_UDN: "mock-unique-id", }, } @@ -392,8 +394,8 @@ async def test_imported_flow_non_encrypted(hass): CONF_ON_ACTION: "test-on-action", ATTR_DEVICE_INFO: { ATTR_FRIENDLY_NAME: DEFAULT_NAME, - ATTR_MANUFACTURER: "mock-manufacturer", - ATTR_MODEL_NUMBER: "mock-model-number", + ATTR_MANUFACTURER: DEFAULT_MANUFACTURER, + ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER, ATTR_UDN: "mock-unique-id", }, } @@ -442,8 +444,8 @@ async def test_imported_flow_encrypted_valid_pin_code(hass): CONF_ENCRYPTION_KEY: "test-encryption-key", ATTR_DEVICE_INFO: { ATTR_FRIENDLY_NAME: DEFAULT_NAME, - ATTR_MANUFACTURER: "mock-manufacturer", - ATTR_MODEL_NUMBER: "mock-model-number", + ATTR_MANUFACTURER: DEFAULT_MANUFACTURER, + ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER, ATTR_UDN: "mock-unique-id", }, } diff --git a/tests/components/panasonic_viera/test_init.py b/tests/components/panasonic_viera/test_init.py index 741a1bf8127049..ac2a7c951d9f51 100644 --- a/tests/components/panasonic_viera/test_init.py +++ b/tests/components/panasonic_viera/test_init.py @@ -8,6 +8,8 @@ CONF_APP_ID, CONF_ENCRYPTION_KEY, CONF_ON_ACTION, + DEFAULT_MANUFACTURER, + DEFAULT_MODEL_NUMBER, DEFAULT_NAME, DEFAULT_PORT, DOMAIN, @@ -33,8 +35,8 @@ MOCK_DEVICE_INFO = { ATTR_FRIENDLY_NAME: DEFAULT_NAME, - ATTR_MANUFACTURER: "mock-manufacturer", - ATTR_MODEL_NUMBER: "mock-model-number", + ATTR_MANUFACTURER: DEFAULT_MANUFACTURER, + ATTR_MODEL_NUMBER: DEFAULT_MODEL_NUMBER, ATTR_UDN: "mock-unique-id", } From 6f7be1dfd61575e43686e878fa3f443ab099a663 Mon Sep 17 00:00:00 2001 From: joogps Date: Fri, 23 Oct 2020 15:20:28 -0300 Subject: [PATCH 3/6] Fixing tests --- tests/components/panasonic_viera/test_init.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/components/panasonic_viera/test_init.py b/tests/components/panasonic_viera/test_init.py index ac2a7c951d9f51..2c082098665ad5 100644 --- a/tests/components/panasonic_viera/test_init.py +++ b/tests/components/panasonic_viera/test_init.py @@ -78,7 +78,7 @@ async def test_setup_entry_encrypted(hass): await hass.async_block_till_done() state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -110,7 +110,7 @@ async def test_setup_entry_encrypted_missing_device_info(hass): assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN] state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -142,7 +142,7 @@ async def test_setup_entry_encrypted_missing_device_info_none(hass): assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST] state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -171,7 +171,7 @@ async def test_setup_entry_unencrypted(hass): await hass.async_block_till_done() state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -203,7 +203,7 @@ async def test_setup_entry_unencrypted_missing_device_info(hass): assert mock_entry.unique_id == MOCK_DEVICE_INFO[ATTR_UDN] state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -235,7 +235,7 @@ async def test_setup_entry_unencrypted_missing_device_info_none(hass): assert mock_entry.unique_id == MOCK_CONFIG_DATA[CONF_HOST] state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv assert state_tv.name == DEFAULT_NAME @@ -280,7 +280,7 @@ async def test_setup_unload_entry(hass): assert mock_entry.state == ENTRY_STATE_NOT_LOADED state_tv = hass.states.get("media_player.panasonic_viera_tv") - state_remote = hass.states.get("media_player.panasonic_viera_remote") + state_remote = hass.states.get("remote.panasonic_viera_tv") assert state_tv is None assert state_remote is None From d2f2b5def288e4b565dbf53734d3bca4a0fb1597 Mon Sep 17 00:00:00 2001 From: joogps Date: Fri, 23 Oct 2020 22:46:23 -0300 Subject: [PATCH 4/6] Adding config flow tests --- .../panasonic_viera/test_config_flow.py | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/tests/components/panasonic_viera/test_config_flow.py b/tests/components/panasonic_viera/test_config_flow.py index dc61f2c08e0d19..15e6b73202d8d2 100644 --- a/tests/components/panasonic_viera/test_config_flow.py +++ b/tests/components/panasonic_viera/test_config_flow.py @@ -39,6 +39,7 @@ def panasonic_viera_setup_fixture(): def get_mock_remote( host="1.2.3.4", + request_error=None, authorize_error=None, encrypted=False, app_id=None, @@ -56,7 +57,8 @@ def get_mock_remote( mock_remote.enc_key = encryption_key def request_pin_code(name=None): - return + if request_error is not None: + raise request_error mock_remote.request_pin_code = request_pin_code @@ -166,6 +168,56 @@ async def test_flow_unknown_abort(hass): assert result["reason"] == "unknown" +async def test_flow_encrypted_not_connected_pin_code_request(hass): + """Test flow with encryption and PIN code request connection error abortion during pairing request step.""" + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert result["type"] == "form" + assert result["step_id"] == "user" + + mock_remote = get_mock_remote(encrypted=True, request_error=TimeoutError) + + with patch( + "homeassistant.components.panasonic_viera.config_flow.RemoteControl", + return_value=mock_remote, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME}, + ) + + assert result["type"] == "abort" + assert result["reason"] == "cannot_connect" + + +async def test_flow_encrypted_unknown_pin_code_request(hass): + """Test flow with encryption and PIN code request unknown error abortion during pairing request step.""" + + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + + assert result["type"] == "form" + assert result["step_id"] == "user" + + mock_remote = get_mock_remote(encrypted=True, request_error=Exception) + + with patch( + "homeassistant.components.panasonic_viera.config_flow.RemoteControl", + return_value=mock_remote, + ): + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + {CONF_HOST: "1.2.3.4", CONF_NAME: DEFAULT_NAME}, + ) + + assert result["type"] == "abort" + assert result["reason"] == "unknown" + + async def test_flow_encrypted_valid_pin_code(hass): """Test flow with encryption and valid PIN code.""" From 8b0c34d56db3c261419efc41fbea82fa7d82a571 Mon Sep 17 00:00:00 2001 From: joogps Date: Sat, 24 Oct 2020 00:22:17 -0300 Subject: [PATCH 5/6] Adding remote tests --- .../panasonic_viera/media_player.py | 2 +- .../components/panasonic_viera/remote.py | 2 +- .../components/panasonic_viera/test_remote.py | 84 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tests/components/panasonic_viera/test_remote.py diff --git a/homeassistant/components/panasonic_viera/media_player.py b/homeassistant/components/panasonic_viera/media_player.py index 04eceabbfbb866..c59c77b569c7a8 100644 --- a/homeassistant/components/panasonic_viera/media_player.py +++ b/homeassistant/components/panasonic_viera/media_player.py @@ -71,7 +71,7 @@ def __init__(self, remote, name, device_info): self._device_info = device_info @property - def unique_id(self) -> str: + def unique_id(self): """Return the unique ID of the device.""" if self._device_info is None: return None diff --git a/homeassistant/components/panasonic_viera/remote.py b/homeassistant/components/panasonic_viera/remote.py index 527c56d18d209d..fe449894d1b81b 100644 --- a/homeassistant/components/panasonic_viera/remote.py +++ b/homeassistant/components/panasonic_viera/remote.py @@ -46,7 +46,7 @@ def unique_id(self): """Return the unique ID of the device.""" if self._device_info is None: return None - return self._device_info.get(ATTR_UDN) + return self._device_info[ATTR_UDN] @property def device_info(self): diff --git a/tests/components/panasonic_viera/test_remote.py b/tests/components/panasonic_viera/test_remote.py new file mode 100644 index 00000000000000..3fe7086c96271a --- /dev/null +++ b/tests/components/panasonic_viera/test_remote.py @@ -0,0 +1,84 @@ +"""Test the Panasonic Viera remote entity.""" + +from homeassistant.components.panasonic_viera.const import ATTR_UDN, DOMAIN +from homeassistant.components.remote import ( + ATTR_COMMAND, + DOMAIN as REMOTE_DOMAIN, + SERVICE_SEND_COMMAND, +) +from homeassistant.const import ATTR_ENTITY_ID, SERVICE_TURN_OFF, SERVICE_TURN_ON + +from .test_init import ( + MOCK_CONFIG_DATA, + MOCK_DEVICE_INFO, + MOCK_ENCRYPTION_DATA, + get_mock_remote, +) + +from tests.async_mock import patch +from tests.common import MockConfigEntry + + +async def setup_panasonic_viera(hass): + """Initialize integration for tests.""" + mock_entry = MockConfigEntry( + domain=DOMAIN, + unique_id=MOCK_DEVICE_INFO[ATTR_UDN], + data={**MOCK_CONFIG_DATA, **MOCK_ENCRYPTION_DATA, **MOCK_DEVICE_INFO}, + ) + + 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() + + +async def test_turn_on(hass): + """Test turn on service call.""" + mock_remote = get_mock_remote() + + with patch( + "homeassistant.components.panasonic_viera.Remote", + return_value=mock_remote, + ): + await setup_panasonic_viera(hass) + + data = {ATTR_ENTITY_ID: "remote.panasonic_viera_tv"} + await hass.services.async_call(REMOTE_DOMAIN, SERVICE_TURN_ON, data) + await hass.async_block_till_done() + + +async def test_turn_off(hass): + """Test turn off service call.""" + mock_remote = get_mock_remote() + + with patch( + "homeassistant.components.panasonic_viera.Remote", + return_value=mock_remote, + ): + await setup_panasonic_viera(hass) + + data = {ATTR_ENTITY_ID: "remote.panasonic_viera_tv"} + await hass.services.async_call(REMOTE_DOMAIN, SERVICE_TURN_OFF, data) + await hass.async_block_till_done() + + +async def test_send_command(hass): + """Test send command service call.""" + mock_remote = get_mock_remote() + + with patch( + "homeassistant.components.panasonic_viera.Remote", + return_value=mock_remote, + ): + await setup_panasonic_viera(hass) + + data = {ATTR_ENTITY_ID: "remote.panasonic_viera_tv", ATTR_COMMAND: "power"} + await hass.services.async_call(REMOTE_DOMAIN, SERVICE_SEND_COMMAND, data) + await hass.async_block_till_done() From 1ecc602d2672f91c51fae09df24af37f14c3b1e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Gabriel?= Date: Sat, 24 Oct 2020 11:22:21 -0300 Subject: [PATCH 6/6] Update const.py --- homeassistant/components/panasonic_viera/const.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/homeassistant/components/panasonic_viera/const.py b/homeassistant/components/panasonic_viera/const.py index a2e3fc2eece594..39fba1f5b5c2d2 100644 --- a/homeassistant/components/panasonic_viera/const.py +++ b/homeassistant/components/panasonic_viera/const.py @@ -19,6 +19,6 @@ ATTR_UDN = "UDN" DEFAULT_MANUFACTURER = "Panasonic" -DEFAULT_MODEL_NUMBER = "Panasonic Viera" +DEFAULT_MODEL_NUMBER = "Viera" ERROR_INVALID_PIN_CODE = "invalid_pin_code"