Reduce overhead to write dlna_dmr state (#113776)

* Reduce overhead to write dlna_dmr state

- Only update supported_features once per state write cycle
- Use a dict lookup for state

* useless dispatch

* fix tests

* remove unreachable code
pull/113854/head
J. Nick Koston 2024-03-19 15:13:34 -10:00 committed by GitHub
parent 02c1088596
commit 417b491b78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 27 additions and 20 deletions

View File

@ -57,6 +57,17 @@ _R = TypeVar("_R")
_P = ParamSpec("_P")
_TRANSPORT_STATE_TO_MEDIA_PLAYER_STATE = {
TransportState.PLAYING: MediaPlayerState.PLAYING,
TransportState.TRANSITIONING: MediaPlayerState.PLAYING,
TransportState.PAUSED_PLAYBACK: MediaPlayerState.PAUSED,
TransportState.PAUSED_RECORDING: MediaPlayerState.PAUSED,
# Unable to map this state to anything reasonable, so it's "Unknown"
TransportState.VENDOR_DEFINED: None,
None: MediaPlayerState.ON,
}
def catch_request_errors(
func: Callable[Concatenate[_DlnaDmrEntityT, _P], Awaitable[_R]],
) -> Callable[Concatenate[_DlnaDmrEntityT, _P], Coroutine[Any, Any, _R | None]]:
@ -186,6 +197,7 @@ class DlnaDmrEntity(MediaPlayerEntity):
self._updated_registry: bool = False
self._config_entry = config_entry
self._attr_device_info = dr.DeviceInfo(connections={(dr.CONNECTION_UPNP, udn)})
self._attr_supported_features = self._supported_features()
async def async_added_to_hass(self) -> None:
"""Handle addition."""
@ -345,6 +357,11 @@ class DlnaDmrEntity(MediaPlayerEntity):
# Device was de/re-connected, state might have changed
self.async_write_ha_state()
def async_write_ha_state(self) -> None:
"""Write the state."""
self._attr_supported_features = self._supported_features()
super().async_write_ha_state()
async def _device_connect(self, location: str) -> None:
"""Connect to the device now that it's available."""
_LOGGER.debug("Connecting to device at %s", location)
@ -491,6 +508,9 @@ class DlnaDmrEntity(MediaPlayerEntity):
finally:
self.check_available = False
# Supported features may have changed
self._attr_supported_features = self._supported_features()
def _on_event(
self, service: UpnpService, state_variables: Sequence[UpnpStateVariable]
) -> None:
@ -531,28 +551,13 @@ class DlnaDmrEntity(MediaPlayerEntity):
@property
def state(self) -> MediaPlayerState | None:
"""State of the player."""
if not self._device or not self.available:
if not self._device:
return MediaPlayerState.OFF
if self._device.transport_state is None:
return MediaPlayerState.ON
if self._device.transport_state in (
TransportState.PLAYING,
TransportState.TRANSITIONING,
):
return MediaPlayerState.PLAYING
if self._device.transport_state in (
TransportState.PAUSED_PLAYBACK,
TransportState.PAUSED_RECORDING,
):
return MediaPlayerState.PAUSED
if self._device.transport_state == TransportState.VENDOR_DEFINED:
# Unable to map this state to anything reasonable, so it's "Unknown"
return None
return _TRANSPORT_STATE_TO_MEDIA_PLAYER_STATE.get(
self._device.transport_state, MediaPlayerState.IDLE
)
return MediaPlayerState.IDLE
@property
def supported_features(self) -> MediaPlayerEntityFeature:
def _supported_features(self) -> MediaPlayerEntityFeature:
"""Flag media player features that are supported at this moment.
Supported features may change as the device enters different states.

View File

@ -1009,6 +1009,7 @@ async def test_shuffle_repeat_modes(
dmr_device_mock.async_set_play_mode.reset_mock()
dmr_device_mock.play_mode = PlayMode.RANDOM
dmr_device_mock.valid_play_modes = {PlayMode.SHUFFLE, PlayMode.RANDOM}
await get_attrs(hass, mock_entity_id)
await hass.services.async_call(
MP_DOMAIN,
ha_const.SERVICE_SHUFFLE_SET,
@ -1022,6 +1023,7 @@ async def test_shuffle_repeat_modes(
dmr_device_mock.async_set_play_mode.reset_mock()
dmr_device_mock.play_mode = PlayMode.RANDOM
dmr_device_mock.valid_play_modes = {PlayMode.REPEAT_ONE, PlayMode.REPEAT_ALL}
await get_attrs(hass, mock_entity_id)
await hass.services.async_call(
MP_DOMAIN,
ha_const.SERVICE_REPEAT_SET,