Add code to HomeKit lock (#14524)
parent
cc5edf69e3
commit
4c328baaa6
|
@ -5,6 +5,7 @@ from pyhap.const import CATEGORY_DOOR_LOCK
|
|||
|
||||
from homeassistant.components.lock import (
|
||||
ATTR_ENTITY_ID, STATE_LOCKED, STATE_UNLOCKED, STATE_UNKNOWN)
|
||||
from homeassistant.const import ATTR_CODE
|
||||
|
||||
from . import TYPES
|
||||
from .accessories import HomeAccessory
|
||||
|
@ -32,6 +33,7 @@ class Lock(HomeAccessory):
|
|||
def __init__(self, *args):
|
||||
"""Initialize a Lock accessory object."""
|
||||
super().__init__(*args, category=CATEGORY_DOOR_LOCK)
|
||||
self._code = self.config.get(ATTR_CODE)
|
||||
self.flag_target_state = False
|
||||
|
||||
serv_lock_mechanism = self.add_preload_service(SERV_LOCK)
|
||||
|
@ -51,6 +53,8 @@ class Lock(HomeAccessory):
|
|||
service = STATE_TO_SERVICE[hass_value]
|
||||
|
||||
params = {ATTR_ENTITY_ID: self.entity_id}
|
||||
if self._code:
|
||||
params[ATTR_CODE] = self._code
|
||||
self.hass.services.call('lock', service, params)
|
||||
|
||||
def update_state(self, new_state):
|
||||
|
|
|
@ -30,7 +30,7 @@ def validate_entity_config(values):
|
|||
|
||||
domain, _ = split_entity_id(entity)
|
||||
|
||||
if domain == 'alarm_control_panel':
|
||||
if domain in ('alarm_control_panel', 'lock'):
|
||||
code = config.get(ATTR_CODE)
|
||||
params[ATTR_CODE] = cv.string(code) if code else None
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ def test_customize_options(config, name):
|
|||
@pytest.mark.parametrize('type_name, entity_id, state, attrs, config', [
|
||||
('Fan', 'fan.test', 'on', {}, {}),
|
||||
('Light', 'light.test', 'on', {}, {}),
|
||||
('Lock', 'lock.test', 'locked', {}, {}),
|
||||
('Lock', 'lock.test', 'locked', {}, {ATTR_CODE: '1234'}),
|
||||
|
||||
('Thermostat', 'climate.test', 'auto', {}, {}),
|
||||
('Thermostat', 'climate.test', 'auto',
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
"""Test different accessory types: Locks."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.homekit.type_locks import Lock
|
||||
from homeassistant.components.lock import DOMAIN
|
||||
from homeassistant.const import (
|
||||
ATTR_ENTITY_ID, STATE_UNKNOWN, STATE_UNLOCKED, STATE_LOCKED)
|
||||
ATTR_CODE, ATTR_ENTITY_ID, STATE_UNKNOWN, STATE_UNLOCKED, STATE_LOCKED)
|
||||
|
||||
from tests.common import async_mock_service
|
||||
|
||||
|
||||
async def test_lock_unlock(hass):
|
||||
"""Test if accessory and HA are updated accordingly."""
|
||||
code = '1234'
|
||||
config = {ATTR_CODE: code}
|
||||
entity_id = 'lock.kitchen_door'
|
||||
|
||||
hass.states.async_set(entity_id, None)
|
||||
await hass.async_block_till_done()
|
||||
acc = Lock(hass, 'Lock', entity_id, 2, None)
|
||||
acc = Lock(hass, 'Lock', entity_id, 2, config)
|
||||
await hass.async_add_job(acc.run)
|
||||
|
||||
assert acc.aid == 2
|
||||
|
@ -50,10 +54,32 @@ async def test_lock_unlock(hass):
|
|||
await hass.async_block_till_done()
|
||||
assert call_lock
|
||||
assert call_lock[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_lock[0].data[ATTR_CODE] == code
|
||||
assert acc.char_target_state.value == 1
|
||||
|
||||
await hass.async_add_job(acc.char_target_state.client_update_value, 0)
|
||||
await hass.async_block_till_done()
|
||||
assert call_unlock
|
||||
assert call_unlock[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert call_unlock[0].data[ATTR_CODE] == code
|
||||
assert acc.char_target_state.value == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize('config', [{}, {ATTR_CODE: None}])
|
||||
async def test_no_code(hass, config):
|
||||
"""Test accessory if lock doesn't require a code."""
|
||||
entity_id = 'lock.kitchen_door'
|
||||
|
||||
hass.states.async_set(entity_id, None)
|
||||
await hass.async_block_till_done()
|
||||
acc = Lock(hass, 'Lock', entity_id, 2, config)
|
||||
|
||||
# Set from HomeKit
|
||||
call_lock = async_mock_service(hass, DOMAIN, 'lock')
|
||||
|
||||
await hass.async_add_job(acc.char_target_state.client_update_value, 1)
|
||||
await hass.async_block_till_done()
|
||||
assert call_lock
|
||||
assert call_lock[0].data[ATTR_ENTITY_ID] == entity_id
|
||||
assert ATTR_CODE not in call_lock[0].data
|
||||
assert acc.char_target_state.value == 1
|
||||
|
|
|
@ -30,9 +30,16 @@ def test_validate_entity_config():
|
|||
assert vec({}) == {}
|
||||
assert vec({'demo.test': {CONF_NAME: 'Name'}}) == \
|
||||
{'demo.test': {CONF_NAME: 'Name'}}
|
||||
|
||||
assert vec({'alarm_control_panel.demo': {}}) == \
|
||||
{'alarm_control_panel.demo': {ATTR_CODE: None}}
|
||||
assert vec({'alarm_control_panel.demo': {ATTR_CODE: '1234'}}) == \
|
||||
{'alarm_control_panel.demo': {ATTR_CODE: '1234'}}
|
||||
|
||||
assert vec({'lock.demo': {}}) == {'lock.demo': {ATTR_CODE: None}}
|
||||
assert vec({'lock.demo': {ATTR_CODE: '1234'}}) == \
|
||||
{'lock.demo': {ATTR_CODE: '1234'}}
|
||||
|
||||
|
||||
def test_convert_to_float():
|
||||
"""Test convert_to_float method."""
|
||||
|
|
Loading…
Reference in New Issue