Update zwave_js WS APIs for provisioning (#117400)

This commit is contained in:
Raman Gupta 2024-05-29 02:47:09 -04:00 committed by GitHub
parent 1c2cda5033
commit 89ae425ac2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 58 additions and 46 deletions

View File

@ -116,8 +116,8 @@ ENABLED = "enabled"
OPTED_IN = "opted_in" OPTED_IN = "opted_in"
# constants for granting security classes # constants for granting security classes
SECURITY_CLASSES = "security_classes" SECURITY_CLASSES = "securityClasses"
CLIENT_SIDE_AUTH = "client_side_auth" CLIENT_SIDE_AUTH = "clientSideAuth"
# constants for inclusion # constants for inclusion
INCLUSION_STRATEGY = "inclusion_strategy" INCLUSION_STRATEGY = "inclusion_strategy"
@ -145,19 +145,19 @@ QR_CODE_STRING = "qr_code_string"
DSK = "dsk" DSK = "dsk"
VERSION = "version" VERSION = "version"
GENERIC_DEVICE_CLASS = "generic_device_class" GENERIC_DEVICE_CLASS = "genericDeviceClass"
SPECIFIC_DEVICE_CLASS = "specific_device_class" SPECIFIC_DEVICE_CLASS = "specificDeviceClass"
INSTALLER_ICON_TYPE = "installer_icon_type" INSTALLER_ICON_TYPE = "installerIconType"
MANUFACTURER_ID = "manufacturer_id" MANUFACTURER_ID = "manufacturerId"
PRODUCT_TYPE = "product_type" PRODUCT_TYPE = "productType"
PRODUCT_ID = "product_id" PRODUCT_ID = "productId"
APPLICATION_VERSION = "application_version" APPLICATION_VERSION = "applicationVersion"
MAX_INCLUSION_REQUEST_INTERVAL = "max_inclusion_request_interval" MAX_INCLUSION_REQUEST_INTERVAL = "maxInclusionRequestInterval"
UUID = "uuid" UUID = "uuid"
SUPPORTED_PROTOCOLS = "supported_protocols" SUPPORTED_PROTOCOLS = "supportedProtocols"
ADDITIONAL_PROPERTIES = "additional_properties" ADDITIONAL_PROPERTIES = "additional_properties"
STATUS = "status" STATUS = "status"
REQUESTED_SECURITY_CLASSES = "requested_security_classes" REQUESTED_SECURITY_CLASSES = "requestedSecurityClasses"
FEATURE = "feature" FEATURE = "feature"
STRATEGY = "strategy" STRATEGY = "strategy"
@ -183,6 +183,7 @@ def convert_planned_provisioning_entry(info: dict) -> ProvisioningEntry:
def convert_qr_provisioning_information(info: dict) -> QRProvisioningInformation: def convert_qr_provisioning_information(info: dict) -> QRProvisioningInformation:
"""Convert QR provisioning information dict to QRProvisioningInformation.""" """Convert QR provisioning information dict to QRProvisioningInformation."""
## Remove this when we have fix for QRProvisioningInformation.from_dict()
return QRProvisioningInformation( return QRProvisioningInformation(
version=info[VERSION], version=info[VERSION],
security_classes=info[SECURITY_CLASSES], security_classes=info[SECURITY_CLASSES],
@ -199,7 +200,28 @@ def convert_qr_provisioning_information(info: dict) -> QRProvisioningInformation
supported_protocols=info.get(SUPPORTED_PROTOCOLS), supported_protocols=info.get(SUPPORTED_PROTOCOLS),
status=info[STATUS], status=info[STATUS],
requested_security_classes=info.get(REQUESTED_SECURITY_CLASSES), requested_security_classes=info.get(REQUESTED_SECURITY_CLASSES),
additional_properties=info.get(ADDITIONAL_PROPERTIES, {}), additional_properties={
k: v
for k, v in info.items()
if k
not in (
VERSION,
SECURITY_CLASSES,
DSK,
GENERIC_DEVICE_CLASS,
SPECIFIC_DEVICE_CLASS,
INSTALLER_ICON_TYPE,
MANUFACTURER_ID,
PRODUCT_TYPE,
PRODUCT_ID,
APPLICATION_VERSION,
MAX_INCLUSION_REQUEST_INTERVAL,
UUID,
SUPPORTED_PROTOCOLS,
STATUS,
REQUESTED_SECURITY_CLASSES,
)
},
) )
@ -253,8 +275,8 @@ QR_PROVISIONING_INFORMATION_SCHEMA = vol.All(
vol.Optional(REQUESTED_SECURITY_CLASSES): vol.All( vol.Optional(REQUESTED_SECURITY_CLASSES): vol.All(
cv.ensure_list, [vol.Coerce(SecurityClass)] cv.ensure_list, [vol.Coerce(SecurityClass)]
), ),
vol.Optional(ADDITIONAL_PROPERTIES): dict, },
} extra=vol.ALLOW_EXTRA,
), ),
convert_qr_provisioning_information, convert_qr_provisioning_information,
) )
@ -990,9 +1012,7 @@ async def websocket_get_provisioning_entries(
) -> None: ) -> None:
"""Get provisioning entries (entries that have been pre-provisioned).""" """Get provisioning entries (entries that have been pre-provisioned)."""
provisioning_entries = await driver.controller.async_get_provisioning_entries() provisioning_entries = await driver.controller.async_get_provisioning_entries()
connection.send_result( connection.send_result(msg[ID], [entry.to_dict() for entry in provisioning_entries])
msg[ID], [dataclasses.asdict(entry) for entry in provisioning_entries]
)
@websocket_api.require_admin @websocket_api.require_admin
@ -1018,7 +1038,7 @@ async def websocket_parse_qr_code_string(
qr_provisioning_information = await async_parse_qr_code_string( qr_provisioning_information = await async_parse_qr_code_string(
client, msg[QR_CODE_STRING] client, msg[QR_CODE_STRING]
) )
connection.send_result(msg[ID], dataclasses.asdict(qr_provisioning_information)) connection.send_result(msg[ID], qr_provisioning_information.to_dict())
@websocket_api.require_admin @websocket_api.require_admin

View File

@ -38,7 +38,6 @@ from zwave_js_server.model.value import ConfigurationValue, get_value_id_str
from homeassistant.components.websocket_api import ERR_INVALID_FORMAT, ERR_NOT_FOUND from homeassistant.components.websocket_api import ERR_INVALID_FORMAT, ERR_NOT_FOUND
from homeassistant.components.zwave_js.api import ( from homeassistant.components.zwave_js.api import (
ADDITIONAL_PROPERTIES,
APPLICATION_VERSION, APPLICATION_VERSION,
CLIENT_SIDE_AUTH, CLIENT_SIDE_AUTH,
COMMAND_CLASS_ID, COMMAND_CLASS_ID,
@ -59,6 +58,7 @@ from homeassistant.components.zwave_js.api import (
LEVEL, LEVEL,
LOG_TO_FILE, LOG_TO_FILE,
MANUFACTURER_ID, MANUFACTURER_ID,
MAX_INCLUSION_REQUEST_INTERVAL,
NODE_ID, NODE_ID,
OPTED_IN, OPTED_IN,
PIN, PIN,
@ -74,7 +74,9 @@ from homeassistant.components.zwave_js.api import (
SPECIFIC_DEVICE_CLASS, SPECIFIC_DEVICE_CLASS,
STATUS, STATUS,
STRATEGY, STRATEGY,
SUPPORTED_PROTOCOLS,
TYPE, TYPE,
UUID,
VALUE, VALUE,
VERSION, VERSION,
) )
@ -1072,7 +1074,7 @@ async def test_provision_smart_start_node(
PRODUCT_TYPE: 1, PRODUCT_TYPE: 1,
PRODUCT_ID: 1, PRODUCT_ID: 1,
APPLICATION_VERSION: "test", APPLICATION_VERSION: "test",
ADDITIONAL_PROPERTIES: {"name": "test"}, "name": "test",
}, },
} }
) )
@ -1331,14 +1333,7 @@ async def test_get_provisioning_entries(
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
assert msg["success"] assert msg["success"]
assert msg["result"] == [ assert msg["result"] == [
{ {DSK: "test", SECURITY_CLASSES: [0], STATUS: 0, "fake": "test"}
"dsk": "test",
"security_classes": [SecurityClass.S2_UNAUTHENTICATED],
"requested_security_classes": None,
"status": 0,
"protocol": None,
"additional_properties": {"fake": "test"},
}
] ]
assert len(client.async_send_command.call_args_list) == 1 assert len(client.async_send_command.call_args_list) == 1
@ -1414,23 +1409,20 @@ async def test_parse_qr_code_string(
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
assert msg["success"] assert msg["success"]
assert msg["result"] == { assert msg["result"] == {
"version": 0, VERSION: 0,
"security_classes": [SecurityClass.S2_UNAUTHENTICATED], SECURITY_CLASSES: [0],
"dsk": "test", DSK: "test",
"generic_device_class": 1, GENERIC_DEVICE_CLASS: 1,
"specific_device_class": 1, SPECIFIC_DEVICE_CLASS: 1,
"installer_icon_type": 1, INSTALLER_ICON_TYPE: 1,
"manufacturer_id": 1, MANUFACTURER_ID: 1,
"product_type": 1, PRODUCT_TYPE: 1,
"product_id": 1, PRODUCT_ID: 1,
"protocol": None, APPLICATION_VERSION: "test",
"application_version": "test", MAX_INCLUSION_REQUEST_INTERVAL: 1,
"max_inclusion_request_interval": 1, UUID: "test",
"uuid": "test", SUPPORTED_PROTOCOLS: [Protocols.ZWAVE],
"supported_protocols": [Protocols.ZWAVE], STATUS: 0,
"status": 0,
"requested_security_classes": None,
"additional_properties": {},
} }
assert len(client.async_send_command.call_args_list) == 1 assert len(client.async_send_command.call_args_list) == 1