Add audio input format sensor to Sonos HT devices (#60884)
This commit is contained in:
parent
b61dede826
commit
cbf2bf2e1f
5 changed files with 60 additions and 3 deletions
|
@ -144,6 +144,7 @@ PLAYABLE_MEDIA_TYPES = [
|
|||
|
||||
SONOS_CHECK_ACTIVITY = "sonos_check_activity"
|
||||
SONOS_CREATE_ALARM = "sonos_create_alarm"
|
||||
SONOS_CREATE_AUDIO_FORMAT_SENSOR = "sonos_create_audio_format_sensor"
|
||||
SONOS_CREATE_BATTERY = "sonos_create_battery"
|
||||
SONOS_CREATE_SWITCHES = "sonos_create_switches"
|
||||
SONOS_CREATE_LEVELS = "sonos_create_levels"
|
||||
|
|
|
@ -7,9 +7,10 @@ from homeassistant.const import (
|
|||
ENTITY_CATEGORY_DIAGNOSTIC,
|
||||
PERCENTAGE,
|
||||
)
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
|
||||
from .const import SONOS_CREATE_BATTERY
|
||||
from .const import SONOS_CREATE_AUDIO_FORMAT_SENSOR, SONOS_CREATE_BATTERY
|
||||
from .entity import SonosEntity
|
||||
from .speaker import SonosSpeaker
|
||||
|
||||
|
@ -17,12 +18,27 @@ from .speaker import SonosSpeaker
|
|||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up Sonos from a config entry."""
|
||||
|
||||
async def _async_create_entity(speaker: SonosSpeaker) -> None:
|
||||
@callback
|
||||
def _async_create_audio_format_entity(
|
||||
speaker: SonosSpeaker, audio_format: str
|
||||
) -> None:
|
||||
entity = SonosAudioInputFormatSensorEntity(speaker, audio_format)
|
||||
async_add_entities([entity])
|
||||
|
||||
@callback
|
||||
def _async_create_battery_sensor(speaker: SonosSpeaker) -> None:
|
||||
entity = SonosBatteryEntity(speaker)
|
||||
async_add_entities([entity])
|
||||
|
||||
config_entry.async_on_unload(
|
||||
async_dispatcher_connect(hass, SONOS_CREATE_BATTERY, _async_create_entity)
|
||||
async_dispatcher_connect(
|
||||
hass, SONOS_CREATE_AUDIO_FORMAT_SENSOR, _async_create_audio_format_entity
|
||||
)
|
||||
)
|
||||
config_entry.async_on_unload(
|
||||
async_dispatcher_connect(
|
||||
hass, SONOS_CREATE_BATTERY, _async_create_battery_sensor
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
@ -64,3 +80,25 @@ class SonosBatteryEntity(SonosEntity, SensorEntity):
|
|||
def available(self) -> bool:
|
||||
"""Return whether this device is available."""
|
||||
return self.speaker.available and self.speaker.power_source
|
||||
|
||||
|
||||
class SonosAudioInputFormatSensorEntity(SonosEntity, SensorEntity):
|
||||
"""Representation of a Sonos audio import format sensor entity."""
|
||||
|
||||
_attr_entity_category = ENTITY_CATEGORY_DIAGNOSTIC
|
||||
_attr_icon = "mdi:import"
|
||||
_attr_should_poll = True
|
||||
|
||||
def __init__(self, speaker: SonosSpeaker, audio_format: str) -> None:
|
||||
"""Initialize the audio input format sensor."""
|
||||
super().__init__(speaker)
|
||||
self._attr_unique_id = f"{self.soco.uid}-audio-format"
|
||||
self._attr_name = f"{self.speaker.zone_name} Audio Input Format"
|
||||
self._attr_native_value = audio_format
|
||||
|
||||
def update(self) -> None:
|
||||
"""Poll the device for the current state."""
|
||||
self._attr_native_value = self.soco.soundbar_audio_input_format
|
||||
|
||||
async def _async_poll(self) -> None:
|
||||
"""Provide a stub for required ABC method."""
|
||||
|
|
|
@ -46,6 +46,7 @@ from .const import (
|
|||
SCAN_INTERVAL,
|
||||
SONOS_CHECK_ACTIVITY,
|
||||
SONOS_CREATE_ALARM,
|
||||
SONOS_CREATE_AUDIO_FORMAT_SENSOR,
|
||||
SONOS_CREATE_BATTERY,
|
||||
SONOS_CREATE_LEVELS,
|
||||
SONOS_CREATE_MEDIA_PLAYER,
|
||||
|
@ -240,6 +241,11 @@ class SonosSpeaker:
|
|||
|
||||
dispatcher_send(self.hass, SONOS_CREATE_LEVELS, self)
|
||||
|
||||
if audio_format := self.soco.soundbar_audio_input_format:
|
||||
dispatcher_send(
|
||||
self.hass, SONOS_CREATE_AUDIO_FORMAT_SENSOR, self, audio_format
|
||||
)
|
||||
|
||||
if battery_info := fetch_battery_info_or_none(self.soco):
|
||||
self.battery_info = battery_info
|
||||
# Battery events can be infrequent, polling is still necessary
|
||||
|
|
|
@ -74,6 +74,7 @@ def soco_fixture(music_library, speaker_info, battery_info, alarm_clock):
|
|||
mock_soco.treble = -1
|
||||
mock_soco.sub_enabled = False
|
||||
mock_soco.surround_enabled = True
|
||||
mock_soco.soundbar_audio_input_format = "Dolby 5.1"
|
||||
mock_soco.get_battery_info.return_value = battery_info
|
||||
mock_soco.all_zones = [mock_soco]
|
||||
yield mock_soco
|
||||
|
|
|
@ -123,3 +123,14 @@ async def test_device_payload_without_battery_and_ignored_keys(
|
|||
await hass.async_block_till_done()
|
||||
|
||||
assert ignored_payload not in caplog.text
|
||||
|
||||
|
||||
async def test_audio_input_sensor(hass, config_entry, config, soco):
|
||||
"""Test sonos device with battery state."""
|
||||
await setup_platform(hass, config_entry, config)
|
||||
|
||||
entity_registry = await hass.helpers.entity_registry.async_get_registry()
|
||||
|
||||
audio_input_sensor = entity_registry.entities["sensor.zone_a_audio_input_format"]
|
||||
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
|
||||
assert audio_input_state.state == "Dolby 5.1"
|
||||
|
|
Loading…
Add table
Reference in a new issue