media_player: handle STOP command correctly (fixes #128)
Home Assistant sends MEDIA_PLAYER_COMMAND_STOP when the queue is cleared. The MediaPlayer entity did not handle this command, causing playback to continue without media metadata and leaving the UI in an inconsistent state. This change adds explicit handling for the STOP command: - stop playback via the music player - reset the media player state to IDLE This aligns the behavior with the original player and Home Assistant’s expected media player semantics.
This commit is contained in:
1 parent
7a92d69864
commit
72c7d4dff4
1 file changed
+29
@@ -1,6 +1,7 @@
|
||||
from abc import abstractmethod
|
||||
from collections.abc import Iterable
|
||||
from typing import Callable, List, Optional, Union
|
||||
import logging
|
||||
|
||||
# pylint: disable=no-name-in-module
|
||||
from aioesphomeapi.api_pb2 import ( # type: ignore[attr-defined]
|
||||
@@ -68,6 +69,7 @@ class MediaPlayerEntity(ESPHomeEntity):
|
||||
self.previous_volume = 1.0
|
||||
self.music_player = music_player
|
||||
self.announce_player = announce_player
|
||||
self._log = logging.getLogger(f"{self.__class__.__name__}[{self.key}]")
|
||||
|
||||
def play(
|
||||
self,
|
||||
@@ -111,19 +113,37 @@ class MediaPlayerEntity(ESPHomeEntity):
|
||||
yield self._update_state(MediaPlayerState.PLAYING)
|
||||
|
||||
def handle_message(self, msg: message.Message) -> Iterable[message.Message]:
|
||||
self._log.debug("handle_message called with msg: %s", msg)
|
||||
|
||||
if isinstance(msg, MediaPlayerCommandRequest) and (msg.key == self.key):
|
||||
self._log.debug("MediaPlayerCommandRequest matched for this key")
|
||||
|
||||
if msg.has_media_url:
|
||||
self._log.debug("Message has media URL: %s", msg.media_url)
|
||||
announcement = msg.has_announcement and msg.announcement
|
||||
yield from self.play(msg.media_url, announcement=announcement)
|
||||
|
||||
elif msg.has_command:
|
||||
self._log.debug("Message has command: %s", msg.command)
|
||||
command = MediaPlayerCommand(msg.command)
|
||||
|
||||
if msg.command == MediaPlayerCommand.PAUSE:
|
||||
self._log.debug("Executing PAUSE")
|
||||
self.music_player.pause()
|
||||
yield self._update_state(MediaPlayerState.PAUSED)
|
||||
|
||||
elif msg.command == MediaPlayerCommand.PLAY:
|
||||
self._log.debug("Executing PLAY / RESUME")
|
||||
self.music_player.resume()
|
||||
yield self._update_state(MediaPlayerState.PLAYING)
|
||||
|
||||
elif command == MediaPlayerCommand.STOP:
|
||||
self._log.debug("Executing STOP")
|
||||
self.music_player.stop()
|
||||
yield self._update_state(MediaPlayerState.IDLE)
|
||||
|
||||
elif command == MediaPlayerCommand.MUTE:
|
||||
self._log.debug("Executing MUTE")
|
||||
if not self.muted:
|
||||
self.previous_volume = self.volume
|
||||
self.volume = 0
|
||||
@@ -131,20 +151,26 @@ class MediaPlayerEntity(ESPHomeEntity):
|
||||
self.announce_player.set_volume(0)
|
||||
self.muted = True
|
||||
yield self._update_state(self.state)
|
||||
|
||||
elif command == MediaPlayerCommand.UNMUTE:
|
||||
self._log.debug("Executing UNMUTE")
|
||||
if self.muted:
|
||||
self.volume = self.previous_volume
|
||||
self.music_player.set_volume(int(self.volume * 100))
|
||||
self.announce_player.set_volume(int(self.volume * 100))
|
||||
self.muted = False
|
||||
yield self._update_state(self.state)
|
||||
|
||||
elif msg.has_volume:
|
||||
self._log.debug("Message has volume: %.2f", msg.volume)
|
||||
volume = int(msg.volume * 100)
|
||||
self.music_player.set_volume(volume)
|
||||
self.announce_player.set_volume(volume)
|
||||
self.volume = msg.volume
|
||||
yield self._update_state(self.state)
|
||||
|
||||
elif isinstance(msg, ListEntitiesRequest):
|
||||
self._log.debug("ListEntitiesRequest received")
|
||||
yield ListEntitiesMediaPlayerResponse(
|
||||
object_id=self.object_id,
|
||||
key=self.key,
|
||||
@@ -153,7 +179,10 @@ class MediaPlayerEntity(ESPHomeEntity):
|
||||
feature_flags=SUPPORTED_MEDIA_PLAYER_FEATURES,
|
||||
)
|
||||
elif isinstance(msg, SubscribeHomeAssistantStatesRequest):
|
||||
self._log.debug("SubscribeHomeAssistantStatesRequest received")
|
||||
yield self._get_state_message()
|
||||
else:
|
||||
self._log.warning("Unknown message type received: %s", type(msg))
|
||||
|
||||
def _update_state(self, new_state: MediaPlayerState) -> MediaPlayerStateResponse:
|
||||
self.state = new_state
|
||||
|
||||
Reference in new issue
Block a user