[lock.zwave] Add set, get and clear usercodes for zwave locks (#5489)

* Add set, get and clear usercodes for zwave locks

* Fix CRLF
This commit is contained in:
John Arild Berentsen 2017-01-27 06:45:04 +01:00 committed by Paulus Schoutsen
parent 295a232374
commit d0538fe3aa
2 changed files with 153 additions and 22 deletions

View File

@ -1,21 +1,57 @@
lock: clear_usercode:
description: Lock all or specified locks description: Clear a usercode from lock
fields: fields:
entity_id: node_id:
description: Name of lock to lock description: Node id of the lock
example: 'lock.front_door' example: 18
code: code_slot:
description: An optional code to lock the lock with description: Code slot to clear code from
example: 1234 example: 1
unlock: get_usercode:
description: Unlock all or specified locks description: Retrieve a usercode from lock
fields: fields:
entity_id: node_id:
description: Name of lock to unlock description: Node id of the lock
example: 'lock.front_door' example: 18
code: code_slot:
description: An optional code to unlock the lock with description: Code slot to retrive a code from
example: 1234 example: 1
lock:
description: Lock all or specified locks
fields:
entity_id:
description: Name of lock to lock
example: 'lock.front_door'
code:
description: An optional code to lock the lock with
example: 1234
set_usercode:
description: Set a usercode to lock
fields:
node_id:
description: Node id of the lock
example: 18
code_slot:
description: Code slot to set the code
example: 1
usercode:
description: Code to set
example: 1234
unlock:
description: Unlock all or specified locks
fields:
entity_id:
description: Name of lock to unlock
example: 'lock.front_door'
code:
description: An optional code to unlock the lock with
example: 1234

View File

@ -7,14 +7,25 @@ https://home-assistant.io/components/lock.zwave/
# Because we do not compile openzwave on CI # Because we do not compile openzwave on CI
# pylint: disable=import-error # pylint: disable=import-error
import logging import logging
from os import path
import voluptuous as vol
from homeassistant.components.lock import DOMAIN, LockDevice from homeassistant.components.lock import DOMAIN, LockDevice
from homeassistant.components import zwave from homeassistant.components import zwave
from homeassistant.config import load_yaml_config_file
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
ATTR_NOTIFICATION = 'notification' ATTR_NOTIFICATION = 'notification'
ATTR_LOCK_STATUS = 'lock_status' ATTR_LOCK_STATUS = 'lock_status'
ATTR_CODE_SLOT = 'code_slot'
ATTR_USERCODE = 'usercode'
SERVICE_SET_USERCODE = 'set_usercode'
SERVICE_GET_USERCODE = 'get_usercode'
SERVICE_CLEAR_USERCODE = 'clear_usercode'
LOCK_NOTIFICATION = { LOCK_NOTIFICATION = {
1: 'Manual Lock', 1: 'Manual Lock',
2: 'Manual Unlock', 2: 'Manual Unlock',
@ -80,6 +91,22 @@ ALARM_TYPE_STD = [
113 113
] ]
SET_USERCODE_SCHEMA = vol.Schema({
vol.Required(zwave.const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(ATTR_CODE_SLOT): vol.Coerce(int),
vol.Required(ATTR_USERCODE): vol.Coerce(int),
})
GET_USERCODE_SCHEMA = vol.Schema({
vol.Required(zwave.const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(ATTR_CODE_SLOT): vol.Coerce(int),
})
CLEAR_USERCODE_SCHEMA = vol.Schema({
vol.Required(zwave.const.ATTR_NODE_ID): vol.Coerce(int),
vol.Required(ATTR_CODE_SLOT): vol.Coerce(int),
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
@ -90,13 +117,81 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]] node = zwave.NETWORK.nodes[discovery_info[zwave.const.ATTR_NODE_ID]]
value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]] value = node.values[discovery_info[zwave.const.ATTR_VALUE_ID]]
descriptions = load_yaml_config_file(
path.join(path.dirname(__file__), 'services.yaml'))
def set_usercode(service):
"""Set the usercode to index X on the lock."""
node_id = service.data.get(zwave.const.ATTR_NODE_ID)
lock_node = zwave.NETWORK.nodes[node_id]
code_slot = service.data.get(ATTR_CODE_SLOT)
usercode = service.data.get(ATTR_USERCODE)
for value in lock_node.get_values(
class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():
if value.index != code_slot:
continue
if len(str(usercode)) > 4:
_LOGGER.error('Invalid code provided: (%s)'
' usercode must %s or less digits',
usercode, len(value.data))
value.data = str(usercode)
break
def get_usercode(service):
"""Get a usercode at index X on the lock."""
node_id = service.data.get(zwave.const.ATTR_NODE_ID)
lock_node = zwave.NETWORK.nodes[node_id]
code_slot = service.data.get(ATTR_CODE_SLOT)
for value in lock_node.get_values(
class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():
if value.index != code_slot:
continue
_LOGGER.info('Usercode at slot %s is: %s', value.index, value.data)
break
def clear_usercode(service):
"""Set usercode to slot X on the lock."""
node_id = service.data.get(zwave.const.ATTR_NODE_ID)
lock_node = zwave.NETWORK.nodes[node_id]
code_slot = service.data.get(ATTR_CODE_SLOT)
data = ''
for value in lock_node.get_values(
class_id=zwave.const.COMMAND_CLASS_USER_CODE).values():
if value.index != code_slot:
continue
for i in range(len(value.data)):
data += '\0'
i += 1
_LOGGER.debug('Data to clear lock: %s', data)
value.data = data
_LOGGER.info('Usercode at slot %s is cleared', value.index)
break
if value.command_class != zwave.const.COMMAND_CLASS_DOOR_LOCK: if value.command_class != zwave.const.COMMAND_CLASS_DOOR_LOCK:
return return
if value.type != zwave.const.TYPE_BOOL: if value.type != zwave.const.TYPE_BOOL:
return return
if value.genre != zwave.const.GENRE_USER: if value.genre != zwave.const.GENRE_USER:
return return
if node.has_command_class(zwave.const.COMMAND_CLASS_USER_CODE):
hass.services.register(DOMAIN,
SERVICE_SET_USERCODE,
set_usercode,
descriptions.get(SERVICE_SET_USERCODE),
schema=SET_USERCODE_SCHEMA)
hass.services.register(DOMAIN,
SERVICE_GET_USERCODE,
get_usercode,
descriptions.get(SERVICE_GET_USERCODE),
schema=GET_USERCODE_SCHEMA)
hass.services.register(DOMAIN,
SERVICE_CLEAR_USERCODE,
clear_usercode,
descriptions.get(SERVICE_CLEAR_USERCODE),
schema=CLEAR_USERCODE_SCHEMA)
value.set_change_verified(False) value.set_change_verified(False)
add_devices([ZwaveLock(value)]) add_devices([ZwaveLock(value)])