diff --git a/homeassistant/components/zwave_js/siren.py b/homeassistant/components/zwave_js/siren.py index 4ef89b9f4cd..a3fe3dfd595 100644 --- a/homeassistant/components/zwave_js/siren.py +++ b/homeassistant/components/zwave_js/siren.py @@ -68,8 +68,10 @@ class ZwaveSirenEntity(ZWaveBaseEntity, SirenEntity): self._attr_supported_features |= SUPPORT_TONES @property - def is_on(self) -> bool: + def is_on(self) -> bool | None: """Return whether device is on.""" + if self.info.primary_value.value is None: + return None return bool(self.info.primary_value.value) async def async_set_value( diff --git a/tests/components/zwave_js/test_siren.py b/tests/components/zwave_js/test_siren.py index ebe437eb981..b1f7724316a 100644 --- a/tests/components/zwave_js/test_siren.py +++ b/tests/components/zwave_js/test_siren.py @@ -3,7 +3,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 +from homeassistant.const import STATE_OFF, STATE_ON, STATE_UNKNOWN SIREN_ENTITY = "siren.indoor_siren_6_2" @@ -65,7 +65,7 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): state = hass.states.get(SIREN_ENTITY) assert state - assert state.state == STATE_OFF + assert state.state == STATE_UNKNOWN assert state.attributes.get(ATTR_AVAILABLE_TONES) == { 0: "off", 1: "01DING~1 (5 sec)", @@ -117,6 +117,29 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): client.async_send_command.reset_mock() + # Test value update from value updated event + event = Event( + type="value updated", + data={ + "source": "node", + "event": "value updated", + "nodeId": node.node_id, + "args": { + "commandClassName": "Sound Switch", + "commandClass": 121, + "endpoint": 2, + "property": "toneId", + "newValue": 255, + "prevValue": None, + "propertyName": "toneId", + }, + }, + ) + node.receive_event(event) + + state = hass.states.get(SIREN_ENTITY) + assert state.state == STATE_ON + # Test turn on with specific tone name and volume level await hass.services.async_call( "siren", @@ -133,7 +156,7 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): 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["valueId"] == {**TONE_ID_VALUE_ID, "value": 255} assert args["value"] == 1 assert args["options"] == {"volume": 50} @@ -155,7 +178,7 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): 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["valueId"] == {**TONE_ID_VALUE_ID, "value": 255} assert args["value"] == 1 assert args["options"] == {"volume": 50} @@ -173,7 +196,7 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): 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["valueId"] == {**TONE_ID_VALUE_ID, "value": 255} assert args["value"] == 0 client.async_send_command.reset_mock() @@ -190,8 +213,8 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): "commandClass": 121, "endpoint": 2, "property": "toneId", - "newValue": 255, - "prevValue": 0, + "newValue": 0, + "prevValue": 255, "propertyName": "toneId", }, }, @@ -199,4 +222,4 @@ async def test_siren(hass, client, aeotec_zw164_siren, integration): node.receive_event(event) state = hass.states.get(SIREN_ENTITY) - assert state.state == STATE_ON + assert state.state == STATE_OFF