Auto recreate HomeKit TVs when the sources are out of sync (#53208)
parent
2a65c5f93c
commit
f20602e11d
|
@ -58,12 +58,14 @@ from .const import (
|
|||
CONF_LOW_BATTERY_THRESHOLD,
|
||||
DEFAULT_LOW_BATTERY_THRESHOLD,
|
||||
DEVICE_CLASS_PM25,
|
||||
DOMAIN,
|
||||
EVENT_HOMEKIT_CHANGED,
|
||||
HK_CHARGING,
|
||||
HK_NOT_CHARGABLE,
|
||||
HK_NOT_CHARGING,
|
||||
MANUFACTURER,
|
||||
SERV_BATTERY_SERVICE,
|
||||
SERVICE_HOMEKIT_RESET_ACCESSORY,
|
||||
TYPE_FAUCET,
|
||||
TYPE_OUTLET,
|
||||
TYPE_SHOWER,
|
||||
|
@ -454,6 +456,17 @@ class HomeAccessory(Accessory):
|
|||
)
|
||||
)
|
||||
|
||||
@ha_callback
|
||||
def async_reset(self):
|
||||
"""Reset and recreate an accessory."""
|
||||
self.hass.async_create_task(
|
||||
self.hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_HOMEKIT_RESET_ACCESSORY,
|
||||
{ATTR_ENTITY_ID: self.entity_id},
|
||||
)
|
||||
)
|
||||
|
||||
@ha_callback
|
||||
def async_stop(self):
|
||||
"""Cancel any subscriptions when the bridge is stopped."""
|
||||
|
|
|
@ -87,6 +87,7 @@ class RemoteInputSelectAccessory(HomeAccessory):
|
|||
features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
|
||||
|
||||
self.source_key = source_key
|
||||
self.source_list_key = source_list_key
|
||||
self.sources = []
|
||||
self.support_select_source = False
|
||||
if features & required_feature:
|
||||
|
@ -152,13 +153,26 @@ class RemoteInputSelectAccessory(HomeAccessory):
|
|||
index = self.sources.index(source_name)
|
||||
if self.char_input_source.value != index:
|
||||
self.char_input_source.set_value(index)
|
||||
elif hk_state:
|
||||
_LOGGER.warning(
|
||||
"%s: Sources out of sync. Restart Home Assistant",
|
||||
return
|
||||
|
||||
possible_sources = new_state.attributes.get(self.source_list_key, [])
|
||||
if source_name in possible_sources:
|
||||
_LOGGER.debug(
|
||||
"%s: Sources out of sync. Rebuilding Accessory",
|
||||
self.entity_id,
|
||||
)
|
||||
if self.char_input_source.value != 0:
|
||||
self.char_input_source.set_value(0)
|
||||
# Sources are out of sync, recreate the accessory
|
||||
self.async_reset()
|
||||
return
|
||||
|
||||
_LOGGER.debug(
|
||||
"%s: Source %s does not exist the source list: %s",
|
||||
self.entity_id,
|
||||
source_name,
|
||||
possible_sources,
|
||||
)
|
||||
if self.char_input_source.value != 0:
|
||||
self.char_input_source.set_value(0)
|
||||
|
||||
|
||||
@TYPES.register("ActivityRemote")
|
||||
|
|
|
@ -242,7 +242,7 @@ async def test_media_player_television(hass, hk_driver, events, caplog):
|
|||
hass.states.async_set(entity_id, STATE_ON, {ATTR_INPUT_SOURCE: "HDMI 5"})
|
||||
await hass.async_block_till_done()
|
||||
assert acc.char_input_source.value == 0
|
||||
assert caplog.records[-2].levelname == "WARNING"
|
||||
assert caplog.records[-2].levelname == "DEBUG"
|
||||
|
||||
# Set from HomeKit
|
||||
call_turn_on = async_mock_service(hass, DOMAIN, "turn_on")
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
from homeassistant.components.homekit.const import (
|
||||
ATTR_KEY_NAME,
|
||||
ATTR_VALUE,
|
||||
DOMAIN as HOMEKIT_DOMAIN,
|
||||
EVENT_HOMEKIT_TV_REMOTE_KEY_PRESSED,
|
||||
KEY_ARROW_RIGHT,
|
||||
SERVICE_HOMEKIT_RESET_ACCESSORY,
|
||||
)
|
||||
from homeassistant.components.homekit.type_remotes import ActivityRemote
|
||||
from homeassistant.components.remote import (
|
||||
|
@ -146,3 +148,19 @@ async def test_activity_remote(hass, hk_driver, events, caplog):
|
|||
|
||||
assert len(events) == 1
|
||||
assert events[0].data[ATTR_KEY_NAME] == KEY_ARROW_RIGHT
|
||||
|
||||
call_reset_accessory = async_mock_service(
|
||||
hass, HOMEKIT_DOMAIN, SERVICE_HOMEKIT_RESET_ACCESSORY
|
||||
)
|
||||
# A wild source appears - The accessory should rebuild itself
|
||||
hass.states.async_set(
|
||||
entity_id,
|
||||
STATE_ON,
|
||||
{
|
||||
ATTR_SUPPORTED_FEATURES: SUPPORT_ACTIVITY,
|
||||
ATTR_CURRENT_ACTIVITY: "Amazon TV",
|
||||
ATTR_ACTIVITY_LIST: ["TV", "Apple TV", "Amazon TV"],
|
||||
},
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert call_reset_accessory[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
|
|
Loading…
Reference in New Issue