diff --git a/homeassistant/components/risco/binary_sensor.py b/homeassistant/components/risco/binary_sensor.py index b1f55dd8693..7c9733e2ab9 100644 --- a/homeassistant/components/risco/binary_sensor.py +++ b/homeassistant/components/risco/binary_sensor.py @@ -35,6 +35,10 @@ async def async_setup_entry( RiscoLocalAlarmedBinarySensor(local_data.system.id, zone_id, zone) for zone_id, zone in local_data.system.zones.items() ) + async_add_entities( + RiscoLocalArmedBinarySensor(local_data.system.id, zone_id, zone) + for zone_id, zone in local_data.system.zones.items() + ) else: coordinator: RiscoDataUpdateCoordinator = hass.data[DOMAIN][ config_entry.entry_id @@ -92,8 +96,6 @@ class RiscoLocalBinarySensor(RiscoLocalZoneEntity, BinarySensorEntity): class RiscoLocalAlarmedBinarySensor(RiscoLocalZoneEntity, BinarySensorEntity): """Representation whether a zone in Risco local is currently triggering an alarm.""" - _attr_should_poll = False - def __init__(self, system_id: str, zone_id: int, zone: Zone) -> None: """Init the zone.""" super().__init__( @@ -108,3 +110,22 @@ class RiscoLocalAlarmedBinarySensor(RiscoLocalZoneEntity, BinarySensorEntity): def is_on(self) -> bool | None: """Return true if sensor is on.""" return self._zone.alarmed + + +class RiscoLocalArmedBinarySensor(RiscoLocalZoneEntity, BinarySensorEntity): + """Representation whether a zone in Risco local is currently armed.""" + + def __init__(self, system_id: str, zone_id: int, zone: Zone) -> None: + """Init the zone.""" + super().__init__( + system_id=system_id, + name="Armed", + suffix="_armed", + zone_id=zone_id, + zone=zone, + ) + + @property + def is_on(self) -> bool | None: + """Return true if sensor is on.""" + return self._zone.armed diff --git a/homeassistant/components/risco/manifest.json b/homeassistant/components/risco/manifest.json index bd8bbfd715f..d31d148f4da 100644 --- a/homeassistant/components/risco/manifest.json +++ b/homeassistant/components/risco/manifest.json @@ -3,7 +3,7 @@ "name": "Risco", "config_flow": true, "documentation": "https://www.home-assistant.io/integrations/risco", - "requirements": ["pyrisco==0.5.5"], + "requirements": ["pyrisco==0.5.6"], "codeowners": ["@OnFreund"], "quality_scale": "platinum", "iot_class": "local_push", diff --git a/requirements_all.txt b/requirements_all.txt index ead4f05bf9d..6290759fe21 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1860,7 +1860,7 @@ pyrecswitch==1.0.2 pyrepetierng==0.1.0 # homeassistant.components.risco -pyrisco==0.5.5 +pyrisco==0.5.6 # homeassistant.components.rituals_perfume_genie pyrituals==0.0.6 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index d8661001022..d07aeff4b7b 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -1316,7 +1316,7 @@ pyps4-2ndscreen==1.3.1 pyqwikswitch==0.93 # homeassistant.components.risco -pyrisco==0.5.5 +pyrisco==0.5.6 # homeassistant.components.rituals_perfume_genie pyrituals==0.0.6 diff --git a/tests/components/risco/conftest.py b/tests/components/risco/conftest.py index cc65efd9b55..9d14cfdcff0 100644 --- a/tests/components/risco/conftest.py +++ b/tests/components/risco/conftest.py @@ -70,6 +70,8 @@ def two_zone_local(): zone_mocks[0], "alarmed", new_callable=PropertyMock(return_value=False) ), patch.object( zone_mocks[0], "bypassed", new_callable=PropertyMock(return_value=False) + ), patch.object( + zone_mocks[0], "armed", new_callable=PropertyMock(return_value=False) ), patch.object( zone_mocks[1], "id", new_callable=PropertyMock(return_value=1) ), patch.object( @@ -78,6 +80,8 @@ def two_zone_local(): zone_mocks[1], "alarmed", new_callable=PropertyMock(return_value=False) ), patch.object( zone_mocks[1], "bypassed", new_callable=PropertyMock(return_value=False) + ), patch.object( + zone_mocks[1], "armed", new_callable=PropertyMock(return_value=False) ), patch( "homeassistant.components.risco.RiscoLocal.partitions", new_callable=PropertyMock(return_value={}), diff --git a/tests/components/risco/test_binary_sensor.py b/tests/components/risco/test_binary_sensor.py index 00d10f6059e..1c331adc145 100644 --- a/tests/components/risco/test_binary_sensor.py +++ b/tests/components/risco/test_binary_sensor.py @@ -15,6 +15,8 @@ FIRST_ENTITY_ID = "binary_sensor.zone_0" SECOND_ENTITY_ID = "binary_sensor.zone_1" FIRST_ALARMED_ENTITY_ID = FIRST_ENTITY_ID + "_alarmed" SECOND_ALARMED_ENTITY_ID = SECOND_ENTITY_ID + "_alarmed" +FIRST_ARMED_ENTITY_ID = FIRST_ENTITY_ID + "_armed" +SECOND_ARMED_ENTITY_ID = SECOND_ENTITY_ID + "_armed" @pytest.mark.parametrize("exception", [CannotConnectError, UnauthorizedError]) @@ -95,33 +97,19 @@ async def test_local_setup(hass, two_zone_local, setup_risco_local): assert device.manufacturer == "Risco" -async def _check_local_state(hass, zones, triggered, entity_id, zone_id, callback): - with patch.object( - zones[zone_id], - "triggered", - new_callable=PropertyMock(return_value=triggered), - ): - await callback(zone_id, zones[zone_id]) - await hass.async_block_till_done() - - expected_triggered = STATE_ON if triggered else STATE_OFF - assert hass.states.get(entity_id).state == expected_triggered - assert hass.states.get(entity_id).attributes["zone_id"] == zone_id - - -async def _check_alarmed_local_state( - hass, zones, alarmed, entity_id, zone_id, callback +async def _check_local_state( + hass, zones, property, value, entity_id, zone_id, callback ): with patch.object( zones[zone_id], - "alarmed", - new_callable=PropertyMock(return_value=alarmed), + property, + new_callable=PropertyMock(return_value=value), ): await callback(zone_id, zones[zone_id]) await hass.async_block_till_done() - expected_alarmed = STATE_ON if alarmed else STATE_OFF - assert hass.states.get(entity_id).state == expected_alarmed + expected_value = STATE_ON if value else STATE_OFF + assert hass.states.get(entity_id).state == expected_value assert hass.states.get(entity_id).attributes["zone_id"] == zone_id @@ -134,34 +122,64 @@ def _mock_zone_handler(): async def test_local_states( hass, two_zone_local, _mock_zone_handler, setup_risco_local ): - """Test the various alarm states.""" + """Test the various zone states.""" callback = _mock_zone_handler.call_args.args[0] assert callback is not None - await _check_local_state(hass, two_zone_local, True, FIRST_ENTITY_ID, 0, callback) - await _check_local_state(hass, two_zone_local, False, FIRST_ENTITY_ID, 0, callback) - await _check_local_state(hass, two_zone_local, True, SECOND_ENTITY_ID, 1, callback) - await _check_local_state(hass, two_zone_local, False, SECOND_ENTITY_ID, 1, callback) + await _check_local_state( + hass, two_zone_local, "triggered", True, FIRST_ENTITY_ID, 0, callback + ) + await _check_local_state( + hass, two_zone_local, "triggered", False, FIRST_ENTITY_ID, 0, callback + ) + await _check_local_state( + hass, two_zone_local, "triggered", True, SECOND_ENTITY_ID, 1, callback + ) + await _check_local_state( + hass, two_zone_local, "triggered", False, SECOND_ENTITY_ID, 1, callback + ) async def test_alarmed_local_states( hass, two_zone_local, _mock_zone_handler, setup_risco_local ): - """Test the various alarm states.""" + """Test the various zone alarmed states.""" callback = _mock_zone_handler.call_args.args[0] assert callback is not None - await _check_alarmed_local_state( - hass, two_zone_local, True, FIRST_ALARMED_ENTITY_ID, 0, callback + await _check_local_state( + hass, two_zone_local, "alarmed", True, FIRST_ALARMED_ENTITY_ID, 0, callback ) - await _check_alarmed_local_state( - hass, two_zone_local, False, FIRST_ALARMED_ENTITY_ID, 0, callback + await _check_local_state( + hass, two_zone_local, "alarmed", False, FIRST_ALARMED_ENTITY_ID, 0, callback ) - await _check_alarmed_local_state( - hass, two_zone_local, True, SECOND_ALARMED_ENTITY_ID, 1, callback + await _check_local_state( + hass, two_zone_local, "alarmed", True, SECOND_ALARMED_ENTITY_ID, 1, callback ) - await _check_alarmed_local_state( - hass, two_zone_local, False, SECOND_ALARMED_ENTITY_ID, 1, callback + await _check_local_state( + hass, two_zone_local, "alarmed", False, SECOND_ALARMED_ENTITY_ID, 1, callback + ) + + +async def test_armed_local_states( + hass, two_zone_local, _mock_zone_handler, setup_risco_local +): + """Test the various zone armed states.""" + callback = _mock_zone_handler.call_args.args[0] + + assert callback is not None + + await _check_local_state( + hass, two_zone_local, "armed", True, FIRST_ARMED_ENTITY_ID, 0, callback + ) + await _check_local_state( + hass, two_zone_local, "armed", False, FIRST_ARMED_ENTITY_ID, 0, callback + ) + await _check_local_state( + hass, two_zone_local, "armed", True, SECOND_ARMED_ENTITY_ID, 1, callback + ) + await _check_local_state( + hass, two_zone_local, "armed", False, SECOND_ARMED_ENTITY_ID, 1, callback )