zwave-js-server-python 0.34.0__py3-none-any.whl → 0.35.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zwave_js_server/client.py +3 -3
- zwave_js_server/const/__init__.py +5 -2
- zwave_js_server/const/command_class/power_level.py +11 -0
- zwave_js_server/event.py +11 -2
- zwave_js_server/exceptions.py +14 -0
- zwave_js_server/model/command_class.py +5 -3
- zwave_js_server/model/{controller.py → controller/__init__.py} +18 -201
- zwave_js_server/model/controller/data_model.py +35 -0
- zwave_js_server/model/controller/event_model.py +160 -0
- zwave_js_server/model/controller/inclusion_and_provisioning.py +169 -0
- zwave_js_server/model/{controller_statistics.py → controller/statistics.py} +8 -1
- zwave_js_server/model/device_class.py +8 -1
- zwave_js_server/model/device_config.py +33 -8
- zwave_js_server/model/driver.py +51 -17
- zwave_js_server/model/endpoint.py +14 -3
- zwave_js_server/model/firmware.py +8 -1
- zwave_js_server/model/log_config.py +8 -3
- zwave_js_server/model/log_message.py +7 -2
- zwave_js_server/model/{node.py → node/__init__.py} +64 -74
- zwave_js_server/model/node/data_model.py +59 -0
- zwave_js_server/model/node/event_model.py +219 -0
- zwave_js_server/model/{node_health_check.py → node/health_check.py} +7 -2
- zwave_js_server/model/{node_statistics.py → node/statistics.py} +8 -1
- zwave_js_server/model/notification.py +75 -20
- zwave_js_server/model/utils.py +1 -1
- zwave_js_server/model/value.py +18 -5
- zwave_js_server/model/version.py +7 -1
- zwave_js_server/util/command_class/multilevel_sensor.py +1 -1
- zwave_js_server/util/multicast.py +1 -2
- {zwave_js_server_python-0.34.0.dist-info → zwave_js_server_python-0.35.2.dist-info}/METADATA +2 -1
- zwave_js_server_python-0.35.2.dist-info/RECORD +62 -0
- {zwave_js_server_python-0.34.0.dist-info → zwave_js_server_python-0.35.2.dist-info}/top_level.txt +0 -1
- scripts/__init__.py +0 -1
- scripts/generate_multilevel_sensor_constants.py +0 -245
- scripts/run_mock_server.py +0 -385
- zwave_js_server_python-0.34.0.dist-info/RECORD +0 -59
- {zwave_js_server_python-0.34.0.dist-info → zwave_js_server_python-0.35.2.dist-info}/LICENSE +0 -0
- {zwave_js_server_python-0.34.0.dist-info → zwave_js_server_python-0.35.2.dist-info}/WHEEL +0 -0
- {zwave_js_server_python-0.34.0.dist-info → zwave_js_server_python-0.35.2.dist-info}/entry_points.txt +0 -0
zwave_js_server/client.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""Client."""
|
|
2
2
|
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
import pprint
|
|
5
|
+
import uuid
|
|
3
6
|
from collections import defaultdict
|
|
4
7
|
from copy import deepcopy
|
|
5
8
|
from datetime import datetime
|
|
6
|
-
import logging
|
|
7
9
|
from operator import itemgetter
|
|
8
|
-
import pprint
|
|
9
|
-
import uuid
|
|
10
10
|
from types import TracebackType
|
|
11
11
|
from typing import Any, DefaultDict, Dict, List, Optional, cast
|
|
12
12
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""Constants for the Z-Wave JS python library."""
|
|
2
|
+
import sys
|
|
2
3
|
from enum import Enum, IntEnum
|
|
3
4
|
|
|
4
5
|
# minimal server schema version we can handle
|
|
5
|
-
MIN_SERVER_SCHEMA_VERSION =
|
|
6
|
+
MIN_SERVER_SCHEMA_VERSION = 15
|
|
6
7
|
# max server schema version we can handle (and our code is compatible with)
|
|
7
|
-
MAX_SERVER_SCHEMA_VERSION =
|
|
8
|
+
MAX_SERVER_SCHEMA_VERSION = 15
|
|
9
|
+
|
|
10
|
+
TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED = sys.version_info < (3, 9, 2)
|
|
8
11
|
|
|
9
12
|
VALUE_UNKNOWN = "unknown"
|
|
10
13
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""Constants for the Power Level Command Class."""
|
|
2
|
+
from enum import IntEnum
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class PowerLevelTestStatus(IntEnum):
|
|
6
|
+
"""Enum with all known power level test statuses."""
|
|
7
|
+
|
|
8
|
+
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/commandclass/PowerlevelCC.ts#L52
|
|
9
|
+
FAILED = 0
|
|
10
|
+
SUCCESS = 1
|
|
11
|
+
IN_PROGRESS = 2
|
zwave_js_server/event.py
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
"""Provide Event base classes for Z-Wave JS."""
|
|
2
2
|
import logging
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Callable, Dict, List
|
|
4
|
+
from typing import Callable, Dict, List, Literal
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
5
7
|
|
|
6
8
|
LOGGER = logging.getLogger(__package__)
|
|
7
9
|
|
|
8
10
|
|
|
11
|
+
class BaseEventModel(BaseModel):
|
|
12
|
+
"""Base model for an event."""
|
|
13
|
+
|
|
14
|
+
source: Literal["controller", "driver", "node"]
|
|
15
|
+
event: str
|
|
16
|
+
|
|
17
|
+
|
|
9
18
|
@dataclass
|
|
10
19
|
class Event:
|
|
11
20
|
"""Represent an event."""
|
|
@@ -48,7 +57,7 @@ class EventBase:
|
|
|
48
57
|
|
|
49
58
|
def emit(self, event_name: str, data: dict) -> None:
|
|
50
59
|
"""Run all callbacks for an event."""
|
|
51
|
-
for listener in self._listeners.get(event_name, []):
|
|
60
|
+
for listener in self._listeners.get(event_name, []).copy():
|
|
52
61
|
listener(data)
|
|
53
62
|
|
|
54
63
|
def _handle_event_protocol(self, event: Event) -> None:
|
zwave_js_server/exceptions.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import TYPE_CHECKING, Optional
|
|
|
4
4
|
from .const import CommandClass
|
|
5
5
|
|
|
6
6
|
if TYPE_CHECKING:
|
|
7
|
+
from .event import Event
|
|
7
8
|
from .model.value import Value
|
|
8
9
|
|
|
9
10
|
|
|
@@ -156,3 +157,16 @@ class UnknownValueData(BaseZwaveJSServerError):
|
|
|
156
157
|
"upstream issue with the driver or missing support for this data in the "
|
|
157
158
|
"library"
|
|
158
159
|
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class NotificationHasUnsupportedCommandClass(BaseZwaveJSServerError):
|
|
163
|
+
"""Exception raised when notification is received for an unsupported CC."""
|
|
164
|
+
|
|
165
|
+
def __init__(self, event: "Event", command_class: CommandClass) -> None:
|
|
166
|
+
"""Initialize an invalid Command Class error."""
|
|
167
|
+
self.event_data = event.data
|
|
168
|
+
self.command_class = command_class
|
|
169
|
+
super().__init__(
|
|
170
|
+
"Notification received with unsupported command class "
|
|
171
|
+
f"{command_class.name}: {event.data}"
|
|
172
|
+
)
|
|
@@ -3,10 +3,12 @@ Model for Zwave Command Class Info.
|
|
|
3
3
|
|
|
4
4
|
https://zwave-js.github.io/node-zwave-js/#/api/endpoint?id=commandclasses
|
|
5
5
|
"""
|
|
6
|
+
from ..const import TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED, CommandClass
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
if TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED:
|
|
9
|
+
from typing_extensions import TypedDict
|
|
10
|
+
else:
|
|
11
|
+
from typing import TypedDict
|
|
10
12
|
|
|
11
13
|
|
|
12
14
|
class CommandClassInfoDataType(TypedDict):
|
|
@@ -1,101 +1,30 @@
|
|
|
1
1
|
"""Provide a model for the Z-Wave JS controller."""
|
|
2
2
|
from dataclasses import dataclass
|
|
3
|
-
from typing import
|
|
4
|
-
TYPE_CHECKING,
|
|
5
|
-
Any,
|
|
6
|
-
Dict,
|
|
7
|
-
List,
|
|
8
|
-
Literal,
|
|
9
|
-
Optional,
|
|
10
|
-
TypedDict,
|
|
11
|
-
Union,
|
|
12
|
-
cast,
|
|
13
|
-
)
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Optional, Union, cast
|
|
14
4
|
|
|
15
|
-
from
|
|
5
|
+
from ...const import (
|
|
16
6
|
MINIMUM_QR_STRING_LENGTH,
|
|
17
7
|
InclusionState,
|
|
18
8
|
InclusionStrategy,
|
|
19
|
-
Protocols,
|
|
20
9
|
QRCodeVersion,
|
|
21
10
|
RFRegion,
|
|
22
|
-
SecurityClass,
|
|
23
11
|
ZwaveFeature,
|
|
24
12
|
)
|
|
25
|
-
from
|
|
26
|
-
from
|
|
27
|
-
from
|
|
28
|
-
from
|
|
29
|
-
from
|
|
30
|
-
|
|
31
|
-
|
|
13
|
+
from ...event import Event, EventBase
|
|
14
|
+
from ...util.helpers import convert_base64_to_bytes, convert_bytes_to_base64
|
|
15
|
+
from ..association import Association, AssociationGroup
|
|
16
|
+
from ..node import Node
|
|
17
|
+
from .data_model import ControllerDataType
|
|
18
|
+
from .event_model import CONTROLLER_EVENT_MODEL_MAP
|
|
19
|
+
from .inclusion_and_provisioning import (
|
|
20
|
+
InclusionGrant,
|
|
21
|
+
ProvisioningEntry,
|
|
22
|
+
QRProvisioningInformation,
|
|
32
23
|
)
|
|
24
|
+
from .statistics import ControllerStatistics
|
|
33
25
|
|
|
34
26
|
if TYPE_CHECKING:
|
|
35
|
-
from
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class InclusionGrantDataType(TypedDict):
|
|
39
|
-
"""Representation of an inclusion grant data dict type."""
|
|
40
|
-
|
|
41
|
-
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/zwave-js/src/lib/controller/Inclusion.ts#L48-L56
|
|
42
|
-
securityClasses: List[int]
|
|
43
|
-
clientSideAuth: bool
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
@dataclass
|
|
47
|
-
class InclusionGrant:
|
|
48
|
-
"""Representation of an inclusion grant."""
|
|
49
|
-
|
|
50
|
-
security_classes: List[SecurityClass]
|
|
51
|
-
client_side_auth: bool
|
|
52
|
-
|
|
53
|
-
def to_dict(self) -> InclusionGrantDataType:
|
|
54
|
-
"""Return InclusionGrantDataType dict from self."""
|
|
55
|
-
return {
|
|
56
|
-
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
57
|
-
"clientSideAuth": self.client_side_auth,
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
@classmethod
|
|
61
|
-
def from_dict(cls, data: InclusionGrantDataType) -> "InclusionGrant":
|
|
62
|
-
"""Return InclusionGrant from InclusionGrantDataType dict."""
|
|
63
|
-
return cls(
|
|
64
|
-
security_classes=[
|
|
65
|
-
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
66
|
-
],
|
|
67
|
-
client_side_auth=data["clientSideAuth"],
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@dataclass
|
|
72
|
-
class ProvisioningEntry:
|
|
73
|
-
"""Class to represent the base fields of a provisioning entry."""
|
|
74
|
-
|
|
75
|
-
dsk: str
|
|
76
|
-
security_classes: List[SecurityClass]
|
|
77
|
-
additional_properties: Optional[Dict[str, Any]] = None
|
|
78
|
-
|
|
79
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
80
|
-
"""Return PlannedProvisioning data dict from self."""
|
|
81
|
-
return {
|
|
82
|
-
"dsk": self.dsk,
|
|
83
|
-
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
84
|
-
**(self.additional_properties or {}),
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
@classmethod
|
|
88
|
-
def from_dict(cls, data: Dict[str, Any]) -> "ProvisioningEntry":
|
|
89
|
-
"""Return ProvisioningEntry from data dict."""
|
|
90
|
-
return cls(
|
|
91
|
-
dsk=data["dsk"],
|
|
92
|
-
security_classes=[
|
|
93
|
-
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
94
|
-
],
|
|
95
|
-
additional_properties={
|
|
96
|
-
k: v for k, v in data.items() if k not in {"dsk", "securityClasses"}
|
|
97
|
-
},
|
|
98
|
-
)
|
|
27
|
+
from ...client import Client
|
|
99
28
|
|
|
100
29
|
|
|
101
30
|
@dataclass
|
|
@@ -106,122 +35,6 @@ class NVMProgress:
|
|
|
106
35
|
total_bytes: int
|
|
107
36
|
|
|
108
37
|
|
|
109
|
-
@dataclass
|
|
110
|
-
class QRProvisioningInformationMixin:
|
|
111
|
-
"""Mixin class to represent the base fields of a QR provisioning information."""
|
|
112
|
-
|
|
113
|
-
version: QRCodeVersion
|
|
114
|
-
generic_device_class: int
|
|
115
|
-
specific_device_class: int
|
|
116
|
-
installer_icon_type: int
|
|
117
|
-
manufacturer_id: int
|
|
118
|
-
product_type: int
|
|
119
|
-
product_id: int
|
|
120
|
-
application_version: str
|
|
121
|
-
max_inclusion_request_interval: Optional[int]
|
|
122
|
-
uuid: Optional[str]
|
|
123
|
-
supported_protocols: Optional[List[Protocols]]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
@dataclass
|
|
127
|
-
class QRProvisioningInformation(ProvisioningEntry, QRProvisioningInformationMixin):
|
|
128
|
-
"""Representation of provisioning information retrieved from a QR code."""
|
|
129
|
-
|
|
130
|
-
def to_dict(self) -> Dict[str, Any]:
|
|
131
|
-
"""Return QRProvisioningInformation data dict from self."""
|
|
132
|
-
data = {
|
|
133
|
-
"version": self.version.value,
|
|
134
|
-
"securityClasses": [sec_cls.value for sec_cls in self.security_classes],
|
|
135
|
-
"dsk": self.dsk,
|
|
136
|
-
"genericDeviceClass": self.generic_device_class,
|
|
137
|
-
"specificDeviceClass": self.specific_device_class,
|
|
138
|
-
"installerIconType": self.installer_icon_type,
|
|
139
|
-
"manufacturerId": self.manufacturer_id,
|
|
140
|
-
"productType": self.product_type,
|
|
141
|
-
"productId": self.product_id,
|
|
142
|
-
"applicationVersion": self.application_version,
|
|
143
|
-
**(self.additional_properties or {}),
|
|
144
|
-
}
|
|
145
|
-
if self.max_inclusion_request_interval is not None:
|
|
146
|
-
data["maxInclusionRequestInterval"] = self.max_inclusion_request_interval
|
|
147
|
-
if self.uuid is not None:
|
|
148
|
-
data["uuid"] = self.uuid
|
|
149
|
-
if self.supported_protocols is not None:
|
|
150
|
-
data["supportedProtocols"] = [
|
|
151
|
-
protocol.value for protocol in self.supported_protocols
|
|
152
|
-
]
|
|
153
|
-
return data
|
|
154
|
-
|
|
155
|
-
@classmethod
|
|
156
|
-
def from_dict(cls, data: Dict[str, Any]) -> "QRProvisioningInformation":
|
|
157
|
-
"""Return QRProvisioningInformation from data dict."""
|
|
158
|
-
return cls(
|
|
159
|
-
version=QRCodeVersion(data["version"]),
|
|
160
|
-
security_classes=[
|
|
161
|
-
SecurityClass(sec_cls) for sec_cls in data["securityClasses"]
|
|
162
|
-
],
|
|
163
|
-
dsk=data["dsk"],
|
|
164
|
-
generic_device_class=data["genericDeviceClass"],
|
|
165
|
-
specific_device_class=data["specificDeviceClass"],
|
|
166
|
-
installer_icon_type=data["installerIconType"],
|
|
167
|
-
manufacturer_id=data["manufacturerId"],
|
|
168
|
-
product_type=data["productType"],
|
|
169
|
-
product_id=data["productId"],
|
|
170
|
-
application_version=data["applicationVersion"],
|
|
171
|
-
max_inclusion_request_interval=data.get("maxInclusionRequestInterval"),
|
|
172
|
-
uuid=data.get("uuid"),
|
|
173
|
-
supported_protocols=[
|
|
174
|
-
Protocols(supported_protocol)
|
|
175
|
-
for supported_protocol in data.get("supportedProtocols", [])
|
|
176
|
-
],
|
|
177
|
-
additional_properties={
|
|
178
|
-
k: v
|
|
179
|
-
for k, v in data.items()
|
|
180
|
-
if k
|
|
181
|
-
not in {
|
|
182
|
-
"version",
|
|
183
|
-
"securityClasses",
|
|
184
|
-
"dsk",
|
|
185
|
-
"genericDeviceClass",
|
|
186
|
-
"specificDeviceClass",
|
|
187
|
-
"installerIconType",
|
|
188
|
-
"manufacturerId",
|
|
189
|
-
"productType",
|
|
190
|
-
"productId",
|
|
191
|
-
"applicationVersion",
|
|
192
|
-
"maxInclusionRequestInterval",
|
|
193
|
-
"uuid",
|
|
194
|
-
"supportedProtocols",
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class ControllerDataType(TypedDict, total=False):
|
|
201
|
-
"""Represent a controller data dict type."""
|
|
202
|
-
|
|
203
|
-
libraryVersion: str
|
|
204
|
-
type: int
|
|
205
|
-
homeId: int
|
|
206
|
-
ownNodeId: int
|
|
207
|
-
isSecondary: bool # TODO: The following items are missing in the docs.
|
|
208
|
-
isUsingHomeIdFromOtherNetwork: bool
|
|
209
|
-
isSISPresent: bool
|
|
210
|
-
wasRealPrimary: bool
|
|
211
|
-
isStaticUpdateController: bool
|
|
212
|
-
isSlave: bool
|
|
213
|
-
serialApiVersion: str
|
|
214
|
-
manufacturerId: int
|
|
215
|
-
productType: int
|
|
216
|
-
productId: int
|
|
217
|
-
supportedFunctionTypes: List[int]
|
|
218
|
-
sucNodeId: int
|
|
219
|
-
supportsTimers: bool
|
|
220
|
-
isHealNetworkActive: bool
|
|
221
|
-
statistics: ControllerStatisticsDataType
|
|
222
|
-
inclusionState: int
|
|
223
|
-
|
|
224
|
-
|
|
225
38
|
class Controller(EventBase):
|
|
226
39
|
"""Represent a Z-Wave JS controller."""
|
|
227
40
|
|
|
@@ -833,6 +646,8 @@ class Controller(EventBase):
|
|
|
833
646
|
f"Controller doesn't know how to handle/forward this event: {event.data}"
|
|
834
647
|
)
|
|
835
648
|
|
|
649
|
+
CONTROLLER_EVENT_MODEL_MAP[event.type](**event.data)
|
|
650
|
+
|
|
836
651
|
self._handle_event_protocol(event)
|
|
837
652
|
|
|
838
653
|
event.data["controller"] = self
|
|
@@ -864,6 +679,8 @@ class Controller(EventBase):
|
|
|
864
679
|
def handle_node_removed(self, event: Event) -> None:
|
|
865
680
|
"""Process a node removed event."""
|
|
866
681
|
event.data["node"] = self.nodes.pop(event.data["node"]["nodeId"])
|
|
682
|
+
# Remove client from node since it's no longer connected to the controller
|
|
683
|
+
event.data["node"].client = None
|
|
867
684
|
|
|
868
685
|
def handle_heal_network_progress(self, event: Event) -> None:
|
|
869
686
|
"""Process a heal network progress event."""
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Data model for a Z-Wave JS controller."""
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from ...const import TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED
|
|
5
|
+
from .statistics import ControllerStatisticsDataType
|
|
6
|
+
|
|
7
|
+
if TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED:
|
|
8
|
+
from typing_extensions import TypedDict
|
|
9
|
+
else:
|
|
10
|
+
from typing import TypedDict
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ControllerDataType(TypedDict, total=False):
|
|
14
|
+
"""Represent a controller data dict type."""
|
|
15
|
+
|
|
16
|
+
libraryVersion: str
|
|
17
|
+
type: int
|
|
18
|
+
homeId: int
|
|
19
|
+
ownNodeId: int
|
|
20
|
+
isSecondary: bool # TODO: The following items are missing in the docs.
|
|
21
|
+
isUsingHomeIdFromOtherNetwork: bool
|
|
22
|
+
isSISPresent: bool
|
|
23
|
+
wasRealPrimary: bool
|
|
24
|
+
isStaticUpdateController: bool
|
|
25
|
+
isSlave: bool
|
|
26
|
+
serialApiVersion: str
|
|
27
|
+
manufacturerId: int
|
|
28
|
+
productType: int
|
|
29
|
+
productId: int
|
|
30
|
+
supportedFunctionTypes: List[int]
|
|
31
|
+
sucNodeId: int
|
|
32
|
+
supportsTimers: bool
|
|
33
|
+
isHealNetworkActive: bool
|
|
34
|
+
statistics: ControllerStatisticsDataType
|
|
35
|
+
inclusionState: int
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
"""Provide a model for the Z-Wave JS controller's events."""
|
|
2
|
+
from typing import Dict, Literal, Type
|
|
3
|
+
|
|
4
|
+
from ...const import TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED
|
|
5
|
+
from ...event import BaseEventModel
|
|
6
|
+
from ..node.data_model import NodeDataType
|
|
7
|
+
from .inclusion_and_provisioning import InclusionGrantDataType
|
|
8
|
+
from .statistics import ControllerStatisticsDataType
|
|
9
|
+
|
|
10
|
+
if TYPING_EXTENSION_FOR_TYPEDDICT_REQUIRED:
|
|
11
|
+
from typing_extensions import TypedDict
|
|
12
|
+
else:
|
|
13
|
+
from typing import TypedDict
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class InclusionResultDataType(TypedDict, total=False):
|
|
17
|
+
"""Represent an inclusion result data dict type."""
|
|
18
|
+
|
|
19
|
+
lowSecurity: bool
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class BaseControllerEventModel(BaseEventModel):
|
|
23
|
+
"""Base model for a controller event."""
|
|
24
|
+
|
|
25
|
+
source: Literal["controller"]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class ExclusionFailedEventModel(BaseControllerEventModel):
|
|
29
|
+
"""Model for `exclusion failed` event data."""
|
|
30
|
+
|
|
31
|
+
event: Literal["exclusion failed"]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ExclusionStartedEventModel(BaseControllerEventModel):
|
|
35
|
+
"""Model for `exclusion started` event data."""
|
|
36
|
+
|
|
37
|
+
event: Literal["exclusion started"]
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class ExclusionStoppedEventModel(BaseControllerEventModel):
|
|
41
|
+
"""Model for `exclusion stopped` event data."""
|
|
42
|
+
|
|
43
|
+
event: Literal["exclusion stopped"]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class GrantSecurityClassesEventModel(BaseControllerEventModel):
|
|
47
|
+
"""Model for `grant security classes` event data."""
|
|
48
|
+
|
|
49
|
+
event: Literal["grant security classes"]
|
|
50
|
+
requested: InclusionGrantDataType
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class HealNetworkDoneEventModel(BaseControllerEventModel):
|
|
54
|
+
"""Model for `heal network done` event data."""
|
|
55
|
+
|
|
56
|
+
event: Literal["heal network done"]
|
|
57
|
+
result: Dict[int, str]
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class HealNetworkProgressEventModel(BaseControllerEventModel):
|
|
61
|
+
"""Model for `heal network progress` event data."""
|
|
62
|
+
|
|
63
|
+
event: Literal["heal network progress"]
|
|
64
|
+
progress: Dict[int, str]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class InclusionFailedEventModel(BaseControllerEventModel):
|
|
68
|
+
"""Model for `inclusion failed` event data."""
|
|
69
|
+
|
|
70
|
+
event: Literal["inclusion failed"]
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class InclusionStartedEventModel(BaseControllerEventModel):
|
|
74
|
+
"""Model for `inclusion started` event data."""
|
|
75
|
+
|
|
76
|
+
event: Literal["inclusion started"]
|
|
77
|
+
secure: bool
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class InclusionStoppedEventModel(BaseControllerEventModel):
|
|
81
|
+
"""Model for `inclusion stopped` event data."""
|
|
82
|
+
|
|
83
|
+
event: Literal["inclusion stopped"]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class NodeAddedEventModel(BaseControllerEventModel):
|
|
87
|
+
"""Model for `node added` event data."""
|
|
88
|
+
|
|
89
|
+
event: Literal["node added"]
|
|
90
|
+
node: NodeDataType
|
|
91
|
+
result: InclusionResultDataType
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class NodeRemovedEventModel(BaseControllerEventModel):
|
|
95
|
+
"""Model for `node removed` event data."""
|
|
96
|
+
|
|
97
|
+
event: Literal["node removed"]
|
|
98
|
+
node: NodeDataType
|
|
99
|
+
replaced: bool
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class NVMBackupAndConvertProgressEventModel(BaseControllerEventModel):
|
|
103
|
+
"""Base model for `nvm backup progress` and `nvm convert progress` event data."""
|
|
104
|
+
|
|
105
|
+
bytesRead: int
|
|
106
|
+
total: int
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class NVMBackupProgressEventModel(NVMBackupAndConvertProgressEventModel):
|
|
110
|
+
"""Model for `nvm backup progress` event data."""
|
|
111
|
+
|
|
112
|
+
event: Literal["nvm backup progress"]
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class NVMConvertProgressEventModel(NVMBackupAndConvertProgressEventModel):
|
|
116
|
+
"""Model for `nvm convert progress` event data."""
|
|
117
|
+
|
|
118
|
+
event: Literal["nvm convert progress"]
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class NVMRestoreProgressEventModel(BaseControllerEventModel):
|
|
122
|
+
"""Model for `nvm restore progress` event data."""
|
|
123
|
+
|
|
124
|
+
event: Literal["nvm restore progress"]
|
|
125
|
+
bytesWritten: int
|
|
126
|
+
total: int
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class StatisticsUpdatedEventModel(BaseControllerEventModel):
|
|
130
|
+
"""Model for `statistics updated` event data."""
|
|
131
|
+
|
|
132
|
+
event: Literal["statistics updated"]
|
|
133
|
+
statistics: ControllerStatisticsDataType
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class ValidateDSKAndEnterPINEventModel(BaseControllerEventModel):
|
|
137
|
+
"""Model for `validate dsk and enter pin` event data."""
|
|
138
|
+
|
|
139
|
+
event: Literal["validate dsk and enter pin"]
|
|
140
|
+
dsk: str
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
CONTROLLER_EVENT_MODEL_MAP: Dict[str, Type["BaseControllerEventModel"]] = {
|
|
144
|
+
"exclusion failed": ExclusionFailedEventModel,
|
|
145
|
+
"exclusion started": ExclusionStartedEventModel,
|
|
146
|
+
"exclusion stopped": ExclusionStoppedEventModel,
|
|
147
|
+
"grant security classes": GrantSecurityClassesEventModel,
|
|
148
|
+
"heal network done": HealNetworkDoneEventModel,
|
|
149
|
+
"heal network progress": HealNetworkProgressEventModel,
|
|
150
|
+
"inclusion failed": InclusionFailedEventModel,
|
|
151
|
+
"inclusion started": InclusionStartedEventModel,
|
|
152
|
+
"inclusion stopped": InclusionStoppedEventModel,
|
|
153
|
+
"node added": NodeAddedEventModel,
|
|
154
|
+
"node removed": NodeRemovedEventModel,
|
|
155
|
+
"nvm backup progress": NVMBackupProgressEventModel,
|
|
156
|
+
"nvm convert progress": NVMConvertProgressEventModel,
|
|
157
|
+
"nvm restore progress": NVMRestoreProgressEventModel,
|
|
158
|
+
"statistics updated": StatisticsUpdatedEventModel,
|
|
159
|
+
"validate dsk and enter pin": ValidateDSKAndEnterPINEventModel,
|
|
160
|
+
}
|