mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Skip polling Sonos audio input sensor when idle (#66271)
This commit is contained in:
parent
c6f3c5da79
commit
4d944e35fd
@ -11,7 +11,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from .const import SONOS_CREATE_AUDIO_FORMAT_SENSOR, SONOS_CREATE_BATTERY
|
||||
from .const import SONOS_CREATE_AUDIO_FORMAT_SENSOR, SONOS_CREATE_BATTERY, SOURCE_TV
|
||||
from .entity import SonosEntity, SonosPollingEntity
|
||||
from .helpers import soco_error
|
||||
from .speaker import SonosSpeaker
|
||||
@ -94,8 +94,14 @@ class SonosAudioInputFormatSensorEntity(SonosPollingEntity, SensorEntity):
|
||||
self._attr_name = f"{self.speaker.zone_name} Audio Input Format"
|
||||
self._attr_native_value = audio_format
|
||||
|
||||
@soco_error()
|
||||
def poll_state(self) -> None:
|
||||
"""Poll the state if TV source is active and state has settled."""
|
||||
if self.speaker.media.source_name != SOURCE_TV and self.state == "No input":
|
||||
return
|
||||
self._poll_state()
|
||||
|
||||
@soco_error()
|
||||
def _poll_state(self) -> None:
|
||||
"""Poll the device for the current state."""
|
||||
self._attr_native_value = self.soco.soundbar_audio_input_format
|
||||
|
||||
|
@ -3,6 +3,7 @@ from copy import copy
|
||||
from unittest.mock import AsyncMock, MagicMock, Mock, patch
|
||||
|
||||
import pytest
|
||||
from soco import SoCo
|
||||
|
||||
from homeassistant.components import ssdp, zeroconf
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
@ -82,7 +83,9 @@ def config_entry_fixture():
|
||||
|
||||
|
||||
@pytest.fixture(name="soco")
|
||||
def soco_fixture(music_library, speaker_info, battery_info, alarm_clock):
|
||||
def soco_fixture(
|
||||
music_library, speaker_info, current_track_info_empty, battery_info, alarm_clock
|
||||
):
|
||||
"""Create a mock soco SoCo fixture."""
|
||||
with patch("homeassistant.components.sonos.SoCo", autospec=True) as mock, patch(
|
||||
"socket.gethostbyname", return_value="192.168.42.2"
|
||||
@ -92,6 +95,8 @@ def soco_fixture(music_library, speaker_info, battery_info, alarm_clock):
|
||||
mock_soco.uid = "RINCON_test"
|
||||
mock_soco.play_mode = "NORMAL"
|
||||
mock_soco.music_library = music_library
|
||||
mock_soco.get_current_track_info.return_value = current_track_info_empty
|
||||
mock_soco.music_source_from_uri = SoCo.music_source_from_uri
|
||||
mock_soco.get_speaker_info.return_value = speaker_info
|
||||
mock_soco.avTransport = SonosMockService("AVTransport")
|
||||
mock_soco.renderingControl = SonosMockService("RenderingControl")
|
||||
@ -216,6 +221,22 @@ def speaker_info_fixture():
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="current_track_info_empty")
|
||||
def current_track_info_empty_fixture():
|
||||
"""Create current_track_info_empty fixture."""
|
||||
return {
|
||||
"title": "",
|
||||
"artist": "",
|
||||
"album": "",
|
||||
"album_art": "",
|
||||
"position": "NOT_IMPLEMENTED",
|
||||
"playlist_position": "1",
|
||||
"duration": "NOT_IMPLEMENTED",
|
||||
"uri": "",
|
||||
"metadata": "NOT_IMPLEMENTED",
|
||||
}
|
||||
|
||||
|
||||
@pytest.fixture(name="battery_info")
|
||||
def battery_info_fixture():
|
||||
"""Create battery_info fixture."""
|
||||
@ -254,6 +275,61 @@ def alarm_event_fixture(soco):
|
||||
return SonosMockEvent(soco, soco.alarmClock, variables)
|
||||
|
||||
|
||||
@pytest.fixture(name="no_media_event")
|
||||
def no_media_event_fixture(soco):
|
||||
"""Create no_media_event_fixture."""
|
||||
variables = {
|
||||
"current_crossfade_mode": "0",
|
||||
"current_play_mode": "NORMAL",
|
||||
"current_section": "0",
|
||||
"current_track_uri": "",
|
||||
"enqueued_transport_uri": "",
|
||||
"enqueued_transport_uri_meta_data": "",
|
||||
"transport_state": "STOPPED",
|
||||
}
|
||||
return SonosMockEvent(soco, soco.avTransport, variables)
|
||||
|
||||
|
||||
@pytest.fixture(name="tv_event")
|
||||
def tv_event_fixture(soco):
|
||||
"""Create alarm_event fixture."""
|
||||
variables = {
|
||||
"transport_state": "PLAYING",
|
||||
"current_play_mode": "NORMAL",
|
||||
"current_crossfade_mode": "0",
|
||||
"number_of_tracks": "1",
|
||||
"current_track": "1",
|
||||
"current_section": "0",
|
||||
"current_track_uri": f"x-sonos-htastream:{soco.uid}:spdif",
|
||||
"current_track_duration": "",
|
||||
"current_track_meta_data": {
|
||||
"title": " ",
|
||||
"parent_id": "-1",
|
||||
"item_id": "-1",
|
||||
"restricted": True,
|
||||
"resources": [],
|
||||
"desc": None,
|
||||
},
|
||||
"next_track_uri": "",
|
||||
"next_track_meta_data": "",
|
||||
"enqueued_transport_uri": "",
|
||||
"enqueued_transport_uri_meta_data": "",
|
||||
"playback_storage_medium": "NETWORK",
|
||||
"av_transport_uri": f"x-sonos-htastream:{soco.uid}:spdif",
|
||||
"av_transport_uri_meta_data": {
|
||||
"title": soco.uid,
|
||||
"parent_id": "0",
|
||||
"item_id": "spdif-input",
|
||||
"restricted": False,
|
||||
"resources": [],
|
||||
"desc": None,
|
||||
},
|
||||
"current_transport_actions": "Set, Play",
|
||||
"current_valid_play_modes": "",
|
||||
}
|
||||
return SonosMockEvent(soco, soco.avTransport, variables)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_get_source_ip(mock_get_source_ip):
|
||||
"""Mock network util's async_get_source_ip in all sonos tests."""
|
||||
|
@ -1,9 +1,15 @@
|
||||
"""Tests for the Sonos battery sensor platform."""
|
||||
from unittest.mock import PropertyMock
|
||||
|
||||
from soco.exceptions import NotSupportedException
|
||||
|
||||
from homeassistant.components.sensor import SCAN_INTERVAL
|
||||
from homeassistant.components.sonos.binary_sensor import ATTR_BATTERY_POWER_SOURCE
|
||||
from homeassistant.const import STATE_OFF, STATE_ON
|
||||
from homeassistant.helpers import entity_registry as ent_reg
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
|
||||
async def test_entity_registry_unsupported(hass, async_setup_sonos, soco):
|
||||
@ -113,14 +119,46 @@ async def test_device_payload_without_battery_and_ignored_keys(
|
||||
assert ignored_payload not in caplog.text
|
||||
|
||||
|
||||
async def test_audio_input_sensor(hass, async_autosetup_sonos, soco):
|
||||
async def test_audio_input_sensor(
|
||||
hass, async_autosetup_sonos, soco, tv_event, no_media_event
|
||||
):
|
||||
"""Test audio input sensor."""
|
||||
entity_registry = ent_reg.async_get(hass)
|
||||
|
||||
subscription = soco.avTransport.subscribe.return_value
|
||||
sub_callback = subscription.callback
|
||||
sub_callback(tv_event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
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"
|
||||
|
||||
# Set mocked input format to new value and ensure poll success
|
||||
no_input_mock = PropertyMock(return_value="No input")
|
||||
type(soco).soundbar_audio_input_format = no_input_mock
|
||||
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
no_input_mock.assert_called_once()
|
||||
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
|
||||
assert audio_input_state.state == "No input"
|
||||
|
||||
# Ensure state is not polled when source is not TV and state is already "No input"
|
||||
sub_callback(no_media_event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
unpolled_mock = PropertyMock(return_value="Will not be polled")
|
||||
type(soco).soundbar_audio_input_format = unpolled_mock
|
||||
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
unpolled_mock.assert_not_called()
|
||||
audio_input_state = hass.states.get(audio_input_sensor.entity_id)
|
||||
assert audio_input_state.state == "No input"
|
||||
|
||||
|
||||
async def test_microphone_binary_sensor(
|
||||
hass, async_autosetup_sonos, soco, device_properties_event
|
||||
|
Loading…
x
Reference in New Issue
Block a user