diff --git a/homeassistant/components/homekit/const.py b/homeassistant/components/homekit/const.py index e38b86a7032..d8eec057191 100644 --- a/homeassistant/components/homekit/const.py +++ b/homeassistant/components/homekit/const.py @@ -129,6 +129,7 @@ SERV_OUTLET = "Outlet" SERV_SECURITY_SYSTEM = "SecuritySystem" SERV_SMOKE_SENSOR = "SmokeSensor" SERV_SPEAKER = "Speaker" +SERV_STATELESS_PROGRAMMABLE_SWITCH = "StatelessProgrammableSwitch" SERV_SWITCH = "Switch" SERV_TELEVISION = "Television" SERV_TELEVISION_SPEAKER = "TelevisionSpeaker" diff --git a/homeassistant/components/homekit/type_cameras.py b/homeassistant/components/homekit/type_cameras.py index 93b822f9e7a..91b13a93eca 100644 --- a/homeassistant/components/homekit/type_cameras.py +++ b/homeassistant/components/homekit/type_cameras.py @@ -54,6 +54,7 @@ from .const import ( SERV_DOORBELL, SERV_MOTION_SENSOR, SERV_SPEAKER, + SERV_STATELESS_PROGRAMMABLE_SWITCH, ) from .img_util import scale_jpeg_camera_image from .util import pid_is_alive @@ -211,6 +212,7 @@ class Camera(HomeAccessory, PyhapCamera): self._async_update_motion_state(state) self._char_doorbell_detected = None + self._char_doorbell_detected_switch = None self.linked_doorbell_sensor = self.config.get(CONF_LINKED_DOORBELL_SENSOR) if self.linked_doorbell_sensor: state = self.hass.states.get(self.linked_doorbell_sensor) @@ -220,6 +222,14 @@ class Camera(HomeAccessory, PyhapCamera): self._char_doorbell_detected = serv_doorbell.configure_char( CHAR_PROGRAMMABLE_SWITCH_EVENT, value=0, ) + serv_stateless_switch = self.add_preload_service( + SERV_STATELESS_PROGRAMMABLE_SWITCH + ) + self._char_doorbell_detected_switch = serv_stateless_switch.configure_char( + CHAR_PROGRAMMABLE_SWITCH_EVENT, + value=0, + valid_values={"SinglePress": DOORBELL_SINGLE_PRESS}, + ) serv_speaker = self.add_preload_service(SERV_SPEAKER) serv_speaker.configure_char(CHAR_MUTE, value=0) @@ -282,6 +292,7 @@ class Camera(HomeAccessory, PyhapCamera): if new_state.state == STATE_ON: self._char_doorbell_detected.set_value(DOORBELL_SINGLE_PRESS) + self._char_doorbell_detected_switch.set_value(DOORBELL_SINGLE_PRESS) _LOGGER.debug( "%s: Set linked doorbell %s sensor to %d", self.entity_id, diff --git a/tests/components/homekit/test_type_cameras.py b/tests/components/homekit/test_type_cameras.py index 9e8faa34d38..118ce2d9934 100644 --- a/tests/components/homekit/test_type_cameras.py +++ b/tests/components/homekit/test_type_cameras.py @@ -21,6 +21,7 @@ from homeassistant.components.homekit.const import ( DEVICE_CLASS_OCCUPANCY, SERV_DOORBELL, SERV_MOTION_SENSOR, + SERV_STATELESS_PROGRAMMABLE_SWITCH, VIDEO_CODEC_COPY, VIDEO_CODEC_H264_OMX, ) @@ -653,18 +654,28 @@ async def test_camera_with_linked_doorbell_sensor(hass, run_driver, events): assert char.value == 0 + service2 = acc.get_service(SERV_STATELESS_PROGRAMMABLE_SWITCH) + assert service2 + char2 = service.get_characteristic(CHAR_PROGRAMMABLE_SWITCH_EVENT) + assert char2 + + assert char2.value == 0 + hass.states.async_set( doorbell_entity_id, STATE_OFF, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY} ) await hass.async_block_till_done() assert char.value == 0 + assert char2.value == 0 char.set_value(True) + char2.set_value(True) hass.states.async_set( doorbell_entity_id, STATE_ON, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY} ) await hass.async_block_till_done() assert char.value == 0 + assert char2.value == 0 # Ensure we do not throw when the linked # doorbell sensor is removed @@ -673,6 +684,7 @@ async def test_camera_with_linked_doorbell_sensor(hass, run_driver, events): await acc.run_handler() await hass.async_block_till_done() assert char.value == 0 + assert char2.value == 0 async def test_camera_with_a_missing_linked_doorbell_sensor(hass, run_driver, events): @@ -703,3 +715,4 @@ async def test_camera_with_a_missing_linked_doorbell_sensor(hass, run_driver, ev assert acc.category == 17 # Camera assert not acc.get_service(SERV_DOORBELL) + assert not acc.get_service(SERV_STATELESS_PROGRAMMABLE_SWITCH)