mirror of
https://github.com/home-assistant/core.git
synced 2025-04-27 10:47:51 +00:00
Fix HomeKit media players when entity has duplicate sources (#83890)
fixes #83852 fixes #83698
This commit is contained in:
parent
b9753a9f92
commit
692a732555
@ -18,7 +18,7 @@ from homeassistant.const import (
|
|||||||
SERVICE_TURN_ON,
|
SERVICE_TURN_ON,
|
||||||
STATE_ON,
|
STATE_ON,
|
||||||
)
|
)
|
||||||
from homeassistant.core import callback
|
from homeassistant.core import State, callback
|
||||||
|
|
||||||
from .accessories import TYPES, HomeAccessory
|
from .accessories import TYPES, HomeAccessory
|
||||||
from .const import (
|
from .const import (
|
||||||
@ -96,7 +96,7 @@ class RemoteInputSelectAccessory(HomeAccessory, ABC):
|
|||||||
self.sources = []
|
self.sources = []
|
||||||
self.support_select_source = False
|
self.support_select_source = False
|
||||||
if features & required_feature:
|
if features & required_feature:
|
||||||
sources = state.attributes.get(source_list_key, [])
|
sources = self._get_ordered_source_list_from_state(state)
|
||||||
if len(sources) > MAXIMUM_SOURCES:
|
if len(sources) > MAXIMUM_SOURCES:
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"%s: Reached maximum number of sources (%s)",
|
"%s: Reached maximum number of sources (%s)",
|
||||||
@ -143,6 +143,21 @@ class RemoteInputSelectAccessory(HomeAccessory, ABC):
|
|||||||
serv_input.configure_char(CHAR_CURRENT_VISIBILITY_STATE, value=False)
|
serv_input.configure_char(CHAR_CURRENT_VISIBILITY_STATE, value=False)
|
||||||
_LOGGER.debug("%s: Added source %s", self.entity_id, source)
|
_LOGGER.debug("%s: Added source %s", self.entity_id, source)
|
||||||
|
|
||||||
|
def _get_ordered_source_list_from_state(self, state: State) -> list[str]:
|
||||||
|
"""Return ordered source list while preserving order with duplicates removed.
|
||||||
|
|
||||||
|
Some integrations have duplicate sources in the source list
|
||||||
|
which will make the source list conflict as HomeKit requires
|
||||||
|
unique source names.
|
||||||
|
"""
|
||||||
|
seen = set()
|
||||||
|
sources: list[str] = []
|
||||||
|
for source in state.attributes.get(self.source_list_key, []):
|
||||||
|
if source not in seen:
|
||||||
|
sources.append(source)
|
||||||
|
seen.add(source)
|
||||||
|
return sources
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def set_on_off(self, value):
|
def set_on_off(self, value):
|
||||||
"""Move switch state to value if call came from HomeKit."""
|
"""Move switch state to value if call came from HomeKit."""
|
||||||
@ -169,7 +184,7 @@ class RemoteInputSelectAccessory(HomeAccessory, ABC):
|
|||||||
self.char_input_source.set_value(index)
|
self.char_input_source.set_value(index)
|
||||||
return
|
return
|
||||||
|
|
||||||
possible_sources = new_state.attributes.get(self.source_list_key, [])
|
possible_sources = self._get_ordered_source_list_from_state(new_state)
|
||||||
if source in possible_sources:
|
if source in possible_sources:
|
||||||
index = possible_sources.index(source)
|
index = possible_sources.index(source)
|
||||||
if index >= MAXIMUM_SOURCES:
|
if index >= MAXIMUM_SOURCES:
|
||||||
|
@ -512,3 +512,48 @@ async def test_media_player_television_max_sources(hass, hk_driver, events, capl
|
|||||||
)
|
)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert acc.char_input_source.value == 0
|
assert acc.char_input_source.value == 0
|
||||||
|
|
||||||
|
|
||||||
|
async def test_media_player_television_duplicate_sources(
|
||||||
|
hass, hk_driver, events, caplog
|
||||||
|
):
|
||||||
|
"""Test if television accessory with duplicate sources."""
|
||||||
|
entity_id = "media_player.television"
|
||||||
|
sources = ["MUSIC", "HDMI", "SCREEN MIRRORING", "HDMI", "MUSIC"]
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
None,
|
||||||
|
{
|
||||||
|
ATTR_DEVICE_CLASS: MediaPlayerDeviceClass.TV,
|
||||||
|
ATTR_SUPPORTED_FEATURES: 3469,
|
||||||
|
ATTR_MEDIA_VOLUME_MUTED: False,
|
||||||
|
ATTR_INPUT_SOURCE: "HDMI",
|
||||||
|
ATTR_INPUT_SOURCE_LIST: sources,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
acc = TelevisionMediaPlayer(hass, hk_driver, "MediaPlayer", entity_id, 2, None)
|
||||||
|
await acc.run()
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert acc.aid == 2
|
||||||
|
assert acc.category == 31 # Television
|
||||||
|
|
||||||
|
assert acc.char_active.value == 0
|
||||||
|
assert acc.char_remote_key.value == 0
|
||||||
|
assert acc.char_input_source.value == 1
|
||||||
|
assert acc.char_mute.value is False
|
||||||
|
|
||||||
|
hass.states.async_set(
|
||||||
|
entity_id,
|
||||||
|
None,
|
||||||
|
{
|
||||||
|
ATTR_DEVICE_CLASS: MediaPlayerDeviceClass.TV,
|
||||||
|
ATTR_SUPPORTED_FEATURES: 3469,
|
||||||
|
ATTR_MEDIA_VOLUME_MUTED: False,
|
||||||
|
ATTR_INPUT_SOURCE: "MUSIC",
|
||||||
|
ATTR_INPUT_SOURCE_LIST: sources,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
assert acc.char_input_source.value == 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user