Refactor permit services to allow joining using install codes (#40652)
* Update zha.permit schema to support install code * Move install code to core helpers * QR code converter for enbrighten * Fix schemas * Update test for permit service * Refactor zha.permit to accept install codes * Test zha.permit from QR code * Fix regex for Embrighten QR code * Add regex for Aqara QR codes * Add Consciot regex for QR code * Reuse test params for WS tests * ZHA WS permit command with install code * Tests for zha.permit WS service * Refactor zha.permit and zha.remove service to use ATTR_IEEE for the address * Make pylint happy * Deprecate only ieee_address param for now
This commit is contained in:
parent
b9823791f7
commit
47286fbe2a
4 changed files with 400 additions and 23 deletions
|
@ -23,6 +23,7 @@ from .core.const import (
|
|||
ATTR_COMMAND,
|
||||
ATTR_COMMAND_TYPE,
|
||||
ATTR_ENDPOINT_ID,
|
||||
ATTR_IEEE,
|
||||
ATTR_LEVEL,
|
||||
ATTR_MANUFACTURER,
|
||||
ATTR_MEMBERS,
|
||||
|
@ -54,7 +55,12 @@ from .core.const import (
|
|||
WARNING_DEVICE_STROBE_YES,
|
||||
)
|
||||
from .core.group import GroupMember
|
||||
from .core.helpers import async_is_bindable_target, get_matched_clusters
|
||||
from .core.helpers import (
|
||||
async_is_bindable_target,
|
||||
convert_install_code,
|
||||
get_matched_clusters,
|
||||
qr_to_install_code,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -67,9 +73,10 @@ DEVICE_INFO = "device_info"
|
|||
ATTR_DURATION = "duration"
|
||||
ATTR_GROUP = "group"
|
||||
ATTR_IEEE_ADDRESS = "ieee_address"
|
||||
ATTR_IEEE = "ieee"
|
||||
ATTR_INSTALL_CODE = "install_code"
|
||||
ATTR_SOURCE_IEEE = "source_ieee"
|
||||
ATTR_TARGET_IEEE = "target_ieee"
|
||||
ATTR_QR_CODE = "qr_code"
|
||||
|
||||
SERVICE_PERMIT = "permit"
|
||||
SERVICE_REMOVE = "remove"
|
||||
|
@ -83,16 +90,29 @@ SERVICE_WARNING_DEVICE_WARN = "warning_device_warn"
|
|||
SERVICE_ZIGBEE_BIND = "service_zigbee_bind"
|
||||
IEEE_SERVICE = "ieee_based_service"
|
||||
|
||||
SERVICE_PERMIT_PARAMS = {
|
||||
vol.Optional(ATTR_IEEE, default=None): EUI64.convert,
|
||||
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
||||
vol.Coerce(int), vol.Range(0, 254)
|
||||
),
|
||||
vol.Inclusive(ATTR_SOURCE_IEEE, "install_code"): EUI64.convert,
|
||||
vol.Inclusive(ATTR_INSTALL_CODE, "install_code"): convert_install_code,
|
||||
vol.Exclusive(ATTR_QR_CODE, "install_code"): vol.All(str, qr_to_install_code),
|
||||
}
|
||||
|
||||
SERVICE_SCHEMAS = {
|
||||
SERVICE_PERMIT: vol.Schema(
|
||||
{
|
||||
vol.Optional(ATTR_IEEE_ADDRESS, default=None): EUI64.convert,
|
||||
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
||||
vol.Coerce(int), vol.Range(0, 254)
|
||||
),
|
||||
}
|
||||
vol.All(
|
||||
cv.deprecated(ATTR_IEEE_ADDRESS, replacement_key=ATTR_IEEE),
|
||||
SERVICE_PERMIT_PARAMS,
|
||||
)
|
||||
),
|
||||
IEEE_SERVICE: vol.Schema(
|
||||
vol.All(
|
||||
cv.deprecated(ATTR_IEEE_ADDRESS, replacement_key=ATTR_IEEE),
|
||||
{vol.Required(ATTR_IEEE): EUI64.convert},
|
||||
)
|
||||
),
|
||||
IEEE_SERVICE: vol.Schema({vol.Required(ATTR_IEEE_ADDRESS): EUI64.convert}),
|
||||
SERVICE_SET_ZIGBEE_CLUSTER_ATTRIBUTE: vol.Schema(
|
||||
{
|
||||
vol.Required(ATTR_IEEE): EUI64.convert,
|
||||
|
@ -169,13 +189,7 @@ ClusterBinding = collections.namedtuple("ClusterBinding", "id endpoint_id type n
|
|||
@websocket_api.require_admin
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "zha/devices/permit",
|
||||
vol.Optional(ATTR_IEEE, default=None): EUI64.convert,
|
||||
vol.Optional(ATTR_DURATION, default=60): vol.All(
|
||||
vol.Coerce(int), vol.Range(0, 254)
|
||||
),
|
||||
}
|
||||
{vol.Required("type"): "zha/devices/permit", **SERVICE_PERMIT_PARAMS}
|
||||
)
|
||||
async def websocket_permit_devices(hass, connection, msg):
|
||||
"""Permit ZHA zigbee devices."""
|
||||
|
@ -199,7 +213,21 @@ async def websocket_permit_devices(hass, connection, msg):
|
|||
|
||||
connection.subscriptions[msg["id"]] = async_cleanup
|
||||
zha_gateway.async_enable_debug_mode()
|
||||
await zha_gateway.application_controller.permit(time_s=duration, node=ieee)
|
||||
if ATTR_SOURCE_IEEE in msg:
|
||||
src_ieee = msg[ATTR_SOURCE_IEEE]
|
||||
code = msg[ATTR_INSTALL_CODE]
|
||||
_LOGGER.debug("Allowing join for %s device with install code", src_ieee)
|
||||
await zha_gateway.application_controller.permit_with_key(
|
||||
time_s=duration, node=src_ieee, code=code
|
||||
)
|
||||
elif ATTR_QR_CODE in msg:
|
||||
src_ieee, code = msg[ATTR_QR_CODE]
|
||||
_LOGGER.debug("Allowing join for %s device with install code", src_ieee)
|
||||
await zha_gateway.application_controller.permit_with_key(
|
||||
time_s=duration, node=src_ieee, code=code
|
||||
)
|
||||
else:
|
||||
await zha_gateway.application_controller.permit(time_s=duration, node=ieee)
|
||||
connection.send_result(msg["id"])
|
||||
|
||||
|
||||
|
@ -826,8 +854,25 @@ def async_load_api(hass):
|
|||
|
||||
async def permit(service):
|
||||
"""Allow devices to join this network."""
|
||||
duration = service.data.get(ATTR_DURATION)
|
||||
ieee = service.data.get(ATTR_IEEE_ADDRESS)
|
||||
duration = service.data[ATTR_DURATION]
|
||||
ieee = service.data.get(ATTR_IEEE)
|
||||
if ATTR_SOURCE_IEEE in service.data:
|
||||
src_ieee = service.data[ATTR_SOURCE_IEEE]
|
||||
code = service.data[ATTR_INSTALL_CODE]
|
||||
_LOGGER.info("Allowing join for %s device with install code", src_ieee)
|
||||
await application_controller.permit_with_key(
|
||||
time_s=duration, node=src_ieee, code=code
|
||||
)
|
||||
return
|
||||
|
||||
if ATTR_QR_CODE in service.data:
|
||||
src_ieee, code = service.data[ATTR_QR_CODE]
|
||||
_LOGGER.info("Allowing join for %s device with install code", src_ieee)
|
||||
await application_controller.permit_with_key(
|
||||
time_s=duration, node=src_ieee, code=code
|
||||
)
|
||||
return
|
||||
|
||||
if ieee:
|
||||
_LOGGER.info("Permitting joins for %ss on %s device", duration, ieee)
|
||||
else:
|
||||
|
@ -840,7 +885,7 @@ def async_load_api(hass):
|
|||
|
||||
async def remove(service):
|
||||
"""Remove a node from the network."""
|
||||
ieee = service.data[ATTR_IEEE_ADDRESS]
|
||||
ieee = service.data[ATTR_IEEE]
|
||||
zha_gateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY]
|
||||
zha_device = zha_gateway.get_device(ieee)
|
||||
if zha_device is not None and zha_device.is_coordinator:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue