From 19faf06ce724e243d8e37c451af03d04128547a3 Mon Sep 17 00:00:00 2001 From: Jc2k Date: Mon, 9 Mar 2020 16:19:17 +0000 Subject: [PATCH] homekit_controller fixes from testing with an LG TV: (#32610) * Bump aiohomekit to get better reconnection handling and cleaner shutdowns. * Read the ACTIVE characteristic and set ok/problem state Also gets test coverage to 100%. --- .../homekit_controller/manifest.json | 2 +- .../homekit_controller/media_player.py | 20 +++++++++++++++---- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- .../specific_devices/test_lg_tv.py | 4 ++++ .../homekit_controller/test_media_player.py | 19 ++++++++++++++++++ 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/homekit_controller/manifest.json b/homeassistant/components/homekit_controller/manifest.json index 4cfc642bf8c..7582bc10ae5 100644 --- a/homeassistant/components/homekit_controller/manifest.json +++ b/homeassistant/components/homekit_controller/manifest.json @@ -3,7 +3,7 @@ "name": "HomeKit Controller", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/homekit_controller", - "requirements": ["aiohomekit[IP]==0.2.21"], + "requirements": ["aiohomekit[IP]==0.2.24"], "dependencies": [], "zeroconf": ["_hap._tcp.local."], "codeowners": ["@Jc2k"] diff --git a/homeassistant/components/homekit_controller/media_player.py b/homeassistant/components/homekit_controller/media_player.py index 38817712def..09693f3e8a8 100644 --- a/homeassistant/components/homekit_controller/media_player.py +++ b/homeassistant/components/homekit_controller/media_player.py @@ -17,7 +17,13 @@ from homeassistant.components.media_player.const import ( SUPPORT_SELECT_SOURCE, SUPPORT_STOP, ) -from homeassistant.const import STATE_IDLE, STATE_PAUSED, STATE_PLAYING +from homeassistant.const import ( + STATE_IDLE, + STATE_OK, + STATE_PAUSED, + STATE_PLAYING, + STATE_PROBLEM, +) from homeassistant.core import callback from . import KNOWN_DEVICES, HomeKitEntity @@ -62,6 +68,7 @@ class HomeKitTelevision(HomeKitEntity, MediaPlayerDevice): def get_characteristic_types(self): """Define the homekit characteristics the entity cares about.""" return [ + CharacteristicsTypes.ACTIVE, CharacteristicsTypes.CURRENT_MEDIA_STATE, CharacteristicsTypes.TARGET_MEDIA_STATE, CharacteristicsTypes.REMOTE_KEY, @@ -143,10 +150,15 @@ class HomeKitTelevision(HomeKitEntity, MediaPlayerDevice): @property def state(self): """State of the tv.""" + active = self.get_hk_char_value(CharacteristicsTypes.ACTIVE) + if not active: + return STATE_PROBLEM + homekit_state = self.get_hk_char_value(CharacteristicsTypes.CURRENT_MEDIA_STATE) - if homekit_state is None: - return None - return HK_TO_HA_STATE[homekit_state] + if homekit_state is not None: + return HK_TO_HA_STATE[homekit_state] + + return STATE_OK async def async_media_play(self): """Send play command.""" diff --git a/requirements_all.txt b/requirements_all.txt index 3c37befe796..4de51512bd1 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -163,7 +163,7 @@ aioftp==0.12.0 aioharmony==0.1.13 # homeassistant.components.homekit_controller -aiohomekit[IP]==0.2.21 +aiohomekit[IP]==0.2.24 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 356b5a7530a..81ee9addeac 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -62,7 +62,7 @@ aiobotocore==0.11.1 aioesphomeapi==2.6.1 # homeassistant.components.homekit_controller -aiohomekit[IP]==0.2.21 +aiohomekit[IP]==0.2.24 # homeassistant.components.emulated_hue # homeassistant.components.http diff --git a/tests/components/homekit_controller/specific_devices/test_lg_tv.py b/tests/components/homekit_controller/specific_devices/test_lg_tv.py index 3ffd906213b..acebac95006 100644 --- a/tests/components/homekit_controller/specific_devices/test_lg_tv.py +++ b/tests/components/homekit_controller/specific_devices/test_lg_tv.py @@ -50,6 +50,10 @@ async def test_lg_tv(hass): SUPPORT_PAUSE | SUPPORT_PLAY | SUPPORT_SELECT_SOURCE ) + # The LG TV doesn't (at least at this patch level) report its media state via + # CURRENT_MEDIA_STATE. Therefore "ok" is the best we can say. + assert state.state == "ok" + device_registry = await hass.helpers.device_registry.async_get_registry() device = device_registry.async_get(entry.device_id) diff --git a/tests/components/homekit_controller/test_media_player.py b/tests/components/homekit_controller/test_media_player.py index 09798c218a8..44c53af02da 100644 --- a/tests/components/homekit_controller/test_media_player.py +++ b/tests/components/homekit_controller/test_media_player.py @@ -4,6 +4,7 @@ from aiohomekit.model.characteristics import ( CharacteristicsTypes, ) from aiohomekit.model.services import ServicesTypes +import pytest from tests.components.homekit_controller.common import setup_test_component @@ -21,6 +22,8 @@ def create_tv_service(accessory): """ tv_service = accessory.add_service(ServicesTypes.TELEVISION) + tv_service.add_char(CharacteristicsTypes.ACTIVE, value=True) + cur_state = tv_service.add_char(CharacteristicsTypes.CURRENT_MEDIA_STATE) cur_state.value = 0 @@ -245,3 +248,19 @@ async def test_tv_set_source(hass, utcnow): state = await helper.poll_and_get_state() assert state.attributes["source"] == "HDMI 2" + + +async def test_tv_set_source_fail(hass, utcnow): + """Test that we can set the input source of a HomeKit TV.""" + helper = await setup_test_component(hass, create_tv_service) + + with pytest.raises(ValueError): + await hass.services.async_call( + "media_player", + "select_source", + {"entity_id": "media_player.testdevice", "source": "HDMI 999"}, + blocking=True, + ) + + state = await helper.poll_and_get_state() + assert state.attributes["source"] == "HDMI 1"