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:
parent
3c70dd9b42
commit
755c44d152
5 changed files with 82 additions and 0 deletions
|
@ -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):
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue