Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Entity representing a Sonos battery level."""
2 
3 from __future__ import annotations
4 
5 import logging
6 
7 from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
8 from homeassistant.config_entries import ConfigEntry
9 from homeassistant.const import PERCENTAGE, EntityCategory
10 from homeassistant.core import HomeAssistant, callback
11 from homeassistant.helpers.dispatcher import async_dispatcher_connect
12 from homeassistant.helpers.entity_platform import AddEntitiesCallback
13 
14 from .const import (
15  SONOS_CREATE_AUDIO_FORMAT_SENSOR,
16  SONOS_CREATE_BATTERY,
17  SONOS_CREATE_FAVORITES_SENSOR,
18  SONOS_FAVORITES_UPDATED,
19  SOURCE_TV,
20 )
21 from .entity import SonosEntity, SonosPollingEntity
22 from .favorites import SonosFavorites
23 from .helpers import soco_error
24 from .speaker import SonosSpeaker
25 
26 _LOGGER = logging.getLogger(__name__)
27 
28 
30  hass: HomeAssistant,
31  config_entry: ConfigEntry,
32  async_add_entities: AddEntitiesCallback,
33 ) -> None:
34  """Set up Sonos from a config entry."""
35 
36  @callback
37  def _async_create_audio_format_entity(
38  speaker: SonosSpeaker, audio_format: str
39  ) -> None:
40  _LOGGER.debug("Creating audio input format sensor on %s", speaker.zone_name)
41  entity = SonosAudioInputFormatSensorEntity(speaker, audio_format)
42  async_add_entities([entity])
43 
44  @callback
45  def _async_create_battery_sensor(speaker: SonosSpeaker) -> None:
46  _LOGGER.debug("Creating battery level sensor on %s", speaker.zone_name)
47  entity = SonosBatteryEntity(speaker)
48  async_add_entities([entity])
49 
50  @callback
51  def _async_create_favorites_sensor(favorites: SonosFavorites) -> None:
52  _LOGGER.debug(
53  "Creating favorites sensor (%s items) for household %s",
54  favorites.count,
55  favorites.household_id,
56  )
57  entity = SonosFavoritesEntity(favorites)
58  async_add_entities([entity])
59 
60  config_entry.async_on_unload(
62  hass, SONOS_CREATE_AUDIO_FORMAT_SENSOR, _async_create_audio_format_entity
63  )
64  )
65  config_entry.async_on_unload(
67  hass, SONOS_CREATE_BATTERY, _async_create_battery_sensor
68  )
69  )
70 
71  config_entry.async_on_unload(
73  hass, SONOS_CREATE_FAVORITES_SENSOR, _async_create_favorites_sensor
74  )
75  )
76 
77 
79  """Representation of a Sonos Battery entity."""
80 
81  _attr_device_class = SensorDeviceClass.BATTERY
82  _attr_entity_category = EntityCategory.DIAGNOSTIC
83  _attr_native_unit_of_measurement = PERCENTAGE
84 
85  def __init__(self, speaker: SonosSpeaker) -> None:
86  """Initialize the battery sensor."""
87  super().__init__(speaker)
88  self._attr_unique_id_attr_unique_id = f"{self.soco.uid}-battery"
89 
90  async def _async_fallback_poll(self) -> None:
91  """Poll the device for the current state."""
92  await self.speakerspeaker.async_poll_battery()
93 
94  @property
95  def native_value(self) -> int | None:
96  """Return the state of the sensor."""
97  return self.speakerspeaker.battery_info.get("Level")
98 
99  @property
100  def available(self) -> bool:
101  """Return whether this device is available."""
102  return self.speakerspeaker.available and self.speakerspeaker.power_source is not None
103 
104 
106  """Representation of a Sonos audio import format sensor entity."""
107 
108  _attr_entity_category = EntityCategory.DIAGNOSTIC
109  _attr_translation_key = "audio_input_format"
110  _attr_should_poll = True
111 
112  def __init__(self, speaker: SonosSpeaker, audio_format: str) -> None:
113  """Initialize the audio input format sensor."""
114  super().__init__(speaker)
115  self._attr_unique_id_attr_unique_id = f"{self.soco.uid}-audio-format"
116  self._attr_native_value_attr_native_value = audio_format
117 
118  def poll_state(self) -> None:
119  """Poll the state if TV source is active and state has settled."""
120  if self.speakerspeaker.media.source_name != SOURCE_TV and self.statestatestatestate == "No input":
121  return
122  self._poll_state_poll_state()
123 
124  @soco_error()
125  def _poll_state(self) -> None:
126  """Poll the device for the current state."""
127  self._attr_native_value_attr_native_value = self.socosoco.soundbar_audio_input_format
128 
129  async def _async_fallback_poll(self) -> None:
130  """Provide a stub for required ABC method."""
131 
132 
133 class SonosFavoritesEntity(SensorEntity):
134  """Representation of a Sonos favorites info entity."""
135 
136  _attr_entity_registry_enabled_default = False
137  _attr_name = "Sonos favorites"
138  _attr_translation_key = "favorites"
139  _attr_native_unit_of_measurement = "items"
140  _attr_should_poll = False
141 
142  def __init__(self, favorites: SonosFavorites) -> None:
143  """Initialize the favorites sensor."""
144  self.favoritesfavorites = favorites
145  self._attr_unique_id_attr_unique_id = f"{favorites.household_id}-favorites"
146 
147  async def async_added_to_hass(self) -> None:
148  """Handle common setup when added to hass."""
149  await self._async_update_state_async_update_state()
150  self.async_on_removeasync_on_remove(
152  self.hasshass,
153  f"{SONOS_FAVORITES_UPDATED}-{self.favorites.household_id}",
154  self._async_update_state_async_update_state,
155  )
156  )
157 
158  async def _async_update_state(self) -> None:
159  self._attr_native_value_attr_native_value = self.favoritesfavorites.count
160  self._attr_extra_state_attributes_attr_extra_state_attributes = {
161  "items": {fav.item_id: fav.title for fav in self.favoritesfavorites}
162  }
163  self.async_write_ha_stateasync_write_ha_state()
None __init__(self, SonosSpeaker speaker, str audio_format)
Definition: sensor.py:112
None __init__(self, SonosSpeaker speaker)
Definition: sensor.py:85
None __init__(self, SonosFavorites favorites)
Definition: sensor.py:142
None async_on_remove(self, CALLBACK_TYPE func)
Definition: entity.py:1331
None async_setup_entry(HomeAssistant hass, ConfigEntry config_entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:33
Callable[[], None] async_dispatcher_connect(HomeAssistant hass, str signal, Callable[..., Any] target)
Definition: dispatcher.py:103