diff --git a/homeassistant/components/homekit/type_locks.py b/homeassistant/components/homekit/type_locks.py index b08ac5930bd..309f3072768 100644 --- a/homeassistant/components/homekit/type_locks.py +++ b/homeassistant/components/homekit/type_locks.py @@ -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): diff --git a/homeassistant/components/homekit/util.py b/homeassistant/components/homekit/util.py index 5ddef534202..5d86dbc4612 100644 --- a/homeassistant/components/homekit/util.py +++ b/homeassistant/components/homekit/util.py @@ -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 diff --git a/tests/components/homekit/test_get_accessories.py b/tests/components/homekit/test_get_accessories.py index a72f50f6c6f..0ffc1ae4767 100644 --- a/tests/components/homekit/test_get_accessories.py +++ b/tests/components/homekit/test_get_accessories.py @@ -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', diff --git a/tests/components/homekit/test_type_locks.py b/tests/components/homekit/test_type_locks.py index 984d032a1d9..3b8cde47fcb 100644 --- a/tests/components/homekit/test_type_locks.py +++ b/tests/components/homekit/test_type_locks.py @@ -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 diff --git a/tests/components/homekit/test_util.py b/tests/components/homekit/test_util.py index 0b3a5475f7e..f3ce35ee06b 100644 --- a/tests/components/homekit/test_util.py +++ b/tests/components/homekit/test_util.py @@ -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."""