zwave-js-server-python 0.55.3__tar.gz → 0.56.0__tar.gz
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-python-0.55.3 → zwave_js_server_python-0.56.0}/PKG-INFO +1 -1
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/client.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/__init__.py +4 -3
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/barrier_operator.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/basic.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/central_scene.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/color_switch.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/energy_production.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/entry_control.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/humidity_control.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/lock.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/meter.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/multilevel_switch.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/power_level.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/protection.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/scene_activation.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/sound_switch.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/thermostat.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/wake_up.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/window_covering.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/dump.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/event.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/exceptions.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/firmware.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/association.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/command_class.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/__init__.py +14 -6
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/data_model.py +2 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/event_model.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/firmware.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/inclusion_and_provisioning.py +6 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/rebuild_routes.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/controller/statistics.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/device_class.py +11 -6
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/device_config.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/driver.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/duration.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/endpoint.py +7 -3
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/log_config.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/log_message.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/__init__.py +64 -44
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/data_model.py +2 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/event_model.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/firmware.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/health_check.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/node/statistics.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/notification.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/statistics.py +8 -5
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/utils.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/value.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/version.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/command_class/energy_production.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/command_class/meter.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/command_class/multilevel_sensor.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/helpers.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/lock.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/multicast.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/node.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/version.py +1 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/PKG-INFO +1 -1
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/LICENSE +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/MANIFEST.in +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/README.md +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/pyproject.toml +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/setup.cfg +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/__init__.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/__main__.py +1 -1
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/__init__.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/multilevel_sensor.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/command_class/notification.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/__init__.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/py.typed +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/__init__.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/command_class/__init__.py +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/SOURCES.txt +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/dependency_links.txt +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/entry_points.txt +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/requires.txt +0 -0
- {zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server_python.egg-info/top_level.txt +0 -0
{zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/const/__init__.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Constants for the Z-Wave JS python library."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from dataclasses import dataclass, field
|
|
@@ -7,12 +8,12 @@ import logging
|
|
|
7
8
|
from typing import TypedDict
|
|
8
9
|
|
|
9
10
|
PACKAGE_NAME = "zwave-js-server-python"
|
|
10
|
-
__version__ = "0.
|
|
11
|
+
__version__ = "0.56.0"
|
|
11
12
|
|
|
12
13
|
# minimal server schema version we can handle
|
|
13
|
-
MIN_SERVER_SCHEMA_VERSION =
|
|
14
|
+
MIN_SERVER_SCHEMA_VERSION = 35
|
|
14
15
|
# max server schema version we can handle (and our code is compatible with)
|
|
15
|
-
MAX_SERVER_SCHEMA_VERSION =
|
|
16
|
+
MAX_SERVER_SCHEMA_VERSION = 35
|
|
16
17
|
|
|
17
18
|
VALUE_UNKNOWN = "unknown"
|
|
18
19
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Provide a model for the Z-Wave JS controller."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from dataclasses import dataclass
|
|
@@ -243,6 +244,11 @@ class Controller(EventBase):
|
|
|
243
244
|
"""Return status."""
|
|
244
245
|
return ControllerStatus(self.data["status"])
|
|
245
246
|
|
|
247
|
+
@property
|
|
248
|
+
def supports_long_range(self) -> bool | None:
|
|
249
|
+
"""Return whether controller supports long range or not."""
|
|
250
|
+
return self.data.get("supportsLongRange")
|
|
251
|
+
|
|
246
252
|
def update(self, data: ControllerDataType) -> None:
|
|
247
253
|
"""Update controller data."""
|
|
248
254
|
self.data = data
|
|
@@ -350,9 +356,11 @@ class Controller(EventBase):
|
|
|
350
356
|
await self.client.async_send_command(
|
|
351
357
|
{
|
|
352
358
|
"command": "controller.provision_smart_start_node",
|
|
353
|
-
"entry":
|
|
354
|
-
|
|
355
|
-
|
|
359
|
+
"entry": (
|
|
360
|
+
provisioning_info
|
|
361
|
+
if isinstance(provisioning_info, str)
|
|
362
|
+
else provisioning_info.to_dict()
|
|
363
|
+
),
|
|
356
364
|
},
|
|
357
365
|
require_schema=11,
|
|
358
366
|
)
|
|
@@ -870,9 +878,9 @@ class Controller(EventBase):
|
|
|
870
878
|
|
|
871
879
|
def handle_firmware_update_progress(self, event: Event) -> None:
|
|
872
880
|
"""Process a firmware update progress event."""
|
|
873
|
-
self._firmware_update_progress = event.data[
|
|
874
|
-
"
|
|
875
|
-
|
|
881
|
+
self._firmware_update_progress = event.data["firmware_update_progress"] = (
|
|
882
|
+
ControllerFirmwareUpdateProgress(event.data["progress"])
|
|
883
|
+
)
|
|
876
884
|
|
|
877
885
|
def handle_firmware_update_finished(self, event: Event) -> None:
|
|
878
886
|
"""Process a firmware update finished event."""
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Data model for a Z-Wave JS controller."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from typing import TypedDict
|
|
@@ -32,3 +33,4 @@ class ControllerDataType(TypedDict, total=False):
|
|
|
32
33
|
rfRegion: int
|
|
33
34
|
status: int
|
|
34
35
|
rebuildRoutesProgress: dict[str, str]
|
|
36
|
+
supportsLongRange: bool
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Provide a model for inclusion and provisioning."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from dataclasses import dataclass
|
|
@@ -48,6 +49,7 @@ class ProvisioningEntry:
|
|
|
48
49
|
security_classes: list[SecurityClass]
|
|
49
50
|
requested_security_classes: list[SecurityClass] | None = None
|
|
50
51
|
status: ProvisioningEntryStatus = ProvisioningEntryStatus.ACTIVE
|
|
52
|
+
protocol: Protocols | None = None
|
|
51
53
|
additional_properties: dict[str, Any] | None = None
|
|
52
54
|
|
|
53
55
|
def to_dict(self) -> dict[str, Any]:
|
|
@@ -62,6 +64,8 @@ class ProvisioningEntry:
|
|
|
62
64
|
data["requestedSecurityClasses"] = [
|
|
63
65
|
sec_cls.value for sec_cls in self.requested_security_classes
|
|
64
66
|
]
|
|
67
|
+
if self.protocol is not None:
|
|
68
|
+
data["protocol"] = self.protocol.value
|
|
65
69
|
return data
|
|
66
70
|
|
|
67
71
|
@classmethod
|
|
@@ -85,6 +89,8 @@ class ProvisioningEntry:
|
|
|
85
89
|
]
|
|
86
90
|
if "status" in data:
|
|
87
91
|
cls_instance.status = ProvisioningEntryStatus(data["status"])
|
|
92
|
+
if "protocol" in data:
|
|
93
|
+
cls_instance.protocol = Protocols(data["protocol"])
|
|
88
94
|
return cls_instance
|
|
89
95
|
|
|
90
96
|
|
|
@@ -3,6 +3,7 @@ Model for a Zwave Node's device class.
|
|
|
3
3
|
|
|
4
4
|
https://zwave-js.github.io/node-zwave-js/#/api/node?id=deviceclass
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
from __future__ import annotations
|
|
7
8
|
|
|
8
9
|
from dataclasses import dataclass
|
|
@@ -39,29 +40,33 @@ class DeviceClass:
|
|
|
39
40
|
|
|
40
41
|
def __init__(self, data: DeviceClassDataType) -> None:
|
|
41
42
|
"""Initialize."""
|
|
42
|
-
self.
|
|
43
|
+
self._basic = DeviceClassItem(**data["basic"])
|
|
44
|
+
self._generic = DeviceClassItem(**data["generic"])
|
|
45
|
+
self._specific = DeviceClassItem(**data["specific"])
|
|
46
|
+
self._mandatory_supported_ccs: list[int] = data["mandatorySupportedCCs"]
|
|
47
|
+
self._mandatory_controlled_ccs: list[int] = data["mandatoryControlledCCs"]
|
|
43
48
|
|
|
44
49
|
@property
|
|
45
50
|
def basic(self) -> DeviceClassItem:
|
|
46
51
|
"""Return basic DeviceClass."""
|
|
47
|
-
return
|
|
52
|
+
return self._basic
|
|
48
53
|
|
|
49
54
|
@property
|
|
50
55
|
def generic(self) -> DeviceClassItem:
|
|
51
56
|
"""Return generic DeviceClass."""
|
|
52
|
-
return
|
|
57
|
+
return self._generic
|
|
53
58
|
|
|
54
59
|
@property
|
|
55
60
|
def specific(self) -> DeviceClassItem:
|
|
56
61
|
"""Return specific DeviceClass."""
|
|
57
|
-
return
|
|
62
|
+
return self._specific
|
|
58
63
|
|
|
59
64
|
@property
|
|
60
65
|
def mandatory_supported_ccs(self) -> list[int]:
|
|
61
66
|
"""Return list of mandatory Supported CC id's."""
|
|
62
|
-
return self.
|
|
67
|
+
return self._mandatory_supported_ccs
|
|
63
68
|
|
|
64
69
|
@property
|
|
65
70
|
def mandatory_controlled_ccs(self) -> list[int]:
|
|
66
71
|
"""Return list of mandatory Controlled CC id's."""
|
|
67
|
-
return self.
|
|
72
|
+
return self._mandatory_controlled_ccs
|
{zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/endpoint.py
RENAMED
|
@@ -3,6 +3,7 @@ Model for a Zwave Node's endpoints.
|
|
|
3
3
|
|
|
4
4
|
https://zwave-js.github.io/node-zwave-js/#/api/endpoint?id=endpoint-properties
|
|
5
5
|
"""
|
|
6
|
+
|
|
6
7
|
from __future__ import annotations
|
|
7
8
|
|
|
8
9
|
import asyncio
|
|
@@ -56,6 +57,7 @@ class Endpoint(EventBase):
|
|
|
56
57
|
self.node = node
|
|
57
58
|
self.data: EndpointDataType = data
|
|
58
59
|
self.values: dict[str, ConfigurationValue | Value] = {}
|
|
60
|
+
self._device_class: DeviceClass | None = None
|
|
59
61
|
self.update(data, values)
|
|
60
62
|
|
|
61
63
|
def __repr__(self) -> str:
|
|
@@ -89,9 +91,7 @@ class Endpoint(EventBase):
|
|
|
89
91
|
@property
|
|
90
92
|
def device_class(self) -> DeviceClass | None:
|
|
91
93
|
"""Return the device_class."""
|
|
92
|
-
|
|
93
|
-
return None
|
|
94
|
-
return DeviceClass(device_class)
|
|
94
|
+
return self._device_class
|
|
95
95
|
|
|
96
96
|
@property
|
|
97
97
|
def installer_icon(self) -> int | None:
|
|
@@ -118,6 +118,10 @@ class Endpoint(EventBase):
|
|
|
118
118
|
) -> None:
|
|
119
119
|
"""Update the endpoint data."""
|
|
120
120
|
self.data = data
|
|
121
|
+
if (device_class := self.data.get("deviceClass")) is None:
|
|
122
|
+
self._device_class = None
|
|
123
|
+
else:
|
|
124
|
+
self._device_class = DeviceClass(device_class)
|
|
121
125
|
|
|
122
126
|
# Remove stale values
|
|
123
127
|
self.values = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Provide a model for the Z-Wave JS node."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import asyncio
|
|
@@ -14,6 +15,7 @@ from ...const import (
|
|
|
14
15
|
DateAndTime,
|
|
15
16
|
NodeStatus,
|
|
16
17
|
PowerLevel,
|
|
18
|
+
Protocols,
|
|
17
19
|
SecurityClass,
|
|
18
20
|
)
|
|
19
21
|
from ...event import Event, EventBase
|
|
@@ -26,7 +28,7 @@ from ...exceptions import (
|
|
|
26
28
|
from ..command_class import CommandClassInfo
|
|
27
29
|
from ..device_class import DeviceClass
|
|
28
30
|
from ..device_config import DeviceConfig
|
|
29
|
-
from ..endpoint import Endpoint
|
|
31
|
+
from ..endpoint import Endpoint, EndpointDataType
|
|
30
32
|
from ..notification import (
|
|
31
33
|
EntryControlNotification,
|
|
32
34
|
EntryControlNotificationDataType,
|
|
@@ -114,6 +116,8 @@ class Node(EventBase):
|
|
|
114
116
|
client, data.get("statistics", DEFAULT_NODE_STATISTICS)
|
|
115
117
|
)
|
|
116
118
|
self._firmware_update_progress: NodeFirmwareUpdateProgress | None = None
|
|
119
|
+
self._device_class: DeviceClass | None = None
|
|
120
|
+
self._last_seen: datetime | None = None
|
|
117
121
|
self.values: dict[str, ConfigurationValue | Value] = {}
|
|
118
122
|
self.endpoints: dict[int, Endpoint] = {}
|
|
119
123
|
self.status_event = asyncio.Event()
|
|
@@ -148,9 +152,7 @@ class Node(EventBase):
|
|
|
148
152
|
@property
|
|
149
153
|
def device_class(self) -> DeviceClass | None:
|
|
150
154
|
"""Return the device_class."""
|
|
151
|
-
|
|
152
|
-
return None
|
|
153
|
-
return DeviceClass(device_class)
|
|
155
|
+
return self._device_class
|
|
154
156
|
|
|
155
157
|
@property
|
|
156
158
|
def installer_icon(self) -> int | None:
|
|
@@ -358,9 +360,7 @@ class Node(EventBase):
|
|
|
358
360
|
@property
|
|
359
361
|
def last_seen(self) -> datetime | None:
|
|
360
362
|
"""Return when the node was last seen."""
|
|
361
|
-
|
|
362
|
-
return datetime.fromisoformat(last_seen)
|
|
363
|
-
return None
|
|
363
|
+
return self._last_seen
|
|
364
364
|
|
|
365
365
|
@property
|
|
366
366
|
def default_volume(self) -> int | float | None:
|
|
@@ -372,17 +372,42 @@ class Node(EventBase):
|
|
|
372
372
|
"""Return the default transition duration."""
|
|
373
373
|
return self.data.get("defaultTransitionDuration")
|
|
374
374
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
375
|
+
@property
|
|
376
|
+
def protocol(self) -> Protocols | None:
|
|
377
|
+
"""Return the protocol used to communicate with this node."""
|
|
378
|
+
if "protocol" in self.data:
|
|
379
|
+
return Protocols(self.data["protocol"])
|
|
380
|
+
return None
|
|
381
|
+
|
|
382
|
+
def _update_endpoints(self, endpoints: list[EndpointDataType]) -> None:
|
|
383
|
+
"""Update the endpoints data."""
|
|
384
|
+
new_endpoints_data = {endpoint["index"]: endpoint for endpoint in endpoints}
|
|
385
|
+
new_endpoint_idxs = set(new_endpoints_data)
|
|
386
|
+
stale_endpoint_idxs = set(self.endpoints) - new_endpoint_idxs
|
|
382
387
|
|
|
388
|
+
# Remove stale endpoints
|
|
389
|
+
for endpoint_idx in stale_endpoint_idxs:
|
|
390
|
+
self.endpoints.pop(endpoint_idx)
|
|
391
|
+
|
|
392
|
+
# Add new endpoints or update existing ones
|
|
393
|
+
for endpoint_idx in new_endpoint_idxs:
|
|
394
|
+
endpoint = new_endpoints_data[endpoint_idx]
|
|
395
|
+
values = {
|
|
396
|
+
value_id: value
|
|
397
|
+
for value_id, value in self.values.items()
|
|
398
|
+
if self.index == value.endpoint
|
|
399
|
+
}
|
|
400
|
+
if endpoint_idx in self.endpoints:
|
|
401
|
+
self.endpoints[endpoint_idx].update(endpoint, values)
|
|
402
|
+
else:
|
|
403
|
+
self.endpoints[endpoint_idx] = Endpoint(
|
|
404
|
+
self.client, self, endpoint, values
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
def _update_values(self, values: list[ValueDataType]) -> None:
|
|
408
|
+
"""Update the values data."""
|
|
383
409
|
new_values_data = {
|
|
384
|
-
_get_value_id_str_from_dict(self, val): val
|
|
385
|
-
for val in self.data.pop("values")
|
|
410
|
+
_get_value_id_str_from_dict(self, val): val for val in values
|
|
386
411
|
}
|
|
387
412
|
new_value_ids = set(new_values_data)
|
|
388
413
|
stale_value_ids = set(self.values) - new_value_ids
|
|
@@ -409,30 +434,25 @@ class Node(EventBase):
|
|
|
409
434
|
# If we can't parse the value, don't store it
|
|
410
435
|
pass
|
|
411
436
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
437
|
+
def update(self, data: NodeDataType) -> None:
|
|
438
|
+
"""Update the internal state data."""
|
|
439
|
+
self.data = copy.deepcopy(data)
|
|
440
|
+
self._device_config = DeviceConfig(self.data.get("deviceConfig", {}))
|
|
441
|
+
if (device_class := self.data.get("deviceClass")) is None:
|
|
442
|
+
self._device_class = None
|
|
443
|
+
else:
|
|
444
|
+
self._device_class = DeviceClass(device_class)
|
|
417
445
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
446
|
+
self._statistics = NodeStatistics(
|
|
447
|
+
self.client, self.data.get("statistics", DEFAULT_NODE_STATISTICS)
|
|
448
|
+
)
|
|
449
|
+
if last_seen := data.get("lastSeen"):
|
|
450
|
+
self._last_seen = datetime.fromisoformat(last_seen)
|
|
451
|
+
if not self._statistics.last_seen:
|
|
452
|
+
self._statistics.last_seen = self.last_seen
|
|
421
453
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
endpoint = new_endpoints_data[endpoint_idx]
|
|
425
|
-
values = {
|
|
426
|
-
value_id: value
|
|
427
|
-
for value_id, value in self.values.items()
|
|
428
|
-
if self.index == value.endpoint
|
|
429
|
-
}
|
|
430
|
-
if endpoint_idx in self.endpoints:
|
|
431
|
-
self.endpoints[endpoint_idx].update(endpoint, values)
|
|
432
|
-
else:
|
|
433
|
-
self.endpoints[endpoint_idx] = Endpoint(
|
|
434
|
-
self.client, self, endpoint, values
|
|
435
|
-
)
|
|
454
|
+
self._update_values(self.data.pop("values"))
|
|
455
|
+
self._update_endpoints(self.data.pop("endpoints"))
|
|
436
456
|
|
|
437
457
|
def get_command_class_values(
|
|
438
458
|
self, command_class: CommandClass, endpoint: int | None = None
|
|
@@ -1099,10 +1119,10 @@ class Node(EventBase):
|
|
|
1099
1119
|
|
|
1100
1120
|
def handle_firmware_update_progress(self, event: Event) -> None:
|
|
1101
1121
|
"""Process a node firmware update progress event."""
|
|
1102
|
-
self._firmware_update_progress = event.data[
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1122
|
+
self._firmware_update_progress = event.data["firmware_update_progress"] = (
|
|
1123
|
+
NodeFirmwareUpdateProgress(
|
|
1124
|
+
self, cast(NodeFirmwareUpdateProgressDataType, event.data["progress"])
|
|
1125
|
+
)
|
|
1106
1126
|
)
|
|
1107
1127
|
|
|
1108
1128
|
def handle_firmware_update_finished(self, event: Event) -> None:
|
|
@@ -1118,5 +1138,5 @@ class Node(EventBase):
|
|
|
1118
1138
|
event.data["statistics_updated"] = self._statistics = NodeStatistics(
|
|
1119
1139
|
self.client, statistics
|
|
1120
1140
|
)
|
|
1121
|
-
if last_seen
|
|
1122
|
-
self.
|
|
1141
|
+
if self._statistics.last_seen:
|
|
1142
|
+
self._last_seen = self._statistics.last_seen
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Data model for a Z-Wave JS node."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from typing import TypedDict
|
|
@@ -65,3 +66,4 @@ class NodeDataType(TypedDict, total=False):
|
|
|
65
66
|
lastSeen: str
|
|
66
67
|
defaultVolume: int | float | None
|
|
67
68
|
defaultTransitionDuration: int | float | None
|
|
69
|
+
protocol: int
|
{zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/statistics.py
RENAMED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Common models for statistics."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
from dataclasses import dataclass, field
|
|
@@ -94,9 +95,11 @@ class RouteStatistics:
|
|
|
94
95
|
"rssi": self.data.get("rssi"),
|
|
95
96
|
"repeater_rssi": self.data.get("repeaterRSSI", []),
|
|
96
97
|
"route_failed_between": (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
(
|
|
99
|
+
self.route_failed_between[0],
|
|
100
|
+
self.route_failed_between[1],
|
|
101
|
+
)
|
|
102
|
+
if self.route_failed_between
|
|
103
|
+
else None
|
|
104
|
+
),
|
|
102
105
|
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
"""Basic CLI to test Z-Wave JS server."""
|
|
2
|
+
|
|
2
3
|
from __future__ import annotations
|
|
3
4
|
|
|
4
5
|
import argparse
|
|
@@ -17,7 +18,6 @@ LOGGER = logging.getLogger(__package__)
|
|
|
17
18
|
|
|
18
19
|
def get_arguments() -> argparse.Namespace:
|
|
19
20
|
"""Get parsed passed in arguments."""
|
|
20
|
-
|
|
21
21
|
parser = argparse.ArgumentParser(description="Z-Wave JS Server Python")
|
|
22
22
|
parser.add_argument("--debug", action="store_true", help="Log with debug level")
|
|
23
23
|
parser.add_argument(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/model/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{zwave-js-server-python-0.55.3 → zwave_js_server_python-0.56.0}/zwave_js_server/util/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|