Expose video doorbell button state to HomeKit (#38617)

This commit is contained in:
Austin Drummond 2020-08-06 18:47:39 -04:00 committed by GitHub
parent 8fe11fec04
commit 937d993a67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 0 deletions

View file

@ -129,6 +129,7 @@ SERV_OUTLET = "Outlet"
SERV_SECURITY_SYSTEM = "SecuritySystem" SERV_SECURITY_SYSTEM = "SecuritySystem"
SERV_SMOKE_SENSOR = "SmokeSensor" SERV_SMOKE_SENSOR = "SmokeSensor"
SERV_SPEAKER = "Speaker" SERV_SPEAKER = "Speaker"
SERV_STATELESS_PROGRAMMABLE_SWITCH = "StatelessProgrammableSwitch"
SERV_SWITCH = "Switch" SERV_SWITCH = "Switch"
SERV_TELEVISION = "Television" SERV_TELEVISION = "Television"
SERV_TELEVISION_SPEAKER = "TelevisionSpeaker" SERV_TELEVISION_SPEAKER = "TelevisionSpeaker"

View file

@ -54,6 +54,7 @@ from .const import (
SERV_DOORBELL, SERV_DOORBELL,
SERV_MOTION_SENSOR, SERV_MOTION_SENSOR,
SERV_SPEAKER, SERV_SPEAKER,
SERV_STATELESS_PROGRAMMABLE_SWITCH,
) )
from .img_util import scale_jpeg_camera_image from .img_util import scale_jpeg_camera_image
from .util import pid_is_alive from .util import pid_is_alive
@ -211,6 +212,7 @@ class Camera(HomeAccessory, PyhapCamera):
self._async_update_motion_state(state) self._async_update_motion_state(state)
self._char_doorbell_detected = None self._char_doorbell_detected = None
self._char_doorbell_detected_switch = None
self.linked_doorbell_sensor = self.config.get(CONF_LINKED_DOORBELL_SENSOR) self.linked_doorbell_sensor = self.config.get(CONF_LINKED_DOORBELL_SENSOR)
if self.linked_doorbell_sensor: if self.linked_doorbell_sensor:
state = self.hass.states.get(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( self._char_doorbell_detected = serv_doorbell.configure_char(
CHAR_PROGRAMMABLE_SWITCH_EVENT, value=0, 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 = self.add_preload_service(SERV_SPEAKER)
serv_speaker.configure_char(CHAR_MUTE, value=0) serv_speaker.configure_char(CHAR_MUTE, value=0)
@ -282,6 +292,7 @@ class Camera(HomeAccessory, PyhapCamera):
if new_state.state == STATE_ON: if new_state.state == STATE_ON:
self._char_doorbell_detected.set_value(DOORBELL_SINGLE_PRESS) self._char_doorbell_detected.set_value(DOORBELL_SINGLE_PRESS)
self._char_doorbell_detected_switch.set_value(DOORBELL_SINGLE_PRESS)
_LOGGER.debug( _LOGGER.debug(
"%s: Set linked doorbell %s sensor to %d", "%s: Set linked doorbell %s sensor to %d",
self.entity_id, self.entity_id,

View file

@ -21,6 +21,7 @@ from homeassistant.components.homekit.const import (
DEVICE_CLASS_OCCUPANCY, DEVICE_CLASS_OCCUPANCY,
SERV_DOORBELL, SERV_DOORBELL,
SERV_MOTION_SENSOR, SERV_MOTION_SENSOR,
SERV_STATELESS_PROGRAMMABLE_SWITCH,
VIDEO_CODEC_COPY, VIDEO_CODEC_COPY,
VIDEO_CODEC_H264_OMX, VIDEO_CODEC_H264_OMX,
) )
@ -653,18 +654,28 @@ async def test_camera_with_linked_doorbell_sensor(hass, run_driver, events):
assert char.value == 0 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( hass.states.async_set(
doorbell_entity_id, STATE_OFF, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY} doorbell_entity_id, STATE_OFF, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY}
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert char.value == 0 assert char.value == 0
assert char2.value == 0
char.set_value(True) char.set_value(True)
char2.set_value(True)
hass.states.async_set( hass.states.async_set(
doorbell_entity_id, STATE_ON, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY} doorbell_entity_id, STATE_ON, {ATTR_DEVICE_CLASS: DEVICE_CLASS_OCCUPANCY}
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert char.value == 0 assert char.value == 0
assert char2.value == 0
# Ensure we do not throw when the linked # Ensure we do not throw when the linked
# doorbell sensor is removed # 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 acc.run_handler()
await hass.async_block_till_done() await hass.async_block_till_done()
assert char.value == 0 assert char.value == 0
assert char2.value == 0
async def test_camera_with_a_missing_linked_doorbell_sensor(hass, run_driver, events): 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 acc.category == 17 # Camera
assert not acc.get_service(SERV_DOORBELL) assert not acc.get_service(SERV_DOORBELL)
assert not acc.get_service(SERV_STATELESS_PROGRAMMABLE_SWITCH)