mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
[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:
parent
295a232374
commit
d0538fe3aa
@ -1,3 +1,25 @@
|
|||||||
|
clear_usercode:
|
||||||
|
description: Clear a usercode from lock
|
||||||
|
|
||||||
|
fields:
|
||||||
|
node_id:
|
||||||
|
description: Node id of the lock
|
||||||
|
example: 18
|
||||||
|
code_slot:
|
||||||
|
description: Code slot to clear code from
|
||||||
|
example: 1
|
||||||
|
|
||||||
|
get_usercode:
|
||||||
|
description: Retrieve a usercode from lock
|
||||||
|
|
||||||
|
fields:
|
||||||
|
node_id:
|
||||||
|
description: Node id of the lock
|
||||||
|
example: 18
|
||||||
|
code_slot:
|
||||||
|
description: Code slot to retrive a code from
|
||||||
|
example: 1
|
||||||
|
|
||||||
lock:
|
lock:
|
||||||
description: Lock all or specified locks
|
description: Lock all or specified locks
|
||||||
|
|
||||||
@ -9,6 +31,20 @@ lock:
|
|||||||
description: An optional code to lock the lock with
|
description: An optional code to lock the lock with
|
||||||
example: 1234
|
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:
|
unlock:
|
||||||
description: Unlock all or specified locks
|
description: Unlock all or specified locks
|
||||||
|
|
||||||
|
@ -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)])
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user