Modify behavior of media_player groups (#74056)
parent
c19a8ef8e0
commit
9a613aeb96
|
@ -103,6 +103,8 @@ async def async_setup_entry(
|
|||
class MediaPlayerGroup(MediaPlayerEntity):
|
||||
"""Representation of a Media Group."""
|
||||
|
||||
_attr_available: bool = False
|
||||
|
||||
def __init__(self, unique_id: str | None, name: str, entities: list[str]) -> None:
|
||||
"""Initialize a Media Group entity."""
|
||||
self._name = name
|
||||
|
@ -390,19 +392,29 @@ class MediaPlayerGroup(MediaPlayerEntity):
|
|||
@callback
|
||||
def async_update_state(self) -> None:
|
||||
"""Query all members and determine the media group state."""
|
||||
states = [self.hass.states.get(entity) for entity in self._entities]
|
||||
states_values = [state.state for state in states if state is not None]
|
||||
off_values = STATE_OFF, STATE_UNAVAILABLE, STATE_UNKNOWN
|
||||
states = [
|
||||
state.state
|
||||
for entity_id in self._entities
|
||||
if (state := self.hass.states.get(entity_id)) is not None
|
||||
]
|
||||
|
||||
if states_values:
|
||||
if states_values.count(states_values[0]) == len(states_values):
|
||||
self._state = states_values[0]
|
||||
elif any(state for state in states_values if state not in off_values):
|
||||
# Set group as unavailable if all members are unavailable or missing
|
||||
self._attr_available = any(state != STATE_UNAVAILABLE for state in states)
|
||||
|
||||
valid_state = any(
|
||||
state not in (STATE_UNKNOWN, STATE_UNAVAILABLE) for state in states
|
||||
)
|
||||
if not valid_state:
|
||||
# Set as unknown if all members are unknown or unavailable
|
||||
self._state = None
|
||||
else:
|
||||
off_values = (STATE_OFF, STATE_UNAVAILABLE, STATE_UNKNOWN)
|
||||
if states.count(states[0]) == len(states):
|
||||
self._state = states[0]
|
||||
elif any(state for state in states if state not in off_values):
|
||||
self._state = STATE_ON
|
||||
else:
|
||||
self._state = STATE_OFF
|
||||
else:
|
||||
self._state = None
|
||||
|
||||
supported_features = 0
|
||||
if self._features[KEY_CLEAR_PLAYLIST]:
|
||||
|
|
|
@ -126,8 +126,24 @@ async def test_state_reporting(hass):
|
|||
await hass.async_start()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Initial state with no group member in the state machine -> unknown
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNKNOWN
|
||||
# Initial state with no group member in the state machine -> unavailable
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNAVAILABLE
|
||||
|
||||
# All group members unavailable -> unavailable
|
||||
hass.states.async_set("media_player.player_1", STATE_UNAVAILABLE)
|
||||
hass.states.async_set("media_player.player_2", STATE_UNAVAILABLE)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNAVAILABLE
|
||||
|
||||
# The group state is unknown if all group members are unknown or unavailable.
|
||||
for state_1 in (
|
||||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
):
|
||||
hass.states.async_set("media_player.player_1", state_1)
|
||||
hass.states.async_set("media_player.player_2", STATE_UNKNOWN)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNKNOWN
|
||||
|
||||
# All group members buffering -> buffering
|
||||
# All group members idle -> idle
|
||||
|
@ -156,30 +172,18 @@ async def test_state_reporting(hass):
|
|||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_ON
|
||||
|
||||
# Otherwise off
|
||||
for state_1 in (STATE_OFF, STATE_UNAVAILABLE, STATE_UNKNOWN):
|
||||
hass.states.async_set("media_player.player_1", state_1)
|
||||
hass.states.async_set("media_player.player_2", STATE_OFF)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_OFF
|
||||
|
||||
# Otherwise off
|
||||
for state_1 in (STATE_OFF, STATE_UNKNOWN):
|
||||
hass.states.async_set("media_player.player_1", state_1)
|
||||
hass.states.async_set("media_player.player_2", STATE_UNAVAILABLE)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_OFF
|
||||
|
||||
for state_1 in (STATE_OFF, STATE_UNAVAILABLE):
|
||||
hass.states.async_set("media_player.player_1", state_1)
|
||||
hass.states.async_set("media_player.player_2", STATE_UNKNOWN)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_OFF
|
||||
|
||||
# All group members removed from the state machine -> unknown
|
||||
# All group members removed from the state machine -> unavailable
|
||||
hass.states.async_remove("media_player.player_1")
|
||||
hass.states.async_remove("media_player.player_2")
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNKNOWN
|
||||
assert hass.states.get("media_player.media_group").state == STATE_UNAVAILABLE
|
||||
|
||||
|
||||
async def test_supported_features(hass):
|
||||
|
|
Loading…
Reference in New Issue