pyvlx 0.2.27__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.
Files changed (84) hide show
  1. pyvlx/__init__.py +21 -0
  2. pyvlx/api/__init__.py +23 -0
  3. pyvlx/api/activate_scene.py +63 -0
  4. pyvlx/api/api_event.py +73 -0
  5. pyvlx/api/command_send.py +85 -0
  6. pyvlx/api/factory_default.py +34 -0
  7. pyvlx/api/frame_creation.py +202 -0
  8. pyvlx/api/frames/__init__.py +76 -0
  9. pyvlx/api/frames/alias_array.py +45 -0
  10. pyvlx/api/frames/frame.py +56 -0
  11. pyvlx/api/frames/frame_activate_scene.py +92 -0
  12. pyvlx/api/frames/frame_activation_log_updated.py +14 -0
  13. pyvlx/api/frames/frame_command_send.py +280 -0
  14. pyvlx/api/frames/frame_discover_nodes.py +64 -0
  15. pyvlx/api/frames/frame_error_notification.py +42 -0
  16. pyvlx/api/frames/frame_facory_default.py +32 -0
  17. pyvlx/api/frames/frame_get_all_nodes_information.py +218 -0
  18. pyvlx/api/frames/frame_get_limitation.py +127 -0
  19. pyvlx/api/frames/frame_get_local_time.py +38 -0
  20. pyvlx/api/frames/frame_get_network_setup.py +64 -0
  21. pyvlx/api/frames/frame_get_node_information.py +223 -0
  22. pyvlx/api/frames/frame_get_protocol_version.py +53 -0
  23. pyvlx/api/frames/frame_get_scene_list.py +82 -0
  24. pyvlx/api/frames/frame_get_state.py +47 -0
  25. pyvlx/api/frames/frame_get_version.py +72 -0
  26. pyvlx/api/frames/frame_helper.py +40 -0
  27. pyvlx/api/frames/frame_house_status_monitor_disable_cfm.py +14 -0
  28. pyvlx/api/frames/frame_house_status_monitor_disable_req.py +14 -0
  29. pyvlx/api/frames/frame_house_status_monitor_enable_cfm.py +14 -0
  30. pyvlx/api/frames/frame_house_status_monitor_enable_req.py +14 -0
  31. pyvlx/api/frames/frame_leave_learn_state.py +41 -0
  32. pyvlx/api/frames/frame_node_information_changed.py +57 -0
  33. pyvlx/api/frames/frame_node_state_position_changed_notification.py +84 -0
  34. pyvlx/api/frames/frame_password_change.py +114 -0
  35. pyvlx/api/frames/frame_password_enter.py +70 -0
  36. pyvlx/api/frames/frame_reboot.py +32 -0
  37. pyvlx/api/frames/frame_set_node_name.py +73 -0
  38. pyvlx/api/frames/frame_set_utc.py +45 -0
  39. pyvlx/api/frames/frame_status_request.py +212 -0
  40. pyvlx/api/get_all_nodes_information.py +46 -0
  41. pyvlx/api/get_limitation.py +64 -0
  42. pyvlx/api/get_local_time.py +34 -0
  43. pyvlx/api/get_network_setup.py +34 -0
  44. pyvlx/api/get_node_information.py +42 -0
  45. pyvlx/api/get_protocol_version.py +40 -0
  46. pyvlx/api/get_scene_list.py +49 -0
  47. pyvlx/api/get_state.py +43 -0
  48. pyvlx/api/get_version.py +34 -0
  49. pyvlx/api/house_status_monitor.py +52 -0
  50. pyvlx/api/leave_learn_state.py +33 -0
  51. pyvlx/api/password_enter.py +39 -0
  52. pyvlx/api/reboot.py +33 -0
  53. pyvlx/api/session_id.py +20 -0
  54. pyvlx/api/set_node_name.py +32 -0
  55. pyvlx/api/set_utc.py +31 -0
  56. pyvlx/api/status_request.py +48 -0
  57. pyvlx/config.py +54 -0
  58. pyvlx/connection.py +182 -0
  59. pyvlx/const.py +685 -0
  60. pyvlx/dataobjects.py +161 -0
  61. pyvlx/discovery.py +100 -0
  62. pyvlx/exception.py +26 -0
  63. pyvlx/heartbeat.py +79 -0
  64. pyvlx/klf200gateway.py +167 -0
  65. pyvlx/lightening_device.py +102 -0
  66. pyvlx/log.py +4 -0
  67. pyvlx/node.py +74 -0
  68. pyvlx/node_helper.py +165 -0
  69. pyvlx/node_updater.py +162 -0
  70. pyvlx/nodes.py +99 -0
  71. pyvlx/on_off_switch.py +44 -0
  72. pyvlx/opening_device.py +644 -0
  73. pyvlx/parameter.py +357 -0
  74. pyvlx/py.typed +0 -0
  75. pyvlx/pyvlx.py +124 -0
  76. pyvlx/scene.py +53 -0
  77. pyvlx/scenes.py +60 -0
  78. pyvlx/slip.py +48 -0
  79. pyvlx/string_helper.py +20 -0
  80. pyvlx-0.2.27.dist-info/METADATA +122 -0
  81. pyvlx-0.2.27.dist-info/RECORD +84 -0
  82. pyvlx-0.2.27.dist-info/WHEEL +5 -0
  83. pyvlx-0.2.27.dist-info/licenses/LICENSE +165 -0
  84. pyvlx-0.2.27.dist-info/top_level.txt +1 -0
@@ -0,0 +1,70 @@
1
+ """Module for password enter frame classes."""
2
+ from enum import Enum
3
+ from typing import Optional
4
+
5
+ from pyvlx.const import Command
6
+ from pyvlx.exception import PyVLXException
7
+ from pyvlx.string_helper import bytes_to_string, string_to_bytes
8
+
9
+ from .frame import FrameBase
10
+
11
+
12
+ class FramePasswordEnterRequest(FrameBase):
13
+ """Frame for sending password enter request."""
14
+
15
+ MAX_SIZE = 32
16
+ PAYLOAD_LEN = 32
17
+
18
+ def __init__(self, password: Optional[str] = None):
19
+ """Init Frame."""
20
+ super().__init__(Command.GW_PASSWORD_ENTER_REQ)
21
+ self.password = password
22
+
23
+ def get_payload(self) -> bytes:
24
+ """Return Payload."""
25
+ if self.password is None:
26
+ raise PyVLXException("password is none")
27
+ if len(self.password) > self.MAX_SIZE:
28
+ raise PyVLXException("password is too long")
29
+ return string_to_bytes(self.password, self.MAX_SIZE)
30
+
31
+ def from_payload(self, payload: bytes) -> None:
32
+ """Init frame from binary data."""
33
+ self.password = bytes_to_string(payload)
34
+
35
+ def __str__(self) -> str:
36
+ """Return human readable string."""
37
+ password_esc = (
38
+ None if self.password is None else "{}****".format(self.password[:2])
39
+ )
40
+ return '<{} password="{}"/>'.format(type(self).__name__, password_esc)
41
+
42
+
43
+ class PasswordEnterConfirmationStatus(Enum):
44
+ """Enum class for status of password enter confirmation."""
45
+
46
+ SUCCESSFUL = 0
47
+ FAILED = 1
48
+
49
+
50
+ class FramePasswordEnterConfirmation(FrameBase):
51
+ """Frame for confirmation for sent password."""
52
+
53
+ PAYLOAD_LEN = 1
54
+
55
+ def __init__(self, status: PasswordEnterConfirmationStatus = PasswordEnterConfirmationStatus.SUCCESSFUL):
56
+ """Init Frame."""
57
+ super().__init__(Command.GW_PASSWORD_ENTER_CFM)
58
+ self.status = status
59
+
60
+ def get_payload(self) -> bytes:
61
+ """Return Payload."""
62
+ return bytes([self.status.value])
63
+
64
+ def from_payload(self, payload: bytes) -> None:
65
+ """Init frame from binary data."""
66
+ self.status = PasswordEnterConfirmationStatus(payload[0])
67
+
68
+ def __str__(self) -> str:
69
+ """Return human readable string."""
70
+ return '<{} status="{}"/>'.format(type(self).__name__, self.status)
@@ -0,0 +1,32 @@
1
+ """Module for reboot frame classes."""
2
+ from pyvlx.const import Command
3
+
4
+ from .frame import FrameBase
5
+
6
+
7
+ class FrameGatewayRebootRequest(FrameBase):
8
+ """Frame for requesting reboot."""
9
+
10
+ PAYLOAD_LEN = 0
11
+
12
+ def __init__(self) -> None:
13
+ """Init Frame."""
14
+ super().__init__(Command.GW_REBOOT_REQ)
15
+
16
+ def __str__(self) -> str:
17
+ """Return human readable string."""
18
+ return '<{}/>'.format(type(self).__name__)
19
+
20
+
21
+ class FrameGatewayRebootConfirmation(FrameBase):
22
+ """Frame for response for reboot requests."""
23
+
24
+ PAYLOAD_LEN = 0
25
+
26
+ def __init__(self) -> None:
27
+ """Init Frame."""
28
+ super().__init__(Command.GW_REBOOT_CFM)
29
+
30
+ def __str__(self) -> str:
31
+ """Return human readable string."""
32
+ return '<{}/>'.format(type(self).__name__)
@@ -0,0 +1,73 @@
1
+ """Module for requesting change of node name."""
2
+ from enum import Enum
3
+ from typing import Optional
4
+
5
+ from pyvlx.const import Command
6
+ from pyvlx.string_helper import bytes_to_string, string_to_bytes
7
+
8
+ from .frame import FrameBase
9
+
10
+
11
+ class FrameSetNodeNameRequest(FrameBase):
12
+ """Frame for requesting node name change."""
13
+
14
+ PAYLOAD_LEN = 65
15
+
16
+ def __init__(self, node_id: int = 0, name: Optional[str] = None):
17
+ """Init Frame."""
18
+ super().__init__(Command.GW_SET_NODE_NAME_REQ)
19
+ self.node_id = node_id
20
+ self.name = name
21
+
22
+ def get_payload(self) -> bytes:
23
+ """Return Payload."""
24
+ ret = bytes([self.node_id])
25
+ assert self.name is not None
26
+ ret += string_to_bytes(self.name, 64)
27
+ return ret
28
+
29
+ def from_payload(self, payload: bytes) -> None:
30
+ """Init frame from binary data."""
31
+ self.node_id = payload[0]
32
+ self.name = bytes_to_string(payload[1:65])
33
+
34
+ def __str__(self) -> str:
35
+ """Return human readable string."""
36
+ return '<{} node_id="{}" name="{}"/>'.format(
37
+ type(self).__name__, self.node_id, self.name
38
+ )
39
+
40
+
41
+ class SetNodeNameConfirmationStatus(Enum):
42
+ """Enum class for status of password enter confirmation."""
43
+
44
+ OK = 0
45
+ ERROR_REQUEST_REJECTED = 1
46
+ ERROR_INVALID_SYSTEM_TABLE_INDEX = 2
47
+
48
+
49
+ class FrameSetNodeNameConfirmation(FrameBase):
50
+ """Frame for confirmation for set node name."""
51
+
52
+ PAYLOAD_LEN = 2
53
+
54
+ def __init__(self, status: SetNodeNameConfirmationStatus = SetNodeNameConfirmationStatus.OK, node_id: int = 0):
55
+ """Init Frame."""
56
+ super().__init__(Command.GW_SET_NODE_NAME_CFM)
57
+ self.status = status
58
+ self.node_id = node_id
59
+
60
+ def get_payload(self) -> bytes:
61
+ """Return Payload."""
62
+ return bytes([self.status.value, self.node_id])
63
+
64
+ def from_payload(self, payload: bytes) -> None:
65
+ """Init frame from binary data."""
66
+ self.status = SetNodeNameConfirmationStatus(payload[0])
67
+ self.node_id = payload[1]
68
+
69
+ def __str__(self) -> str:
70
+ """Return human readable string."""
71
+ return '<{} node_id="{}" status="{}"/>'.format(
72
+ type(self).__name__, self.node_id, self.status
73
+ )
@@ -0,0 +1,45 @@
1
+ """Module for sending command to gw."""
2
+ import struct
3
+ from datetime import datetime
4
+
5
+ from pyvlx.const import Command
6
+
7
+ from .frame import FrameBase
8
+
9
+
10
+ class FrameSetUTCConfirmation(FrameBase):
11
+ """Frame for confirmation for setting UTC time."""
12
+
13
+ PAYLOAD_LEN = 0
14
+
15
+ def __init__(self) -> None:
16
+ """Init Frame."""
17
+ super().__init__(Command.GW_SET_UTC_CFM)
18
+
19
+
20
+ class FrameSetUTCRequest(FrameBase):
21
+ """Frame for command for setting UTC time."""
22
+
23
+ PAYLOAD_LEN = 4
24
+
25
+ def __init__(self, timestamp: float = 0):
26
+ """Init Frame."""
27
+ super().__init__(Command.GW_SET_UTC_REQ)
28
+ self.timestamp = timestamp
29
+
30
+ @property
31
+ def timestamp_formatted(self) -> str:
32
+ """Return time as human readable string."""
33
+ return datetime.fromtimestamp(self.timestamp).strftime("%Y-%m-%d %H:%M:%S")
34
+
35
+ def get_payload(self) -> bytes:
36
+ """Return Payload."""
37
+ return struct.pack(">I", self.timestamp)
38
+
39
+ def from_payload(self, payload: bytes) -> None:
40
+ """Init frame from binary data."""
41
+ self.timestamp = struct.unpack(">I", payload[0:4])[0]
42
+
43
+ def __str__(self) -> str:
44
+ """Return human readable string."""
45
+ return '<{} time="{}"/>'.format(type(self).__name__, self.timestamp_formatted)
@@ -0,0 +1,212 @@
1
+ """Module for get node information from gateway."""
2
+ from enum import Enum
3
+ from typing import Dict, List, Optional
4
+
5
+ from pyvlx.const import (
6
+ Command, NodeParameter, RunStatus, StatusReply, StatusType)
7
+ from pyvlx.exception import PyVLXException
8
+ from pyvlx.parameter import Parameter
9
+
10
+ from .frame import FrameBase
11
+
12
+
13
+ class FrameStatusRequestRequest(FrameBase):
14
+ """Frame for status request request."""
15
+
16
+ PAYLOAD_LEN = 26
17
+
18
+ def __init__(self, session_id: Optional[int] = None, node_ids: Optional[List[int]] = None):
19
+ """Init Frame."""
20
+ super().__init__(Command.GW_STATUS_REQUEST_REQ)
21
+ self.session_id = session_id
22
+ self.node_ids = node_ids if node_ids is not None else []
23
+ self.status_type = StatusType.REQUEST_CURRENT_POSITION
24
+ self.fpi1 = 254 # Request FP1 to FP7
25
+ self.fpi2 = 0
26
+
27
+ def get_payload(self) -> bytes:
28
+ """Return Payload."""
29
+ assert self.session_id is not None
30
+ ret = bytes([self.session_id >> 8 & 255, self.session_id & 255])
31
+ ret += bytes([len(self.node_ids)]) # index array count
32
+ ret += bytes(self.node_ids) + bytes(20 - len(self.node_ids))
33
+ ret += bytes([self.status_type.value])
34
+ ret += bytes([self.fpi1])
35
+ ret += bytes([self.fpi2])
36
+ return ret
37
+
38
+ def from_payload(self, payload: bytes) -> None:
39
+ """Init frame from binary data."""
40
+ self.session_id = payload[0] * 256 + payload[1]
41
+ len_node_ids = payload[2]
42
+ if len_node_ids > 20:
43
+ raise PyVLXException("command_send_request_wrong_node_length")
44
+ self.node_ids = []
45
+ for i in range(len_node_ids):
46
+ self.node_ids.append(payload[3] + i)
47
+
48
+ self.status_type = StatusType(payload[23])
49
+ self.fpi1 = payload[24]
50
+ self.fpi2 = payload[25]
51
+
52
+ def __str__(self) -> str:
53
+ """Return human readable string."""
54
+ return (
55
+ '<{} session_id="{}" node_ids="{}" '
56
+ 'status_type="{}" fpi1="{}" fpi2="{}"/>'.format(
57
+ type(self).__name__, self.session_id,
58
+ self.node_ids,
59
+ self.status_type, self.fpi1, self.fpi2
60
+ )
61
+ )
62
+
63
+
64
+ class StatusRequestStatus(Enum):
65
+ """Enum for status request status."""
66
+
67
+ REJECTED = 0
68
+ ACCEPTED = 1
69
+
70
+
71
+ class FrameStatusRequestConfirmation(FrameBase):
72
+ """Frame for confirmation for status request request."""
73
+
74
+ PAYLOAD_LEN = 3
75
+
76
+ def __init__(self, session_id: Optional[int] = None, status: Optional[StatusRequestStatus] = None):
77
+ """Init Frame."""
78
+ super().__init__(Command.GW_STATUS_REQUEST_CFM)
79
+ self.session_id = session_id
80
+ self.status = status
81
+
82
+ def get_payload(self) -> bytes:
83
+ """Return Payload."""
84
+ assert self.session_id is not None
85
+ ret = bytes([self.session_id >> 8 & 255, self.session_id & 255])
86
+ assert self.status is not None
87
+ ret += bytes([self.status.value])
88
+ return ret
89
+
90
+ def from_payload(self, payload: bytes) -> None:
91
+ """Init frame from binary data."""
92
+ self.session_id = payload[0] * 256 + payload[1]
93
+ self.status = StatusRequestStatus(payload[2])
94
+
95
+ def __str__(self) -> str:
96
+ """Return human readable string."""
97
+ return '<{} session_id="{}" status="{}"/>'.format(
98
+ type(self).__name__, self.session_id, self.status
99
+ )
100
+
101
+
102
+ class FrameStatusRequestNotification(FrameBase):
103
+ """Frame for notification of status request request."""
104
+
105
+ # PAYLOAD_LEN = 59
106
+ # No PAYLOAD_LEN because it is variable depending on StatusType
107
+
108
+ def __init__(self) -> None:
109
+ """Init Frame."""
110
+ super().__init__(Command.GW_STATUS_REQUEST_NTF)
111
+ self.session_id = 0
112
+ self.status_id = 0
113
+ self.node_id = 0
114
+ self.run_status = RunStatus.EXECUTION_COMPLETED
115
+ self.status_reply = StatusReply.UNKNOWN_STATUS_REPLY
116
+ self.status_type = StatusType.REQUEST_TARGET_POSITION
117
+ self.status_count = 0
118
+ self.parameter_data: Dict[NodeParameter, Parameter] = {}
119
+ self.target_position = Parameter()
120
+ self.current_position = Parameter()
121
+ self.remaining_time = 0
122
+ self.last_master_execution_address = b''
123
+ self.last_command_originator = 0
124
+
125
+ def get_payload(self) -> bytes:
126
+ """Return Payload."""
127
+ payload = bytes()
128
+ payload += bytes([self.session_id >> 8 & 255, self.session_id & 255])
129
+ payload += bytes([self.status_id])
130
+ payload += bytes([self.node_id])
131
+ payload += bytes([self.run_status.value])
132
+ payload += bytes([self.status_reply.value])
133
+ payload += bytes([self.status_type.value])
134
+ if self.status_type == StatusType.REQUEST_MAIN_INFO:
135
+ payload += bytes(self.target_position.raw)
136
+ payload += bytes(self.current_position.raw)
137
+ payload += bytes([self.remaining_time >> 8 & 255, self.remaining_time & 255])
138
+ payload += self.last_master_execution_address
139
+ payload += bytes([self.last_command_originator])
140
+ else:
141
+ payload += bytes([self.status_count])
142
+ keys = self.parameter_data.keys()
143
+ for key in keys:
144
+ payload += bytes([key.value])
145
+ payload += bytes(self.parameter_data[key].raw)
146
+ payload += bytes(51 - len(self.parameter_data))
147
+
148
+ return payload
149
+
150
+ def from_payload(self, payload: bytes) -> None:
151
+ """Init frame from binary data."""
152
+ self.session_id = payload[0] * 256 + payload[1]
153
+ self.status_id = payload[2]
154
+ self.node_id = payload[3]
155
+ self.run_status = RunStatus(payload[4])
156
+ self.status_reply = StatusReply(payload[5])
157
+ self.status_type = StatusType(payload[6])
158
+ if self.status_type == StatusType.REQUEST_MAIN_INFO:
159
+ self.target_position = Parameter(payload[7:8])
160
+ self.current_position = Parameter(payload[9:10])
161
+ self.remaining_time = payload[11] * 256 + payload[12]
162
+ self.last_master_execution_address = payload[13:16]
163
+ self.last_command_originator = payload[17]
164
+ else:
165
+ self.status_count = payload[7]
166
+ for i in range(8, 8 + self.status_count*3, 3):
167
+ self.parameter_data.update({NodeParameter(payload[i]): Parameter(payload[i+1:i+3])})
168
+
169
+ def __str__(self) -> str:
170
+ """Return human readable string."""
171
+ if self.status_type == StatusType.REQUEST_MAIN_INFO:
172
+ return (
173
+ '<{} session_id="{}" status_id="{}" '
174
+ 'node_id="{}" run_status="{}" status_reply="{}" status_type="{}" target_position="{}" '
175
+ 'current_position="{}" remaining_time="{}" last_master_execution_address="{!r}" last_command_originator="{}"/>'.format(
176
+ type(self).__name__,
177
+ self.session_id,
178
+ self.status_id,
179
+ self.node_id,
180
+ self.run_status,
181
+ self.status_reply,
182
+ self.status_type,
183
+ self.target_position,
184
+ self.current_position,
185
+ self.remaining_time,
186
+ self.last_master_execution_address,
187
+ self.last_command_originator,
188
+ )
189
+ )
190
+
191
+ parameter_data_str = ""
192
+ for key, value in self.parameter_data.items():
193
+ parameter_data_str += "%s: %s, " % (
194
+ str(key),
195
+ str(value),
196
+ )
197
+
198
+ return (
199
+ '<{} session_id="{}" status_id="{}" '
200
+ 'node_id="{}" run_status="{}" status_reply="{}" status_type="{}" status_count="{}" '
201
+ 'parameter_data="{}"/>'.format(
202
+ type(self).__name__,
203
+ self.session_id,
204
+ self.status_id,
205
+ self.node_id,
206
+ self.run_status,
207
+ self.status_reply,
208
+ self.status_type,
209
+ self.status_count,
210
+ parameter_data_str
211
+ )
212
+ )
@@ -0,0 +1,46 @@
1
+ """Module for retrieving node information from API."""
2
+ from typing import TYPE_CHECKING, List
3
+
4
+ from pyvlx.log import PYVLXLOG
5
+
6
+ from .api_event import ApiEvent
7
+ from .frames import (
8
+ FrameBase, FrameGetAllNodesInformationConfirmation,
9
+ FrameGetAllNodesInformationFinishedNotification,
10
+ FrameGetAllNodesInformationNotification,
11
+ FrameGetAllNodesInformationRequest)
12
+
13
+ if TYPE_CHECKING:
14
+ from pyvlx import PyVLX
15
+
16
+
17
+ class GetAllNodesInformation(ApiEvent):
18
+ """Class for retrieving node information from API."""
19
+
20
+ def __init__(self, pyvlx: "PyVLX"):
21
+ """Initialize SceneList class."""
22
+ super().__init__(pyvlx=pyvlx)
23
+ self.number_of_nodes = 0
24
+ self.success = False
25
+ self.notification_frames: List[FrameGetAllNodesInformationNotification] = []
26
+
27
+ async def handle_frame(self, frame: FrameBase) -> bool:
28
+ """Handle incoming API frame, return True if this was the expected frame."""
29
+ if isinstance(frame, FrameGetAllNodesInformationConfirmation):
30
+ self.number_of_nodes = frame.number_of_nodes
31
+ # We are still waiting for FrameGetAllNodesInformationNotification
32
+ return False
33
+ if isinstance(frame, FrameGetAllNodesInformationNotification):
34
+ self.notification_frames.append(frame)
35
+ if isinstance(frame, FrameGetAllNodesInformationFinishedNotification):
36
+ if self.number_of_nodes != len(self.notification_frames):
37
+ PYVLXLOG.warning(
38
+ "Number of received scenes does not match expected number"
39
+ )
40
+ self.success = True
41
+ return True
42
+ return False
43
+
44
+ def request_frame(self) -> FrameGetAllNodesInformationRequest:
45
+ """Construct initiating frame."""
46
+ return FrameGetAllNodesInformationRequest()
@@ -0,0 +1,64 @@
1
+ """Module for retrieving limitation value from API."""
2
+
3
+ from typing import TYPE_CHECKING, Optional
4
+
5
+ from ..const import LimitationType, Originator
6
+ from ..parameter import Position
7
+ from .api_event import ApiEvent
8
+ from .frames import (
9
+ FrameBase, FrameGetLimitationStatus, FrameGetLimitationStatusConfirmation,
10
+ FrameGetLimitationStatusNotification)
11
+ from .session_id import get_new_session_id
12
+
13
+ if TYPE_CHECKING:
14
+ from pyvlx import PyVLX
15
+
16
+
17
+ class GetLimitation(ApiEvent):
18
+ """Class for retrieving gateway state from API."""
19
+
20
+ def __init__(self, pyvlx: "PyVLX", node_id: int, limitation_type: LimitationType = LimitationType.MIN_LIMITATION):
21
+ """Initialize SceneList class."""
22
+ super().__init__(pyvlx=pyvlx)
23
+ self.node_id = node_id
24
+ self.limitation_type = limitation_type
25
+ self.success = False
26
+ self.notification_frame: Optional[FrameGetLimitationStatusNotification] = None
27
+ self.session_id: Optional[int] = None
28
+ self.min_value_raw: Optional[bytes] = None
29
+ self.max_value_raw: Optional[bytes] = None
30
+ self.originator: Optional[Originator] = None
31
+ self.limit_time: Optional[int] = None
32
+
33
+ @property
34
+ def max_value(self) -> int:
35
+ """Return max value."""
36
+ assert self.max_value_raw is not None
37
+ return Position.to_percent(self.max_value_raw)
38
+
39
+ @property
40
+ def min_value(self) -> int:
41
+ """Return min value."""
42
+ assert self.min_value_raw is not None
43
+ return Position.to_percent(self.min_value_raw)
44
+
45
+ async def handle_frame(self, frame: FrameBase) -> bool:
46
+ """Handle incoming API frame, return True if this was the expected frame."""
47
+ if isinstance(frame, FrameGetLimitationStatusConfirmation):
48
+ return False # Wait for Notification Frame
49
+ if isinstance(frame, FrameGetLimitationStatusNotification):
50
+ if frame.session_id == self.session_id:
51
+ self.success = True
52
+ self.min_value_raw = frame.min_value
53
+ self.max_value_raw = frame.max_value
54
+ self.originator = frame.limit_originator
55
+ self.limit_time = frame.limit_time
56
+ self.notification_frame = frame
57
+ return True
58
+ return False
59
+
60
+ def request_frame(self) -> FrameGetLimitationStatus:
61
+ """Construct initiating frame."""
62
+ self.session_id = get_new_session_id()
63
+ return FrameGetLimitationStatus(node_ids=[self.node_id], session_id=self.session_id,
64
+ limitation_type=self.limitation_type)
@@ -0,0 +1,34 @@
1
+ """Module for local time firmware version from API."""
2
+ from typing import TYPE_CHECKING
3
+
4
+ from pyvlx.dataobjects import DtoLocalTime
5
+
6
+ from .api_event import ApiEvent
7
+ from .frames import (
8
+ FrameBase, FrameGetLocalTimeConfirmation, FrameGetLocalTimeRequest)
9
+
10
+ if TYPE_CHECKING:
11
+ from pyvlx import PyVLX
12
+
13
+
14
+ class GetLocalTime(ApiEvent):
15
+ """Class for retrieving firmware version from API."""
16
+
17
+ def __init__(self, pyvlx: "PyVLX"):
18
+ """Initialize GetLocalTime class."""
19
+ super().__init__(pyvlx=pyvlx)
20
+ self.success = False
21
+ self.localtime = DtoLocalTime()
22
+
23
+ async def handle_frame(self, frame: FrameBase) -> bool:
24
+ """Handle incoming API frame, return True if this was the expected frame."""
25
+ if not isinstance(frame, FrameGetLocalTimeConfirmation):
26
+ return False
27
+ self.localtime = frame.time
28
+ self.success = True
29
+
30
+ return True
31
+
32
+ def request_frame(self) -> FrameGetLocalTimeRequest:
33
+ """Construct initiating frame."""
34
+ return FrameGetLocalTimeRequest()
@@ -0,0 +1,34 @@
1
+ """Module for retrieving gateway state from API."""
2
+ from typing import TYPE_CHECKING
3
+
4
+ from pyvlx.dataobjects import DtoNetworkSetup
5
+
6
+ from .api_event import ApiEvent
7
+ from .frames import (
8
+ FrameBase, FrameGetNetworkSetupConfirmation, FrameGetNetworkSetupRequest)
9
+
10
+ if TYPE_CHECKING:
11
+ from pyvlx import PyVLX
12
+
13
+
14
+ class GetNetworkSetup(ApiEvent):
15
+ """Class for retrieving gateway state from API."""
16
+
17
+ def __init__(self, pyvlx: "PyVLX"):
18
+ """Initialize GetNetworkSetup class."""
19
+ super().__init__(pyvlx=pyvlx)
20
+ self.success = False
21
+ self.networksetup = DtoNetworkSetup()
22
+
23
+ async def handle_frame(self, frame: FrameBase) -> bool:
24
+ """Handle incoming API frame, return True if this was the expected frame."""
25
+ if not isinstance(frame, FrameGetNetworkSetupConfirmation):
26
+ return False
27
+ self.success = True
28
+ self.networksetup = DtoNetworkSetup(
29
+ frame.ipaddress, frame.gateway, frame.netmask, frame.dhcp)
30
+ return True
31
+
32
+ def request_frame(self) -> FrameGetNetworkSetupRequest:
33
+ """Construct initiating frame."""
34
+ return FrameGetNetworkSetupRequest()
@@ -0,0 +1,42 @@
1
+ """Module for retrieving node information from API."""
2
+ from typing import TYPE_CHECKING, Optional
3
+
4
+ from .api_event import ApiEvent
5
+ from .frames import (
6
+ FrameBase, FrameGetNodeInformationConfirmation,
7
+ FrameGetNodeInformationNotification, FrameGetNodeInformationRequest)
8
+
9
+ if TYPE_CHECKING:
10
+ from pyvlx import PyVLX
11
+
12
+
13
+ class GetNodeInformation(ApiEvent):
14
+ """Class for retrieving node informationfrom API."""
15
+
16
+ def __init__(self, pyvlx: "PyVLX", node_id: int):
17
+ """Initialize SceneList class."""
18
+ super().__init__(pyvlx=pyvlx)
19
+ self.node_id = node_id
20
+ self.success = False
21
+ self.notification_frame: Optional[FrameGetNodeInformationNotification] = None
22
+
23
+ async def handle_frame(self, frame: FrameBase) -> bool:
24
+ """Handle incoming API frame, return True if this was the expected frame."""
25
+ if (
26
+ isinstance(frame, FrameGetNodeInformationConfirmation)
27
+ and frame.node_id == self.node_id
28
+ ):
29
+ # We are still waiting for GetNodeInformationNotification
30
+ return False
31
+ if (
32
+ isinstance(frame, FrameGetNodeInformationNotification)
33
+ and frame.node_id == self.node_id
34
+ ):
35
+ self.notification_frame = frame
36
+ self.success = True
37
+ return True
38
+ return False
39
+
40
+ def request_frame(self) -> FrameGetNodeInformationRequest:
41
+ """Construct initiating frame."""
42
+ return FrameGetNodeInformationRequest(node_id=self.node_id)