Skip to content

Commit

Permalink
Fix songpal crash for soundbars without sound modes (home-assistant#1…
Browse files Browse the repository at this point in the history
…19999)

Getting soundField on soundbar that doesn't support it crash raise an exception, so it make the whole components unavailable. As there is no simple way to know if soundField is supported, I just get all sound settings, and then pick soundField one if present. If not present, then return None to make it continue, it will just have to effect to display no sound mode and not able to select one (Exactly what we want).
  • Loading branch information
BestPig authored Jun 20, 2024
1 parent 99cae16 commit 7c5fcec
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
7 changes: 6 additions & 1 deletion homeassistant/components/songpal/media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,12 @@ async def async_will_remove_from_hass(self) -> None:

async def _get_sound_modes_info(self):
"""Get available sound modes and the active one."""
settings = await self._dev.get_sound_settings("soundField")
for settings in await self._dev.get_sound_settings():
if settings.target == "soundField":
break
else:
return None, {}

if isinstance(settings, Setting):
settings = [settings]

Expand Down
13 changes: 11 additions & 2 deletions tests/components/songpal/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
}


def _create_mocked_device(throw_exception=False, wired_mac=MAC, wireless_mac=None):
def _create_mocked_device(
throw_exception=False, wired_mac=MAC, wireless_mac=None, no_soundfield=False
):
mocked_device = MagicMock()

type(mocked_device).get_supported_methods = AsyncMock(
Expand Down Expand Up @@ -101,7 +103,14 @@ def _create_mocked_device(throw_exception=False, wired_mac=MAC, wireless_mac=Non
soundField = MagicMock()
soundField.currentValue = "sound_mode2"
soundField.candidate = [sound_mode1, sound_mode2, sound_mode3]
type(mocked_device).get_sound_settings = AsyncMock(return_value=[soundField])

settings = MagicMock()
settings.target = "soundField"
settings.__iter__.return_value = [soundField]

type(mocked_device).get_sound_settings = AsyncMock(
return_value=[] if no_soundfield else [settings]
)

type(mocked_device).set_power = AsyncMock()
type(mocked_device).set_sound_settings = AsyncMock()
Expand Down
37 changes: 37 additions & 0 deletions tests/components/songpal/test_media_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,43 @@ async def test_state(
assert entity.unique_id == MAC


async def test_state_nosoundmode(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
entity_registry: er.EntityRegistry,
) -> None:
"""Test state of the entity with no soundField in sound settings."""
mocked_device = _create_mocked_device(no_soundfield=True)
entry = MockConfigEntry(domain=songpal.DOMAIN, data=CONF_DATA)
entry.add_to_hass(hass)

with _patch_media_player_device(mocked_device):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()

state = hass.states.get(ENTITY_ID)
assert state.name == FRIENDLY_NAME
assert state.state == STATE_ON
attributes = state.as_dict()["attributes"]
assert attributes["volume_level"] == 0.5
assert attributes["is_volume_muted"] is False
assert attributes["source_list"] == ["title1", "title2"]
assert attributes["source"] == "title2"
assert "sound_mode_list" not in attributes
assert "sound_mode" not in attributes
assert attributes["supported_features"] == SUPPORT_SONGPAL

device = device_registry.async_get_device(identifiers={(songpal.DOMAIN, MAC)})
assert device.connections == {(dr.CONNECTION_NETWORK_MAC, MAC)}
assert device.manufacturer == "Sony Corporation"
assert device.name == FRIENDLY_NAME
assert device.sw_version == SW_VERSION
assert device.model == MODEL

entity = entity_registry.async_get(ENTITY_ID)
assert entity.unique_id == MAC


async def test_state_wireless(
hass: HomeAssistant,
device_registry: dr.DeviceRegistry,
Expand Down

0 comments on commit 7c5fcec

Please sign in to comment.