Home Assistant Unofficial Reference 2024.12.1
media_player.py
Go to the documentation of this file.
1 """Support for track controls on the Sisyphus Kinetic Art Table."""
2 
3 from __future__ import annotations
4 
5 import aiohttp
6 from sisyphus_control import Track
7 
9  MediaPlayerEntity,
10  MediaPlayerEntityFeature,
11  MediaPlayerState,
12 )
13 from homeassistant.const import CONF_HOST
14 from homeassistant.core import HomeAssistant
15 from homeassistant.exceptions import PlatformNotReady
16 from homeassistant.helpers.entity_platform import AddEntitiesCallback
17 from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
18 
19 from . import DATA_SISYPHUS
20 
21 MEDIA_TYPE_TRACK = "sisyphus_track"
22 
23 
25  hass: HomeAssistant,
26  config: ConfigType,
27  add_entities: AddEntitiesCallback,
28  discovery_info: DiscoveryInfoType | None = None,
29 ) -> None:
30  """Set up a media player entity for a Sisyphus table."""
31  if not discovery_info:
32  return
33  host = discovery_info[CONF_HOST]
34  try:
35  table_holder = hass.data[DATA_SISYPHUS][host]
36  table = await table_holder.get_table()
37  except aiohttp.ClientError as err:
38  raise PlatformNotReady from err
39 
40  add_entities([SisyphusPlayer(table_holder.name, host, table)], True)
41 
42 
44  """Representation of a Sisyphus table as a media player device."""
45 
46  _attr_supported_features = (
47  MediaPlayerEntityFeature.VOLUME_MUTE
48  | MediaPlayerEntityFeature.VOLUME_SET
49  | MediaPlayerEntityFeature.TURN_OFF
50  | MediaPlayerEntityFeature.TURN_ON
51  | MediaPlayerEntityFeature.PAUSE
52  | MediaPlayerEntityFeature.SHUFFLE_SET
53  | MediaPlayerEntityFeature.PREVIOUS_TRACK
54  | MediaPlayerEntityFeature.NEXT_TRACK
55  | MediaPlayerEntityFeature.PLAY
56  )
57 
58  def __init__(self, name, host, table):
59  """Initialize the Sisyphus media device."""
60  self._name_name = name
61  self._host_host = host
62  self._table_table = table
63 
64  async def async_added_to_hass(self) -> None:
65  """Add listeners after this object has been initialized."""
66  self._table_table.add_listener(self.async_write_ha_stateasync_write_ha_state)
67 
68  async def async_update(self) -> None:
69  """Force update table state."""
70  await self._table_table.refresh()
71 
72  @property
73  def unique_id(self):
74  """Return the UUID of the table."""
75  return self._table_table.id
76 
77  @property
78  def available(self) -> bool:
79  """Return true if the table is responding to heartbeats."""
80  return self._table_table.is_connected
81 
82  @property
83  def name(self):
84  """Return the name of the table."""
85  return self._name_name
86 
87  @property
88  def state(self) -> MediaPlayerState | None:
89  """Return the current state of the table; sleeping maps to off."""
90  if self._table_table.state in ["homing", "playing"]:
91  return MediaPlayerState.PLAYING
92  if self._table_table.state == "paused":
93  if self._table_table.is_sleeping:
94  return MediaPlayerState.OFF
95 
96  return MediaPlayerState.PAUSED
97  if self._table_table.state == "waiting":
98  return MediaPlayerState.IDLE
99 
100  return None
101 
102  @property
103  def volume_level(self):
104  """Return the current playback speed (0..1)."""
105  return self._table_table.speed
106 
107  @property
108  def shuffle(self):
109  """Return True if the current playlist is in shuffle mode."""
110  return self._table_table.is_shuffle
111 
112  async def async_set_shuffle(self, shuffle: bool) -> None:
113  """Change the shuffle mode of the current playlist."""
114  await self._table_table.set_shuffle(shuffle)
115 
116  @property
117  def media_playlist(self):
118  """Return the name of the current playlist."""
119  return self._table_table.active_playlist.name if self._table_table.active_playlist else None
120 
121  @property
122  def media_title(self):
123  """Return the title of the current track."""
124  return self._table_table.active_track.name if self._table_table.active_track else None
125 
126  @property
128  """Return the content type currently playing; i.e. a Sisyphus track."""
129  return MEDIA_TYPE_TRACK
130 
131  @property
132  def media_content_id(self):
133  """Return the track ID of the current track."""
134  return self._table_table.active_track.id if self._table_table.active_track else None
135 
136  @property
137  def media_duration(self):
138  """Return the total time it will take to run this track at the current speed."""
139  return self._table_table.active_track_total_time.total_seconds()
140 
141  @property
142  def media_position(self):
143  """Return the current position within the track."""
144  return (
145  self._table_table.active_track_total_time
146  - self._table_table.active_track_remaining_time
147  ).total_seconds()
148 
149  @property
151  """Return the last time we got a position update."""
152  return self._table_table.active_track_remaining_time_as_of
153 
154  @property
155  def media_image_url(self):
156  """Return the URL for a thumbnail image of the current track."""
157 
158  if self._table_table.active_track:
159  return self._table_table.active_track.get_thumbnail_url(Track.ThumbnailSize.LARGE)
160 
161  return super().media_image_url
162 
163  async def async_turn_on(self) -> None:
164  """Wake up a sleeping table."""
165  await self._table_table.wakeup()
166 
167  async def async_turn_off(self) -> None:
168  """Put the table to sleep."""
169  await self._table_table.sleep()
170 
171  async def async_volume_down(self) -> None:
172  """Slow down playback."""
173  await self._table_table.set_speed(max(0, self._table_table.speed - 0.1))
174 
175  async def async_volume_up(self) -> None:
176  """Speed up playback."""
177  await self._table_table.set_speed(min(1.0, self._table_table.speed + 0.1))
178 
179  async def async_set_volume_level(self, volume: float) -> None:
180  """Set playback speed (0..1)."""
181  await self._table_table.set_speed(volume)
182 
183  async def async_media_play(self) -> None:
184  """Start playing."""
185  await self._table_table.play()
186 
187  async def async_media_pause(self) -> None:
188  """Pause."""
189  await self._table_table.pause()
190 
191  async def async_media_next_track(self) -> None:
192  """Skip to next track."""
193  cur_track_index = self._get_current_track_index_get_current_track_index()
194 
195  await self._table_table.active_playlist.play(
196  self._table_table.active_playlist.tracks[cur_track_index + 1]
197  )
198 
199  async def async_media_previous_track(self) -> None:
200  """Skip to previous track."""
201  cur_track_index = self._get_current_track_index_get_current_track_index()
202 
203  await self._table_table.active_playlist.play(
204  self._table_table.active_playlist.tracks[cur_track_index - 1]
205  )
206 
208  for index, track in enumerate(self._table_table.active_playlist.tracks):
209  if track.id == self._table_table.active_track.id:
210  return index
211 
212  return -1
None add_entities(AsusWrtRouter router, AddEntitiesCallback async_add_entities, set[str] tracked)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback add_entities, DiscoveryInfoType|None discovery_info=None)
Definition: media_player.py:29