Home Assistant Unofficial Reference 2024.12.1
media_player.py
Go to the documentation of this file.
1 """Media player platform for Teslemetry integration."""
2 
3 from __future__ import annotations
4 
5 from tesla_fleet_api.const import Scope
6 
8  MediaPlayerDeviceClass,
9  MediaPlayerEntity,
10  MediaPlayerEntityFeature,
11  MediaPlayerState,
12 )
13 from homeassistant.core import HomeAssistant
14 from homeassistant.helpers.entity_platform import AddEntitiesCallback
15 
16 from . import TeslemetryConfigEntry
17 from .entity import TeslemetryVehicleEntity
18 from .helpers import handle_vehicle_command
19 from .models import TeslemetryVehicleData
20 
21 STATES = {
22  "Playing": MediaPlayerState.PLAYING,
23  "Paused": MediaPlayerState.PAUSED,
24  "Stopped": MediaPlayerState.IDLE,
25  "Off": MediaPlayerState.OFF,
26 }
27 VOLUME_MAX = 11.0
28 VOLUME_STEP = 1.0 / 3
29 
30 PARALLEL_UPDATES = 0
31 
32 
34  hass: HomeAssistant,
35  entry: TeslemetryConfigEntry,
36  async_add_entities: AddEntitiesCallback,
37 ) -> None:
38  """Set up the Teslemetry Media platform from a config entry."""
39 
41  TeslemetryMediaEntity(vehicle, Scope.VEHICLE_CMDS in entry.runtime_data.scopes)
42  for vehicle in entry.runtime_data.vehicles
43  )
44 
45 
47  """Vehicle media player class."""
48 
49  _attr_device_class = MediaPlayerDeviceClass.SPEAKER
50  _attr_supported_features = (
51  MediaPlayerEntityFeature.NEXT_TRACK
52  | MediaPlayerEntityFeature.PAUSE
53  | MediaPlayerEntityFeature.PLAY
54  | MediaPlayerEntityFeature.PREVIOUS_TRACK
55  | MediaPlayerEntityFeature.VOLUME_SET
56  )
57  _volume_max: float = VOLUME_MAX
58 
59  def __init__(
60  self,
61  data: TeslemetryVehicleData,
62  scoped: bool,
63  ) -> None:
64  """Initialize the media player entity."""
65  super().__init__(data, "media")
66  self.scopedscoped = scoped
67  if not scoped:
69 
70  def _async_update_attrs(self) -> None:
71  """Update entity attributes."""
72  self._volume_max_volume_max = (
73  self.getget("vehicle_state_media_info_audio_volume_max") or VOLUME_MAX
74  )
75  self._attr_state_attr_state = STATES.get(
76  self.getget("vehicle_state_media_info_media_playback_status") or "Off",
77  )
78  self._attr_volume_step_attr_volume_step = (
79  1.0
80  / self._volume_max_volume_max
81  / (
82  self.getget("vehicle_state_media_info_audio_volume_increment")
83  or VOLUME_STEP
84  )
85  )
86 
87  if volume := self.getget("vehicle_state_media_info_audio_volume"):
88  self._attr_volume_level_attr_volume_level = volume / self._volume_max_volume_max
89  else:
90  self._attr_volume_level_attr_volume_level = None
91 
92  if duration := self.getget("vehicle_state_media_info_now_playing_duration"):
93  self._attr_media_duration_attr_media_duration = duration / 1000
94  else:
95  self._attr_media_duration_attr_media_duration = None
96 
97  if duration and (
98  position := self.getget("vehicle_state_media_info_now_playing_elapsed")
99  ):
100  self._attr_media_position_attr_media_position = position / 1000
101  else:
102  self._attr_media_position_attr_media_position = None
103 
104  self._attr_media_title_attr_media_title = self.getget("vehicle_state_media_info_now_playing_title")
105  self._attr_media_artist_attr_media_artist = self.getget(
106  "vehicle_state_media_info_now_playing_artist"
107  )
108  self._attr_media_album_name_attr_media_album_name = self.getget(
109  "vehicle_state_media_info_now_playing_album"
110  )
111  self._attr_media_playlist_attr_media_playlist = self.getget(
112  "vehicle_state_media_info_now_playing_station"
113  )
114  self._attr_source_attr_source = self.getget("vehicle_state_media_info_now_playing_source")
115 
116  async def async_set_volume_level(self, volume: float) -> None:
117  """Set volume level, range 0..1."""
118  self.raise_for_scoperaise_for_scope(Scope.VEHICLE_CMDS)
119  await self.wake_up_if_asleepwake_up_if_asleep()
121  self.apiapiapiapiapiapi.adjust_volume(int(volume * self._volume_max_volume_max))
122  )
123  self._attr_volume_level_attr_volume_level = volume
124  self.async_write_ha_stateasync_write_ha_state()
125 
126  async def async_media_play(self) -> None:
127  """Send play command."""
128  if self.statestatestatestatestate != MediaPlayerState.PLAYING:
129  self.raise_for_scoperaise_for_scope(Scope.VEHICLE_CMDS)
130  await self.wake_up_if_asleepwake_up_if_asleep()
131  await handle_vehicle_command(self.apiapiapiapiapiapi.media_toggle_playback())
132  self._attr_state_attr_state = MediaPlayerState.PLAYING
133  self.async_write_ha_stateasync_write_ha_state()
134 
135  async def async_media_pause(self) -> None:
136  """Send pause command."""
137  if self.statestatestatestatestate == MediaPlayerState.PLAYING:
138  self.raise_for_scoperaise_for_scope(Scope.VEHICLE_CMDS)
139  await self.wake_up_if_asleepwake_up_if_asleep()
140  await handle_vehicle_command(self.apiapiapiapiapiapi.media_toggle_playback())
141  self._attr_state_attr_state = MediaPlayerState.PAUSED
142  self.async_write_ha_stateasync_write_ha_state()
143 
144  async def async_media_next_track(self) -> None:
145  """Send next track command."""
146  self.raise_for_scoperaise_for_scope(Scope.VEHICLE_CMDS)
147  await self.wake_up_if_asleepwake_up_if_asleep()
149 
150  async def async_media_previous_track(self) -> None:
151  """Send previous track command."""
152  self.raise_for_scoperaise_for_scope(Scope.VEHICLE_CMDS)
153  await self.wake_up_if_asleepwake_up_if_asleep()
154  await handle_vehicle_command(self.apiapiapiapiapiapi.media_prev_track())
Any|None get(self, str key, Any|None default=None)
Definition: entity.py:61
None __init__(self, TeslemetryVehicleData data, bool scoped)
Definition: media_player.py:63
bool handle_vehicle_command(Awaitable command)
Definition: helpers.py:50
None async_setup_entry(HomeAssistant hass, TeslemetryConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: media_player.py:37