From c79ee53ab121dda1540b2a4814a1533ca87ca8e1 Mon Sep 17 00:00:00 2001 From: Raman Gupta <7243222+raman325@users.noreply.github.com> Date: Mon, 9 Aug 2021 07:29:17 -0400 Subject: [PATCH] Use dict for zwave_js siren.available_tones (#54305) * Use dict for zwave_js siren.available_tones * update siren.turn_on service description --- homeassistant/components/siren/services.yaml | 2 +- homeassistant/components/zwave_js/siren.py | 18 ++----- tests/components/zwave_js/test_siren.py | 56 ++++++++++++++++++++ 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/siren/services.yaml b/homeassistant/components/siren/services.yaml index 8c5ed3be974..18bf782eaf2 100644 --- a/homeassistant/components/siren/services.yaml +++ b/homeassistant/components/siren/services.yaml @@ -7,7 +7,7 @@ turn_on: domain: siren fields: tone: - description: The tone to emit when turning the siren on. Must be supported by the integration. + description: The tone to emit when turning the siren on. When `available_tones` property is a map, either the key or the value can be used. Must be supported by the integration. example: fire required: false selector: diff --git a/homeassistant/components/zwave_js/siren.py b/homeassistant/components/zwave_js/siren.py index de74f55fa9a..c1b354f4faa 100644 --- a/homeassistant/components/zwave_js/siren.py +++ b/homeassistant/components/zwave_js/siren.py @@ -58,9 +58,9 @@ class ZwaveSirenEntity(ZWaveBaseEntity, SirenEntity): """Initialize a ZwaveSirenEntity entity.""" super().__init__(config_entry, client, info) # Entity class attributes - self._attr_available_tones = list( - self.info.primary_value.metadata.states.values() - ) + self._attr_available_tones = { + int(id): val for id, val in self.info.primary_value.metadata.states.items() + } self._attr_supported_features = ( SUPPORT_TURN_ON | SUPPORT_TURN_OFF | SUPPORT_VOLUME_SET ) @@ -82,23 +82,15 @@ class ZwaveSirenEntity(ZWaveBaseEntity, SirenEntity): async def async_turn_on(self, **kwargs: Any) -> None: """Turn the device on.""" - tone: str | None = kwargs.get(ATTR_TONE) + tone_id: int | None = kwargs.get(ATTR_TONE) options = {} if (volume := kwargs.get(ATTR_VOLUME_LEVEL)) is not None: options["volume"] = round(volume * 100) # Play the default tone if a tone isn't provided - if tone is None: + if tone_id is None: await self.async_set_value(ToneID.DEFAULT, options) return - tone_id = int( - next( - key - for key, value in self.info.primary_value.metadata.states.items() - if value == tone - ) - ) - await self.async_set_value(tone_id, options) async def async_turn_off(self, **kwargs: Any) -> None: diff --git a/tests/components/zwave_js/test_siren.py b/tests/components/zwave_js/test_siren.py index 937b2c0fa67..ebe437eb981 100644 --- a/tests/components/zwave_js/test_siren.py +++ b/tests/components/zwave_js/test_siren.py @@ -2,6 +2,7 @@ from zwave_js_server.event import Event from homeassistant.components.siren import ATTR_TONE, ATTR_VOLUME_LEVEL +from homeassistant.components.siren.const import ATTR_AVAILABLE_TONES from homeassistant.const import STATE_OFF, STATE_ON SIREN_ENTITY = "siren.indoor_siren_6_2" @@ -65,6 +66,39 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): assert state assert state.state == STATE_OFF + assert state.attributes.get(ATTR_AVAILABLE_TONES) == { + 0: "off", + 1: "01DING~1 (5 sec)", + 2: "02DING~1 (9 sec)", + 3: "03TRAD~1 (11 sec)", + 4: "04ELEC~1 (2 sec)", + 5: "05WEST~1 (13 sec)", + 6: "06CHIM~1 (7 sec)", + 7: "07CUCK~1 (31 sec)", + 8: "08TRAD~1 (6 sec)", + 9: "09SMOK~1 (11 sec)", + 10: "10SMOK~1 (6 sec)", + 11: "11FIRE~1 (35 sec)", + 12: "12COSE~1 (5 sec)", + 13: "13KLAX~1 (38 sec)", + 14: "14DEEP~1 (41 sec)", + 15: "15WARN~1 (37 sec)", + 16: "16TORN~1 (46 sec)", + 17: "17ALAR~1 (35 sec)", + 18: "18DEEP~1 (62 sec)", + 19: "19ALAR~1 (15 sec)", + 20: "20ALAR~1 (7 sec)", + 21: "21DIGI~1 (8 sec)", + 22: "22ALER~1 (64 sec)", + 23: "23SHIP~1 (4 sec)", + 25: "25CHRI~1 (4 sec)", + 26: "26GONG~1 (12 sec)", + 27: "27SING~1 (1 sec)", + 28: "28TONA~1 (5 sec)", + 29: "29UPWA~1 (2 sec)", + 30: "30DOOR~1 (27 sec)", + 255: "default", + } # Test turn on with default await hass.services.async_call( @@ -105,6 +139,28 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): client.async_send_command.reset_mock() + # Test turn on with specific tone ID and volume level + await hass.services.async_call( + "siren", + "turn_on", + { + "entity_id": SIREN_ENTITY, + ATTR_TONE: 1, + ATTR_VOLUME_LEVEL: 0.5, + }, + blocking=True, + ) + + assert len(client.async_send_command.call_args_list) == 1 + args = client.async_send_command.call_args[0][0] + assert args["command"] == "node.set_value" + assert args["nodeId"] == node.node_id + assert args["valueId"] == TONE_ID_VALUE_ID + assert args["value"] == 1 + assert args["options"] == {"volume": 50} + + client.async_send_command.reset_mock() + # Test turn off await hass.services.async_call( "siren",