File: device_config.py

package info (click to toggle)
zwave-js-server-python 0.67.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,820 kB
  • sloc: python: 15,886; sh: 21; javascript: 16; makefile: 2
file content (228 lines) | stat: -rw-r--r-- 6,525 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
"""
Model for a Zwave Node's device config.

https://zwave-js.github.io/node-zwave-js/#/api/node?id=deviceconfig
"""

from __future__ import annotations

from typing import Any, Literal, TypedDict


class DeviceDeviceDataType(TypedDict, total=False):
    """Represent a device device data dict type."""

    productType: str | int
    productId: str | int


class DeviceDevice:
    """Model for a Zwave Node's device config's device."""

    def __init__(self, data: DeviceDeviceDataType) -> None:
        """Initialize."""
        self.data = data

    @property
    def product_type(self) -> str | int | None:
        """Return product type."""
        return self.data.get("productType")

    @property
    def product_id(self) -> str | int | None:
        """Return product id."""
        return self.data.get("productId")


class DeviceFirmwareVersionRangeDataType(TypedDict, total=False):
    """Represent a device firmware version range data dict type."""

    min: str
    max: str


class DeviceFirmwareVersionRange:
    """Model for a Zwave Node's device config's firmware version range."""

    def __init__(self, data: DeviceFirmwareVersionRangeDataType) -> None:
        """Initialize."""
        self.data = data

    @property
    def min(self) -> str | None:
        """Return min version."""
        return self.data.get("min")

    @property
    def max(self) -> str | None:
        """Return max version."""
        return self.data.get("max")


class CommentDataType(TypedDict):
    """Represent a device config's comment data dict type."""

    # See PR for suggested meanings of each level:
    # https://github.com/zwave-js/node-zwave-js/pull/3947
    level: Literal["info", "warning", "error"]
    text: str


class DeviceMetadataDataType(TypedDict, total=False):
    """Represent a device metadata data dict type."""

    wakeup: str
    inclusion: str
    exclusion: str
    reset: str
    manual: str
    comments: CommentDataType | list[CommentDataType]


class DeviceMetadata:
    """Model for a Zwave Node's device config's metadata."""

    def __init__(self, data: DeviceMetadataDataType) -> None:
        """Initialize."""
        self.data = data

    @property
    def wakeup(self) -> str | None:
        """Return wakeup instructions."""
        return self.data.get("wakeup")

    @property
    def inclusion(self) -> str | None:
        """Return inclusion instructions."""
        return self.data.get("inclusion")

    @property
    def exclusion(self) -> str | None:
        """Return exclusion instructions."""
        return self.data.get("exclusion")

    @property
    def reset(self) -> str | None:
        """Return reset instructions."""
        return self.data.get("reset")

    @property
    def manual(self) -> str | None:
        """Return manual instructions."""
        return self.data.get("manual")

    @property
    def comments(self) -> list[CommentDataType]:
        """Return list of comments about device."""
        comments = self.data.get("comments", [])
        if isinstance(comments, dict):
            return [comments]
        return comments


class DeviceConfigDataType(TypedDict, total=False):
    """Represent a device config data dict type."""

    filename: str
    manufacturer: str
    manufacturerId: int
    label: str
    description: str
    devices: list[DeviceDeviceDataType]
    firmwareVersion: DeviceFirmwareVersionRangeDataType
    associations: dict[str, dict]
    paramInformation: dict[str, dict]
    supportsZWavePlus: bool
    proprietary: dict
    compat: dict[str, Any]
    metadata: DeviceMetadataDataType
    isEmbedded: bool


class DeviceConfig:
    """Model for a Zwave Node's device config."""

    def __init__(self, data: DeviceConfigDataType) -> None:
        """Initialize."""
        self.data = data
        self._devices = [
            DeviceDevice(device) for device in self.data.get("devices", [])
        ]
        self._firmware_version = DeviceFirmwareVersionRange(
            self.data.get("firmwareVersion", {})
        )
        self._metadata = DeviceMetadata(self.data.get("metadata", {}))

    @property
    def filename(self) -> str | None:
        """Return config filename."""
        return self.data.get("filename")

    @property
    def manufacturer(self) -> str | None:
        """Return name of the manufacturer."""
        return self.data.get("manufacturer")

    @property
    def manufacturer_id(self) -> int | None:
        """Return manufacturer id (as defined in specs)."""
        return self.data.get("manufacturerId")

    @property
    def label(self) -> str | None:
        """Return short label for the device."""
        return self.data.get("label")

    @property
    def description(self) -> str | None:
        """Return longer description of the device, usually the full name."""
        return self.data.get("description")

    @property
    def devices(self) -> list[DeviceDevice]:
        """Return list of product type and product ID combinations."""
        return self._devices

    @property
    def firmware_version(self) -> DeviceFirmwareVersionRange:
        """Return firmware version range this config is valid for."""
        return self._firmware_version

    @property
    def associations(self) -> dict[str, dict]:
        """Return dict of association groups the device supports."""
        return self.data.get("associations", {})

    @property
    def param_information(self) -> dict[str, dict]:
        """Return dictionary of configuration parameters the device supports."""
        return self.data.get("paramInformation", {})

    @property
    def supports_zwave_plus(self) -> bool | None:
        """Return if the device complies with the Z-Wave+ standard."""
        return self.data.get("supportsZWavePlus")

    @property
    def proprietary(self) -> dict:
        """Return dictionary of settings for the proprietary CC."""
        return self.data.get("proprietary", {})

    @property
    def compat(self) -> dict[str, dict]:
        """Return compatibility flags."""
        return self.data.get("compat", {})

    @property
    def metadata(self) -> DeviceMetadata:
        """Return metadata."""
        return self._metadata

    @property
    def is_embedded(self) -> bool | None:
        """Return whether device config is embedded in zwave-js-server."""
        return self.data.get("isEmbedded")

    def to_dict(self) -> DeviceConfigDataType:
        """Return dict representation of device config."""
        return self.data.copy()