diff --git a/homeassistant/components/sonos/binary_sensor.py b/homeassistant/components/sonos/binary_sensor.py index 534e5f5dd02..4eaa75f92ae 100644 --- a/homeassistant/components/sonos/binary_sensor.py +++ b/homeassistant/components/sonos/binary_sensor.py @@ -16,6 +16,7 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import SONOS_CREATE_BATTERY, SONOS_CREATE_MIC_SENSOR from .entity import SonosEntity +from .helpers import soco_error from .speaker import SonosSpeaker ATTR_BATTERY_POWER_SOURCE = "power_source" @@ -99,7 +100,13 @@ class SonosMicrophoneSensorEntity(SonosEntity, BinarySensorEntity): self._attr_name = f"{self.speaker.zone_name} Microphone" async def _async_fallback_poll(self) -> None: - """Stub for abstract class implementation. Not a pollable attribute.""" + """Handle polling when subscription fails.""" + await self.hass.async_add_executor_job(self.poll_state) + + @soco_error() + def poll_state(self) -> None: + """Poll the current state of the microphone.""" + self.speaker.mic_enabled = self.soco.mic_enabled @property def is_on(self) -> bool: diff --git a/homeassistant/components/sonos/speaker.py b/homeassistant/components/sonos/speaker.py index 16ca58448e2..018eab4ca04 100644 --- a/homeassistant/components/sonos/speaker.py +++ b/homeassistant/components/sonos/speaker.py @@ -263,6 +263,10 @@ class SonosSpeaker: ) dispatcher_send(self.hass, SONOS_CREATE_BATTERY, self) + if (mic_enabled := self.soco.mic_enabled) is not None: + self.mic_enabled = mic_enabled + dispatcher_send(self.hass, SONOS_CREATE_MIC_SENSOR, self) + if new_alarms := [ alarm.alarm_id for alarm in self.alarms if alarm.zone.uid == self.soco.uid ]: diff --git a/tests/components/sonos/conftest.py b/tests/components/sonos/conftest.py index bc49c12ed81..70061e88692 100644 --- a/tests/components/sonos/conftest.py +++ b/tests/components/sonos/conftest.py @@ -112,6 +112,7 @@ def soco_fixture( mock_soco.audio_delay = 2 mock_soco.bass = 1 mock_soco.treble = -1 + mock_soco.mic_enabled = False mock_soco.sub_enabled = False mock_soco.surround_enabled = True mock_soco.soundbar_audio_input_format = "Dolby 5.1" diff --git a/tests/components/sonos/test_sensor.py b/tests/components/sonos/test_sensor.py index bda4e08cd25..8a51ea5b2e6 100644 --- a/tests/components/sonos/test_sensor.py +++ b/tests/components/sonos/test_sensor.py @@ -165,13 +165,16 @@ async def test_microphone_binary_sensor( ): """Test microphone binary sensor.""" entity_registry = ent_reg.async_get(hass) - assert "binary_sensor.zone_a_microphone" not in entity_registry.entities + assert "binary_sensor.zone_a_microphone" in entity_registry.entities + + mic_binary_sensor = entity_registry.entities["binary_sensor.zone_a_microphone"] + mic_binary_sensor_state = hass.states.get(mic_binary_sensor.entity_id) + assert mic_binary_sensor_state.state == STATE_OFF # Update the speaker with a callback event subscription = soco.deviceProperties.subscribe.return_value subscription.callback(device_properties_event) await hass.async_block_till_done() - mic_binary_sensor = entity_registry.entities["binary_sensor.zone_a_microphone"] mic_binary_sensor_state = hass.states.get(mic_binary_sensor.entity_id) assert mic_binary_sensor_state.state == STATE_ON