Add audio input format sensor to Sonos HT devices (#60884)

This commit is contained in:
jjlawren 2021-12-03 12:06:56 -06:00 committed by GitHub
parent b61dede826
commit cbf2bf2e1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 3 deletions

View file

@ -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"

View file

@ -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."""

View file

@ -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

View file

@ -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

View file

@ -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"