204 lines
7.5 KiB
Python
204 lines
7.5 KiB
Python
"""Provide a model for inclusion and provisioning."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Any, TypedDict
|
|
|
|
from ...const import Protocols, ProvisioningEntryStatus, QRCodeVersion, SecurityClass
|
|
|
|
|
|
class InclusionGrantDataType(TypedDict):
|
|
"""Representation of an inclusion grant data dict type."""
|
|
|
|
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/controller/Inclusion.ts#L48-L56
|
|
securityClasses: list[int]
|
|
clientSideAuth: bool
|
|
|
|
|
|
@dataclass
|
|
class InclusionGrant:
|
|
"""Representation of an inclusion grant."""
|
|
|
|
security_classes: list[SecurityClass]
|
|
client_side_auth: bool
|
|
|
|
def to_dict(self) -> InclusionGrantDataType:
|
|
"""Return InclusionGrantDataType dict from self."""
|
|
return {
|
|
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
"clientSideAuth": self.client_side_auth,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: InclusionGrantDataType) -> InclusionGrant:
|
|
"""Return InclusionGrant from InclusionGrantDataType dict."""
|
|
return cls(
|
|
security_classes=[
|
|
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
],
|
|
client_side_auth=data["clientSideAuth"],
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class ProvisioningEntry:
|
|
"""Class to represent the base fields of a provisioning entry."""
|
|
|
|
dsk: str
|
|
security_classes: list[SecurityClass]
|
|
requested_security_classes: list[SecurityClass] | None = None
|
|
status: ProvisioningEntryStatus = ProvisioningEntryStatus.ACTIVE
|
|
protocol: Protocols | None = None
|
|
additional_properties: dict[str, Any] | None = None
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
"""Return PlannedProvisioning data dict from self."""
|
|
data = {
|
|
"dsk": self.dsk,
|
|
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
"status": self.status.value,
|
|
**(self.additional_properties or {}),
|
|
}
|
|
if self.requested_security_classes:
|
|
data["requestedSecurityClasses"] = [
|
|
sec_cls.value for sec_cls in self.requested_security_classes
|
|
]
|
|
if self.protocol is not None:
|
|
data["protocol"] = self.protocol.value
|
|
return data
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict[str, Any]) -> ProvisioningEntry:
|
|
"""Return ProvisioningEntry from data dict."""
|
|
cls_instance = cls(
|
|
dsk=data["dsk"],
|
|
security_classes=[
|
|
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
],
|
|
)
|
|
if additional_properties := {
|
|
k: v
|
|
for k, v in data.items()
|
|
if k not in ("dsk", "securityClasses", "requestedSecurityClasses", "status")
|
|
}:
|
|
cls_instance.additional_properties = additional_properties
|
|
if "requestedSecurityClasses" in data:
|
|
cls_instance.requested_security_classes = [
|
|
SecurityClass(sec_cls) for sec_cls in data["requestedSecurityClasses"]
|
|
]
|
|
if "status" in data:
|
|
cls_instance.status = ProvisioningEntryStatus(data["status"])
|
|
if "protocol" in data:
|
|
cls_instance.protocol = Protocols(data["protocol"])
|
|
return cls_instance
|
|
|
|
|
|
@dataclass
|
|
class QRProvisioningInformationMixin:
|
|
"""Mixin class to represent the base fields of a QR provisioning information."""
|
|
|
|
version: QRCodeVersion
|
|
generic_device_class: int
|
|
specific_device_class: int
|
|
installer_icon_type: int
|
|
manufacturer_id: int
|
|
product_type: int
|
|
product_id: int
|
|
application_version: str
|
|
max_inclusion_request_interval: int | None
|
|
uuid: str | None
|
|
supported_protocols: list[Protocols] | None
|
|
|
|
|
|
@dataclass
|
|
class QRProvisioningInformation(ProvisioningEntry, QRProvisioningInformationMixin):
|
|
"""Representation of provisioning information retrieved from a QR code."""
|
|
|
|
def to_dict(self) -> dict[str, Any]:
|
|
"""Return QRProvisioningInformation data dict from self."""
|
|
data = {
|
|
"version": self.version.value,
|
|
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
"dsk": self.dsk,
|
|
"status": self.status.value,
|
|
"genericDeviceClass": self.generic_device_class,
|
|
"specificDeviceClass": self.specific_device_class,
|
|
"installerIconType": self.installer_icon_type,
|
|
"manufacturerId": self.manufacturer_id,
|
|
"productType": self.product_type,
|
|
"productId": self.product_id,
|
|
"applicationVersion": self.application_version,
|
|
**(self.additional_properties or {}),
|
|
}
|
|
if self.requested_security_classes:
|
|
data["requestedSecurityClasses"] = [
|
|
sec_cls.value for sec_cls in self.requested_security_classes
|
|
]
|
|
if self.max_inclusion_request_interval is not None:
|
|
data["maxInclusionRequestInterval"] = self.max_inclusion_request_interval
|
|
if self.uuid is not None:
|
|
data["uuid"] = self.uuid
|
|
if self.supported_protocols is not None:
|
|
data["supportedProtocols"] = [
|
|
protocol.value for protocol in self.supported_protocols
|
|
]
|
|
return data
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: dict[str, Any]) -> QRProvisioningInformation:
|
|
"""Return QRProvisioningInformation from data dict."""
|
|
supported_protocols: list[Protocols] | None = None
|
|
if "supportedProtocols" in data:
|
|
supported_protocols = [
|
|
Protocols(supported_protocol)
|
|
for supported_protocol in data["supportedProtocols"]
|
|
]
|
|
cls_instance = cls(
|
|
version=QRCodeVersion(data["version"]),
|
|
security_classes=[
|
|
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
],
|
|
dsk=data["dsk"],
|
|
generic_device_class=data["genericDeviceClass"],
|
|
specific_device_class=data["specificDeviceClass"],
|
|
installer_icon_type=data["installerIconType"],
|
|
manufacturer_id=data["manufacturerId"],
|
|
product_type=data["productType"],
|
|
product_id=data["productId"],
|
|
application_version=data["applicationVersion"],
|
|
max_inclusion_request_interval=data.get("maxInclusionRequestInterval"),
|
|
uuid=data.get("uuid"),
|
|
supported_protocols=supported_protocols,
|
|
)
|
|
if additional_properties := {
|
|
k: v
|
|
for k, v in data.items()
|
|
if k
|
|
not in (
|
|
"version",
|
|
"securityClasses",
|
|
"requestedSecurityClasses",
|
|
"dsk",
|
|
"genericDeviceClass",
|
|
"specificDeviceClass",
|
|
"installerIconType",
|
|
"manufacturerId",
|
|
"productType",
|
|
"productId",
|
|
"applicationVersion",
|
|
"maxInclusionRequestInterval",
|
|
"uuid",
|
|
"supportedProtocols",
|
|
"status",
|
|
)
|
|
}:
|
|
cls_instance.additional_properties = additional_properties
|
|
if "requestedSecurityClasses" in data:
|
|
cls_instance.requested_security_classes = [
|
|
SecurityClass(sec_cls) for sec_cls in data["requestedSecurityClasses"]
|
|
]
|
|
if "status" in data:
|
|
cls_instance.status = ProvisioningEntryStatus(data["status"])
|
|
return cls_instance
|