Add HomeKit Door accessory type (#80741)

Co-authored-by: Jason Redd <jredd46@gmail.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Doney den Ouden 2023-03-07 05:07:43 +01:00 committed by GitHub
parent 3c70dd9b42
commit 755c44d152
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 82 additions and 0 deletions

View file

@ -148,6 +148,11 @@ def get_accessory( # noqa: C901
and features & CoverEntityFeature.SET_POSITION and features & CoverEntityFeature.SET_POSITION
): ):
a_type = "Window" a_type = "Window"
elif (
device_class == CoverDeviceClass.DOOR
and features & CoverEntityFeature.SET_POSITION
):
a_type = "Door"
elif features & CoverEntityFeature.SET_POSITION: elif features & CoverEntityFeature.SET_POSITION:
a_type = "WindowCovering" a_type = "WindowCovering"
elif features & (CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE): elif features & (CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE):

View file

@ -119,6 +119,7 @@ SERV_CAMERA_RTP_STREAM_MANAGEMENT = "CameraRTPStreamManagement"
SERV_CARBON_DIOXIDE_SENSOR = "CarbonDioxideSensor" SERV_CARBON_DIOXIDE_SENSOR = "CarbonDioxideSensor"
SERV_CARBON_MONOXIDE_SENSOR = "CarbonMonoxideSensor" SERV_CARBON_MONOXIDE_SENSOR = "CarbonMonoxideSensor"
SERV_CONTACT_SENSOR = "ContactSensor" SERV_CONTACT_SENSOR = "ContactSensor"
SERV_DOOR = "Door"
SERV_DOORBELL = "Doorbell" SERV_DOORBELL = "Doorbell"
SERV_FANV2 = "Fanv2" SERV_FANV2 = "Fanv2"
SERV_GARAGE_DOOR_OPENER = "GarageDoorOpener" SERV_GARAGE_DOOR_OPENER = "GarageDoorOpener"

View file

@ -2,6 +2,7 @@
import logging import logging
from pyhap.const import ( from pyhap.const import (
CATEGORY_DOOR,
CATEGORY_GARAGE_DOOR_OPENER, CATEGORY_GARAGE_DOOR_OPENER,
CATEGORY_WINDOW, CATEGORY_WINDOW,
CATEGORY_WINDOW_COVERING, CATEGORY_WINDOW_COVERING,
@ -54,6 +55,7 @@ from .const import (
HK_POSITION_STOPPED, HK_POSITION_STOPPED,
PROP_MAX_VALUE, PROP_MAX_VALUE,
PROP_MIN_VALUE, PROP_MIN_VALUE,
SERV_DOOR,
SERV_GARAGE_DOOR_OPENER, SERV_GARAGE_DOOR_OPENER,
SERV_WINDOW, SERV_WINDOW,
SERV_WINDOW_COVERING, SERV_WINDOW_COVERING,
@ -323,6 +325,18 @@ class OpeningDevice(OpeningDeviceBase, HomeAccessory):
super().async_update_state(new_state) super().async_update_state(new_state)
@TYPES.register("Door")
class Door(OpeningDevice):
"""Generate a Door accessory for a cover entity.
The entity must support: set_cover_position.
"""
def __init__(self, *args):
"""Initialize a Door accessory object."""
super().__init__(*args, category=CATEGORY_DOOR, service=SERV_DOOR)
@TYPES.register("Window") @TYPES.register("Window")
class Window(OpeningDevice): class Window(OpeningDevice):
"""Generate a Window accessory for a cover entity with WINDOW device class. """Generate a Window accessory for a cover entity with WINDOW device class.

View file

@ -160,6 +160,15 @@ def test_types(type_name, entity_id, state, attrs, config) -> None:
) )
}, },
), ),
(
"Door",
"cover.door",
"open",
{
ATTR_DEVICE_CLASS: "door",
ATTR_SUPPORTED_FEATURES: cover.SUPPORT_SET_POSITION,
},
),
], ],
) )
def test_type_covers(type_name, entity_id, state, attrs) -> None: def test_type_covers(type_name, entity_id, state, attrs) -> None:

View file

@ -19,6 +19,7 @@ from homeassistant.components.homekit.const import (
PROP_MIN_VALUE, PROP_MIN_VALUE,
) )
from homeassistant.components.homekit.type_covers import ( from homeassistant.components.homekit.type_covers import (
Door,
GarageDoorOpener, GarageDoorOpener,
Window, Window,
WindowCovering, WindowCovering,
@ -128,6 +129,58 @@ async def test_garage_door_open_close(hass: HomeAssistant, hk_driver, events) ->
assert events[-1].data[ATTR_VALUE] is None assert events[-1].data[ATTR_VALUE] is None
async def test_door_instantiate_set_position(
hass: HomeAssistant, hk_driver, events
) -> None:
"""Test if Door accessory is instantiated correctly and can set position."""
entity_id = "cover.door"
hass.states.async_set(
entity_id,
STATE_OPEN,
{
ATTR_SUPPORTED_FEATURES: CoverEntityFeature.SET_POSITION,
ATTR_CURRENT_POSITION: 0,
},
)
await hass.async_block_till_done()
acc = Door(hass, hk_driver, "Door", entity_id, 2, None)
await acc.run()
await hass.async_block_till_done()
assert acc.aid == 2
assert acc.category == 12 # Door
assert acc.char_current_position.value == 0
assert acc.char_target_position.value == 0
hass.states.async_set(
entity_id,
STATE_OPEN,
{
ATTR_SUPPORTED_FEATURES: CoverEntityFeature.SET_POSITION,
ATTR_CURRENT_POSITION: 50,
},
)
await hass.async_block_till_done()
assert acc.char_current_position.value == 50
assert acc.char_target_position.value == 50
assert acc.char_position_state.value == 2
hass.states.async_set(
entity_id,
STATE_OPEN,
{
ATTR_SUPPORTED_FEATURES: CoverEntityFeature.SET_POSITION,
ATTR_CURRENT_POSITION: "GARBAGE",
},
)
await hass.async_block_till_done()
assert acc.char_current_position.value == 50
assert acc.char_target_position.value == 50
assert acc.char_position_state.value == 2
async def test_windowcovering_set_cover_position( async def test_windowcovering_set_cover_position(
hass: HomeAssistant, hk_driver, events hass: HomeAssistant, hk_driver, events
) -> None: ) -> None: