# can be used by a player provider to exclude some sort of players
enabled_by_default: bool = True
+ # needs_poll: bool that can be set by the player(provider)
+ # if this player needs to be polled for state changes by the player manager
+ needs_poll: bool = False
+
+ # poll_interval: a (dynamic) interval in seconds to poll the player (used with needs_poll)
+ poll_interval: int = 30
+
#
# THE BELOW ATTRIBUTES ARE MANAGED BY CONFIG AND THE PLAYER MANAGER
#
if include_values
else PlayerConfig.parse([], raw_conf)
for raw_conf in list(self.get(CONF_PLAYERS, {}).values())
- # filter out unavailable providers
- if raw_conf["provider"] in get_global_cache_value("available_providers", [])
+ # filter out unavailable providers (only if we requested the full info)
+ if (
+ not include_values
+ or raw_conf["provider"] in get_global_cache_value("available_providers", [])
+ )
# optional provider filter
and (provider in (None, raw_conf["provider"]))
]
if provider := self.mass.get_provider(existing["provider"]):
assert isinstance(provider, PlayerProvider)
provider.on_player_config_removed(player_id)
+ if not player:
+ self.mass.signal_event(EventType.PLAYER_REMOVED, player_id)
def create_default_player_config(
self,
if player_playing:
self.mass.loop.call_soon(self.update, player_id)
# Poll player;
- # - every 120 seconds if the player if not powered
- # - every 30 seconds if the player is powered
- # - every 5 seconds if the player is playing
- if (
- (player.powered and count % 30 == 0)
- or (player_playing and count % 5 == 0)
- or count % 120 == 0
- ) and (player_prov := self.get_player_provider(player_id)):
+ if not player.needs_poll:
+ continue
+ if count % player.poll_interval == 0 and (
+ player_prov := self.get_player_provider(player_id)
+ ):
try:
await player_prov.poll_player(player_id)
except PlayerUnavailableError:
"""Poll player for state updates.
This is called by the Player Manager;
- - every 360 seconds if the player if not powered
- - every 30 seconds if the player is powered
- - every 10 seconds if the player is playing
-
- Use this method to request any info that is not automatically updated and/or
- to detect if the player is still alive.
- If this method raises the PlayerUnavailable exception,
- the player is marked as unavailable until
- the next successful poll or event where it becomes available again.
- If the player does not need any polling, simply do not override this method.
+ if 'needs_poll' is set to True in the player object.
"""
def on_child_power(self, player_id: str, child_player_id: str, new_power: bool) -> None:
)
async def poll_player(self, player_id: str) -> None:
- """Poll player for state updates.
-
- This is called by the Player Manager;
- - every 360 seconds if the player if not powered
- - every 30 seconds if the player is powered
- - every 10 seconds if the player is playing
-
- Use this method to request any info that is not automatically updated and/or
- to detect if the player is still alive.
- If this method raises the PlayerUnavailable exception,
- the player is marked as unavailable until
- the next successful poll or event where it becomes available again.
- If the player does not need any polling, simply do not override this method.
- """
+ """Poll player for state updates."""
castplayer = self.castplayers[player_id]
# only update status of media controller if player is on
if not castplayer.player.powered:
return
try:
now = time.time()
- if (now - castplayer.last_poll) >= 30:
+ if (now - castplayer.last_poll) >= 60:
castplayer.last_poll = now
await asyncio.to_thread(castplayer.cc.media_controller.update_status)
await self.update_flow_metadata(castplayer)
PlayerFeature.PAUSE,
),
enabled_by_default=enabled_by_default,
+ needs_poll=True,
),
)
self.castplayers[player_id] = castplayer
async def update_flow_metadata(self, castplayer: CastPlayer) -> None:
"""Update the metadata of a cast player running the flow stream."""
if not castplayer.player.powered:
+ castplayer.player.poll_interval = 300
return
if not castplayer.cc.media_controller.status.player_is_playing:
return
return
if not (queue.flow_mode or current_item.media_type == MediaType.RADIO):
return
+ castplayer.player.poll_interval = 10
media_controller = castplayer.cc.media_controller
# update metadata of current item chromecast
if media_controller.status.media_custom_data["queue_item_id"] != current_item.queue_item_id:
await dlna_player.device.async_mute_volume(muted)
async def poll_player(self, player_id: str) -> None:
- """Poll player for state updates.
-
- This is called by the Player Manager;
- - every 360 seconds if the player if not powered
- - every 30 seconds if the player is powered
- - every 10 seconds if the player is playing
-
- Use this method to request any info that is not automatically updated and/or
- to detect if the player is still alive.
- If this method raises the PlayerUnavailable exception,
- the player is marked as unavailable until
- the next successful poll or event where it becomes available again.
- If the player does not need any polling, simply do not override this method.
- """
+ """Poll player for state updates."""
dlna_player = self.dlnaplayers[player_id]
# try to reconnect the device if the connection was lost
address=description_url,
manufacturer="unknown",
),
+ needs_poll=True,
+ poll_interval=30,
),
description_url=description_url,
)
address=address,
),
supported_features=(PlayerFeature.VOLUME_SET,),
+ needs_poll=True,
+ poll_interval=10,
)
self.mass.players.register_or_update(player)
self._handle_player_update()
self.mass.players.update(player_id)
async def poll_player(self, player_id: str) -> None:
- """Poll player for state updates.
-
- This is called by the Player Manager;
- - every 360 seconds if the player if not powered
- - every 30 seconds if the player is powered
- - every 10 seconds if the player is playing
-
- Use this method to request any info that is not automatically updated and/or
- to detect if the player is still alive.
- If this method raises the PlayerUnavailable exception,
- the player is marked as unavailable until
- the next successful poll or event where it becomes available again.
- If the player does not need any polling, simply do not override this method.
- """
+ """Poll player for state updates."""
try:
async with asyncio.timeout(15):
await self._fully.getDeviceInfo()
return
async def poll_player(self, player_id: str) -> None:
- """Poll player for state updates.
-
- This is called by the Player Manager;
- - every 360 seconds if the player if not powered
- - every 30 seconds if the player is powered
- - every 10 seconds if the player is playing
-
- Use this method to request any info that is not automatically updated and/or
- to detect if the player is still alive.
- If this method raises the PlayerUnavailable exception,
- the player is marked as unavailable until
- the next successful poll or event where it becomes available again.
- If the player does not need any polling, simply do not override this method.
- """
+ """Poll player for state updates."""
if player_id not in self.sonosplayers:
return
sonos_player = self.sonosplayers[player_id]
address=soco.ip_address,
manufacturer="SONOS",
),
+ needs_poll=True,
+ poll_interval=120,
)
self.sonosplayers[player_id] = sonos_player = SonosPlayer(
self,