Home Assistant Unofficial Reference 2024.12.1
media_player.py
Go to the documentation of this file.
1 """Support for Enigma2 media players."""
2 
3 from __future__ import annotations
4 
5 import contextlib
6 from logging import getLogger
7 from typing import cast
8 
9 from aiohttp.client_exceptions import ServerDisconnectedError
10 from openwebif.enums import PowerState, RemoteControlCodes, SetVolumeOption
11 
13  MediaPlayerEntity,
14  MediaPlayerEntityFeature,
15  MediaPlayerState,
16  MediaType,
17 )
18 from homeassistant.config_entries import ConfigEntry
19 from homeassistant.core import HomeAssistant, callback
20 from homeassistant.helpers.entity_platform import AddEntitiesCallback
21 from homeassistant.helpers.update_coordinator import CoordinatorEntity
22 
23 from . import Enigma2ConfigEntry
24 from .coordinator import Enigma2UpdateCoordinator
25 
26 ATTR_MEDIA_CURRENTLY_RECORDING = "media_currently_recording"
27 ATTR_MEDIA_DESCRIPTION = "media_description"
28 ATTR_MEDIA_END_TIME = "media_end_time"
29 ATTR_MEDIA_START_TIME = "media_start_time"
30 
31 _LOGGER = getLogger(__name__)
32 
33 
35  hass: HomeAssistant,
36  entry: Enigma2ConfigEntry,
37  async_add_entities: AddEntitiesCallback,
38 ) -> None:
39  """Set up the Enigma2 media player platform."""
40  async_add_entities([Enigma2Device(entry.runtime_data)])
41 
42 
43 class Enigma2Device(CoordinatorEntity[Enigma2UpdateCoordinator], MediaPlayerEntity):
44  """Representation of an Enigma2 box."""
45 
46  _attr_has_entity_name = True
47  _attr_name = None
48 
49  _attr_media_content_type = MediaType.TVSHOW
50  _attr_supported_features = (
51  MediaPlayerEntityFeature.VOLUME_SET
52  | MediaPlayerEntityFeature.VOLUME_MUTE
53  | MediaPlayerEntityFeature.TURN_OFF
54  | MediaPlayerEntityFeature.NEXT_TRACK
55  | MediaPlayerEntityFeature.STOP
56  | MediaPlayerEntityFeature.PREVIOUS_TRACK
57  | MediaPlayerEntityFeature.VOLUME_STEP
58  | MediaPlayerEntityFeature.TURN_ON
59  | MediaPlayerEntityFeature.PAUSE
60  | MediaPlayerEntityFeature.SELECT_SOURCE
61  )
62 
63  def __init__(self, coordinator: Enigma2UpdateCoordinator) -> None:
64  """Initialize the Enigma2 device."""
65 
66  super().__init__(coordinator)
67 
68  self._attr_unique_id_attr_unique_id = (
69  coordinator.device.mac_address
70  or cast(ConfigEntry, coordinator.config_entry).entry_id
71  )
72 
73  self._attr_device_info_attr_device_info = coordinator.device_info
74 
75  async def async_turn_off(self) -> None:
76  """Turn off media player."""
77  if self.coordinator.device.turn_off_to_deep:
78  with contextlib.suppress(ServerDisconnectedError):
79  await self.coordinator.device.set_powerstate(PowerState.DEEP_STANDBY)
80  self._attr_available_attr_available = False
81  else:
82  await self.coordinator.device.set_powerstate(PowerState.STANDBY)
83  await self.coordinator.async_refresh()
84 
85  async def async_turn_on(self) -> None:
86  """Turn the media player on."""
87  await self.coordinator.device.turn_on()
88  await self.coordinator.async_refresh()
89 
90  async def async_set_volume_level(self, volume: float) -> None:
91  """Set volume level, range 0..1."""
92  await self.coordinator.device.set_volume(int(volume * 100))
93  await self.coordinator.async_refresh()
94 
95  async def async_volume_up(self) -> None:
96  """Volume up the media player."""
97  await self.coordinator.device.set_volume(SetVolumeOption.UP)
98  await self.coordinator.async_refresh()
99 
100  async def async_volume_down(self) -> None:
101  """Volume down media player."""
102  await self.coordinator.device.set_volume(SetVolumeOption.DOWN)
103  await self.coordinator.async_refresh()
104 
105  async def async_media_stop(self) -> None:
106  """Send stop command."""
107  await self.coordinator.device.send_remote_control_action(
108  RemoteControlCodes.STOP
109  )
110  await self.coordinator.async_refresh()
111 
112  async def async_media_play(self) -> None:
113  """Play media."""
114  await self.coordinator.device.send_remote_control_action(
115  RemoteControlCodes.PLAY
116  )
117  await self.coordinator.async_refresh()
118 
119  async def async_media_pause(self) -> None:
120  """Pause the media player."""
121  await self.coordinator.device.send_remote_control_action(
122  RemoteControlCodes.PAUSE
123  )
124  await self.coordinator.async_refresh()
125 
126  async def async_media_next_track(self) -> None:
127  """Send next track command."""
128  await self.coordinator.device.send_remote_control_action(
129  RemoteControlCodes.CHANNEL_UP
130  )
131  await self.coordinator.async_refresh()
132 
133  async def async_media_previous_track(self) -> None:
134  """Send previous track command."""
135  await self.coordinator.device.send_remote_control_action(
136  RemoteControlCodes.CHANNEL_DOWN
137  )
138  await self.coordinator.async_refresh()
139 
140  async def async_mute_volume(self, mute: bool) -> None:
141  """Mute or unmute."""
142  if mute != self.coordinator.data.muted:
143  await self.coordinator.device.toggle_mute()
144  await self.coordinator.async_refresh()
145 
146  async def async_select_source(self, source: str) -> None:
147  """Select input source."""
148  await self.coordinator.device.zap(self.coordinator.device.sources[source])
149  await self.coordinator.async_refresh()
150 
151  @callback
152  def _handle_coordinator_update(self) -> None:
153  """Update state of the media_player."""
154 
155  if not self.coordinator.data.in_standby:
156  self._attr_extra_state_attributes_attr_extra_state_attributes = {
157  ATTR_MEDIA_CURRENTLY_RECORDING: self.coordinator.data.is_recording,
158  ATTR_MEDIA_DESCRIPTION: self.coordinator.data.currservice.fulldescription,
159  ATTR_MEDIA_START_TIME: self.coordinator.data.currservice.begin,
160  ATTR_MEDIA_END_TIME: self.coordinator.data.currservice.end,
161  }
162  else:
163  self._attr_extra_state_attributes_attr_extra_state_attributes = {}
164 
165  self._attr_media_title_attr_media_title = self.coordinator.data.currservice.station
166  self._attr_media_series_title_attr_media_series_title = self.coordinator.data.currservice.name
167  self._attr_media_channel_attr_media_channel = self.coordinator.data.currservice.station
168  self._attr_is_volume_muted_attr_is_volume_muted = self.coordinator.data.muted
169  self._attr_media_content_id_attr_media_content_id = self.coordinator.data.currservice.serviceref
170  self._attr_media_image_url_attr_media_image_url = self.coordinator.device.picon_url
171  self._attr_source_attr_source = self.coordinator.data.currservice.station
172  self._attr_source_list_attr_source_list = self.coordinator.device.source_list
173 
174  if self.coordinator.data.in_standby:
175  self._attr_state_attr_state = MediaPlayerState.OFF
176  else:
177  self._attr_state_attr_state = MediaPlayerState.ON
178 
179  if (volume_level := self.coordinator.data.volume) is not None:
180  self._attr_volume_level_attr_volume_level = volume_level / 100
181  else:
182  self._attr_volume_level_attr_volume_level = None
183 
184  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, Enigma2UpdateCoordinator coordinator)
Definition: media_player.py:63
None async_setup_entry(HomeAssistant hass, Enigma2ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: media_player.py:38