Add siren support for available tones provided as a dict (#54198)

* Add siren support for available tones provided as a dict

* remove paranthesis

* hopefully make logic even easier to read

* drop last parenthesis
This commit is contained in:
Raman Gupta 2021-08-09 00:41:51 -04:00 committed by GitHub
parent 557cc792e9
commit 2e903c92c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 8 deletions

View file

@ -64,10 +64,29 @@ def process_turn_on_params(
if not supported_features & SUPPORT_TONES:
params.pop(ATTR_TONE, None)
elif (tone := params.get(ATTR_TONE)) is not None and (
not siren.available_tones or tone not in siren.available_tones
):
raise ValueError(f"Invalid tone received for entity {siren.entity_id}: {tone}")
elif (tone := params.get(ATTR_TONE)) is not None:
# Raise an exception if the specified tone isn't available
is_tone_dict_value = bool(
isinstance(siren.available_tones, dict)
and tone in siren.available_tones.values()
)
if (
not siren.available_tones
or tone not in siren.available_tones
and not is_tone_dict_value
):
raise ValueError(
f"Invalid tone specified for entity {siren.entity_id}: {tone}, "
"check the available_tones attribute for valid tones to pass in"
)
# If available tones is a dict, and the tone provided is a dict value, we need
# to transform it to the corresponding dict key before returning
if is_tone_dict_value:
assert isinstance(siren.available_tones, dict)
params[ATTR_TONE] = next(
key for key, value in siren.available_tones.items() if value == tone
)
if not supported_features & SUPPORT_DURATION:
params.pop(ATTR_DURATION, None)
@ -131,7 +150,7 @@ class SirenEntity(ToggleEntity):
"""Representation of a siren device."""
entity_description: SirenEntityDescription
_attr_available_tones: list[int | str] | None = None
_attr_available_tones: list[int | str] | dict[int, str] | None = None
@final
@property
@ -145,7 +164,7 @@ class SirenEntity(ToggleEntity):
return None
@property
def available_tones(self) -> list[int | str] | None:
def available_tones(self) -> list[int | str] | dict[int, str] | None:
"""
Return a list of available tones.

View file

@ -48,9 +48,32 @@ async def test_no_available_tones(hass):
process_turn_on_params(siren, {"tone": "test"})
async def test_missing_tones(hass):
"""Test ValueError when setting a tone that is missing from available_tones."""
async def test_available_tones_list(hass):
"""Test that valid tones from tone list will get passed in."""
siren = MockSirenEntity(SUPPORT_TONES, ["a", "b"])
siren.hass = hass
assert process_turn_on_params(siren, {"tone": "a"}) == {"tone": "a"}
async def test_available_tones_dict(hass):
"""Test that valid tones from available_tones dict will get passed in."""
siren = MockSirenEntity(SUPPORT_TONES, {1: "a", 2: "b"})
siren.hass = hass
assert process_turn_on_params(siren, {"tone": "a"}) == {"tone": 1}
assert process_turn_on_params(siren, {"tone": 1}) == {"tone": 1}
async def test_missing_tones_list(hass):
"""Test ValueError when setting a tone that is missing from available_tones list."""
siren = MockSirenEntity(SUPPORT_TONES, ["a", "b"])
siren.hass = hass
with pytest.raises(ValueError):
process_turn_on_params(siren, {"tone": "test"})
async def test_missing_tones_dict(hass):
"""Test ValueError when setting a tone that is missing from available_tones dict."""
siren = MockSirenEntity(SUPPORT_TONES, {1: "a", 2: "b"})
siren.hass = hass
with pytest.raises(ValueError):
process_turn_on_params(siren, {"tone": 3})