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.
- pyvlx/__init__.py +21 -0
- pyvlx/api/__init__.py +23 -0
- pyvlx/api/activate_scene.py +63 -0
- pyvlx/api/api_event.py +73 -0
- pyvlx/api/command_send.py +85 -0
- pyvlx/api/factory_default.py +34 -0
- pyvlx/api/frame_creation.py +202 -0
- pyvlx/api/frames/__init__.py +76 -0
- pyvlx/api/frames/alias_array.py +45 -0
- pyvlx/api/frames/frame.py +56 -0
- pyvlx/api/frames/frame_activate_scene.py +92 -0
- pyvlx/api/frames/frame_activation_log_updated.py +14 -0
- pyvlx/api/frames/frame_command_send.py +280 -0
- pyvlx/api/frames/frame_discover_nodes.py +64 -0
- pyvlx/api/frames/frame_error_notification.py +42 -0
- pyvlx/api/frames/frame_facory_default.py +32 -0
- pyvlx/api/frames/frame_get_all_nodes_information.py +218 -0
- pyvlx/api/frames/frame_get_limitation.py +127 -0
- pyvlx/api/frames/frame_get_local_time.py +38 -0
- pyvlx/api/frames/frame_get_network_setup.py +64 -0
- pyvlx/api/frames/frame_get_node_information.py +223 -0
- pyvlx/api/frames/frame_get_protocol_version.py +53 -0
- pyvlx/api/frames/frame_get_scene_list.py +82 -0
- pyvlx/api/frames/frame_get_state.py +47 -0
- pyvlx/api/frames/frame_get_version.py +72 -0
- pyvlx/api/frames/frame_helper.py +40 -0
- pyvlx/api/frames/frame_house_status_monitor_disable_cfm.py +14 -0
- pyvlx/api/frames/frame_house_status_monitor_disable_req.py +14 -0
- pyvlx/api/frames/frame_house_status_monitor_enable_cfm.py +14 -0
- pyvlx/api/frames/frame_house_status_monitor_enable_req.py +14 -0
- pyvlx/api/frames/frame_leave_learn_state.py +41 -0
- pyvlx/api/frames/frame_node_information_changed.py +57 -0
- pyvlx/api/frames/frame_node_state_position_changed_notification.py +84 -0
- pyvlx/api/frames/frame_password_change.py +114 -0
- pyvlx/api/frames/frame_password_enter.py +70 -0
- pyvlx/api/frames/frame_reboot.py +32 -0
- pyvlx/api/frames/frame_set_node_name.py +73 -0
- pyvlx/api/frames/frame_set_utc.py +45 -0
- pyvlx/api/frames/frame_status_request.py +212 -0
- pyvlx/api/get_all_nodes_information.py +46 -0
- pyvlx/api/get_limitation.py +64 -0
- pyvlx/api/get_local_time.py +34 -0
- pyvlx/api/get_network_setup.py +34 -0
- pyvlx/api/get_node_information.py +42 -0
- pyvlx/api/get_protocol_version.py +40 -0
- pyvlx/api/get_scene_list.py +49 -0
- pyvlx/api/get_state.py +43 -0
- pyvlx/api/get_version.py +34 -0
- pyvlx/api/house_status_monitor.py +52 -0
- pyvlx/api/leave_learn_state.py +33 -0
- pyvlx/api/password_enter.py +39 -0
- pyvlx/api/reboot.py +33 -0
- pyvlx/api/session_id.py +20 -0
- pyvlx/api/set_node_name.py +32 -0
- pyvlx/api/set_utc.py +31 -0
- pyvlx/api/status_request.py +48 -0
- pyvlx/config.py +54 -0
- pyvlx/connection.py +182 -0
- pyvlx/const.py +685 -0
- pyvlx/dataobjects.py +161 -0
- pyvlx/discovery.py +100 -0
- pyvlx/exception.py +26 -0
- pyvlx/heartbeat.py +79 -0
- pyvlx/klf200gateway.py +167 -0
- pyvlx/lightening_device.py +102 -0
- pyvlx/log.py +4 -0
- pyvlx/node.py +74 -0
- pyvlx/node_helper.py +165 -0
- pyvlx/node_updater.py +162 -0
- pyvlx/nodes.py +99 -0
- pyvlx/on_off_switch.py +44 -0
- pyvlx/opening_device.py +644 -0
- pyvlx/parameter.py +357 -0
- pyvlx/py.typed +0 -0
- pyvlx/pyvlx.py +124 -0
- pyvlx/scene.py +53 -0
- pyvlx/scenes.py +60 -0
- pyvlx/slip.py +48 -0
- pyvlx/string_helper.py +20 -0
- pyvlx-0.2.27.dist-info/METADATA +122 -0
- pyvlx-0.2.27.dist-info/RECORD +84 -0
- pyvlx-0.2.27.dist-info/WHEEL +5 -0
- pyvlx-0.2.27.dist-info/licenses/LICENSE +165 -0
- pyvlx-0.2.27.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"""Module for retrieving protocol version from API."""
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from pyvlx.dataobjects import DtoProtocolVersion
|
|
6
|
+
|
|
7
|
+
from .api_event import ApiEvent
|
|
8
|
+
from .frames import (
|
|
9
|
+
FrameBase, FrameGetProtocolVersionConfirmation,
|
|
10
|
+
FrameGetProtocolVersionRequest)
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from pyvlx import PyVLX
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class GetProtocolVersion(ApiEvent):
|
|
17
|
+
"""Class for retrieving protocol version from API."""
|
|
18
|
+
|
|
19
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
20
|
+
"""Initialize GetProtocolVersion class."""
|
|
21
|
+
super().__init__(pyvlx=pyvlx)
|
|
22
|
+
self.success = False
|
|
23
|
+
self.protocolversion = DtoProtocolVersion()
|
|
24
|
+
|
|
25
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
26
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
27
|
+
if not isinstance(frame, FrameGetProtocolVersionConfirmation):
|
|
28
|
+
return False
|
|
29
|
+
self.protocolversion = DtoProtocolVersion(frame.major_version, frame.minor_version)
|
|
30
|
+
self.success = True
|
|
31
|
+
return True
|
|
32
|
+
|
|
33
|
+
def request_frame(self) -> FrameGetProtocolVersionRequest:
|
|
34
|
+
"""Construct initiating frame."""
|
|
35
|
+
return FrameGetProtocolVersionRequest()
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def version(self) -> str:
|
|
39
|
+
"""Return Protocol Version as human readable string."""
|
|
40
|
+
return "{}.{}".format(self.protocolversion.majorversion, self.protocolversion.minorversion)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Module for retrieving scene list from API."""
|
|
2
|
+
from typing import TYPE_CHECKING, List, Optional, Tuple
|
|
3
|
+
|
|
4
|
+
from pyvlx.log import PYVLXLOG
|
|
5
|
+
|
|
6
|
+
from .api_event import ApiEvent
|
|
7
|
+
from .frames import (
|
|
8
|
+
FrameBase, FrameGetSceneListConfirmation, FrameGetSceneListNotification,
|
|
9
|
+
FrameGetSceneListRequest)
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pyvlx import PyVLX
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class GetSceneList(ApiEvent):
|
|
16
|
+
"""Class for retrieving scene list from API."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
19
|
+
"""Initialize SceneList class."""
|
|
20
|
+
super().__init__(pyvlx=pyvlx)
|
|
21
|
+
self.success = False
|
|
22
|
+
self.count_scenes: Optional[int] = None
|
|
23
|
+
self.scenes: List[Tuple[int, str]] = []
|
|
24
|
+
|
|
25
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
26
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
27
|
+
if isinstance(frame, FrameGetSceneListConfirmation):
|
|
28
|
+
self.count_scenes = frame.count_scenes
|
|
29
|
+
if self.count_scenes == 0:
|
|
30
|
+
self.success = True
|
|
31
|
+
return True
|
|
32
|
+
# We are still waiting for FrameGetSceneListNotification(s)
|
|
33
|
+
return False
|
|
34
|
+
if isinstance(frame, FrameGetSceneListNotification):
|
|
35
|
+
self.scenes.extend(frame.scenes)
|
|
36
|
+
if frame.remaining_scenes != 0:
|
|
37
|
+
# We are still waiting for FrameGetSceneListConfirmation(s)
|
|
38
|
+
return False
|
|
39
|
+
if self.count_scenes != len(self.scenes):
|
|
40
|
+
PYVLXLOG.warning(
|
|
41
|
+
"Warning: number of received scenes does not match expected number"
|
|
42
|
+
)
|
|
43
|
+
self.success = True
|
|
44
|
+
return True
|
|
45
|
+
return False
|
|
46
|
+
|
|
47
|
+
def request_frame(self) -> FrameGetSceneListRequest:
|
|
48
|
+
"""Construct initiating frame."""
|
|
49
|
+
return FrameGetSceneListRequest()
|
pyvlx/api/get_state.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Module for retrieving gateway state from API."""
|
|
2
|
+
from typing import TYPE_CHECKING, Optional
|
|
3
|
+
|
|
4
|
+
from pyvlx.const import GatewayState, GatewaySubState
|
|
5
|
+
from pyvlx.dataobjects import DtoState
|
|
6
|
+
|
|
7
|
+
from .api_event import ApiEvent
|
|
8
|
+
from .frames import FrameBase, FrameGetStateConfirmation, FrameGetStateRequest
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyvlx import PyVLX
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GetState(ApiEvent):
|
|
15
|
+
"""Class for retrieving gateway state from API."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
18
|
+
"""Initialize GetState class."""
|
|
19
|
+
super().__init__(pyvlx=pyvlx)
|
|
20
|
+
self.success = False
|
|
21
|
+
self.state = DtoState()
|
|
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, FrameGetStateConfirmation):
|
|
26
|
+
return False
|
|
27
|
+
self.success = True
|
|
28
|
+
self.state = DtoState(frame.gateway_state, frame.gateway_sub_state)
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
def request_frame(self) -> FrameGetStateRequest:
|
|
32
|
+
"""Construct initiating frame."""
|
|
33
|
+
return FrameGetStateRequest()
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def gateway_state(self) -> Optional[GatewayState]:
|
|
37
|
+
"""Return Gateway State as human readable string. Deprecated."""
|
|
38
|
+
return self.state.gateway_state
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def gateway_sub_state(self) -> Optional[GatewaySubState]:
|
|
42
|
+
"""Return Gateway Sub State as human readable string. Deprecated."""
|
|
43
|
+
return self.state.gateway_sub_state
|
pyvlx/api/get_version.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Module for retrieving firmware version from API."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from pyvlx.dataobjects import DtoVersion
|
|
5
|
+
|
|
6
|
+
from .api_event import ApiEvent
|
|
7
|
+
from .frames import (
|
|
8
|
+
FrameBase, FrameGetVersionConfirmation, FrameGetVersionRequest)
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyvlx import PyVLX
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class GetVersion(ApiEvent):
|
|
15
|
+
"""Class for retrieving firmware version from API."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
18
|
+
"""Initialize GetVersion class."""
|
|
19
|
+
super().__init__(pyvlx=pyvlx)
|
|
20
|
+
self.success = False
|
|
21
|
+
self.version = DtoVersion()
|
|
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, FrameGetVersionConfirmation):
|
|
26
|
+
return False
|
|
27
|
+
self.version = DtoVersion(frame.software_version, frame.hardware_version,
|
|
28
|
+
frame.product_group, frame.product_type)
|
|
29
|
+
self.success = True
|
|
30
|
+
return True
|
|
31
|
+
|
|
32
|
+
def request_frame(self) -> FrameGetVersionRequest:
|
|
33
|
+
"""Construct initiating frame."""
|
|
34
|
+
return FrameGetVersionRequest()
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"""Module for house status monitor."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from .api_event import ApiEvent
|
|
5
|
+
from .frames import (
|
|
6
|
+
FrameBase, FrameHouseStatusMonitorDisableConfirmation,
|
|
7
|
+
FrameHouseStatusMonitorDisableRequest,
|
|
8
|
+
FrameHouseStatusMonitorEnableConfirmation,
|
|
9
|
+
FrameHouseStatusMonitorEnableRequest)
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pyvlx import PyVLX
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class HouseStatusMonitorEnable(ApiEvent):
|
|
16
|
+
"""Class for enabling house status monotor."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
19
|
+
"""Initialize HouseStatusMonitorEnable class."""
|
|
20
|
+
super().__init__(pyvlx=pyvlx)
|
|
21
|
+
self.success = False
|
|
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, FrameHouseStatusMonitorEnableConfirmation):
|
|
26
|
+
return False
|
|
27
|
+
self.success = True
|
|
28
|
+
return True
|
|
29
|
+
|
|
30
|
+
def request_frame(self) -> FrameHouseStatusMonitorEnableRequest:
|
|
31
|
+
"""Construct initiating frame."""
|
|
32
|
+
return FrameHouseStatusMonitorEnableRequest()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class HouseStatusMonitorDisable(ApiEvent):
|
|
36
|
+
"""Class for disabling house status monotor."""
|
|
37
|
+
|
|
38
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
39
|
+
"""Initialize HouseStatusMonitorEnable class."""
|
|
40
|
+
super().__init__(pyvlx=pyvlx)
|
|
41
|
+
self.success = False
|
|
42
|
+
|
|
43
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
44
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
45
|
+
if not isinstance(frame, FrameHouseStatusMonitorDisableConfirmation):
|
|
46
|
+
return False
|
|
47
|
+
self.success = True
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
def request_frame(self) -> FrameHouseStatusMonitorDisableRequest:
|
|
51
|
+
"""Construct initiating frame."""
|
|
52
|
+
return FrameHouseStatusMonitorDisableRequest()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Module for handling the login to API."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from pyvlx.dataobjects import DtoLeaveLearnState
|
|
5
|
+
|
|
6
|
+
from .api_event import ApiEvent
|
|
7
|
+
from .frames import (
|
|
8
|
+
FrameBase, FrameLeaveLearnStateConfirmation, FrameLeaveLearnStateRequest)
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyvlx import PyVLX
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class LeaveLearnState(ApiEvent):
|
|
15
|
+
"""Class for handling leave learn state to API."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
18
|
+
"""Initialize leave learn state class."""
|
|
19
|
+
super().__init__(pyvlx=pyvlx)
|
|
20
|
+
self.status = DtoLeaveLearnState()
|
|
21
|
+
self.success = False
|
|
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, FrameLeaveLearnStateConfirmation):
|
|
26
|
+
return False
|
|
27
|
+
self.status.status = frame.status
|
|
28
|
+
self.success = True
|
|
29
|
+
return True
|
|
30
|
+
|
|
31
|
+
def request_frame(self) -> FrameLeaveLearnStateRequest:
|
|
32
|
+
"""Construct initiating frame."""
|
|
33
|
+
return FrameLeaveLearnStateRequest()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Module for handling the login to API."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from pyvlx.log import PYVLXLOG
|
|
5
|
+
|
|
6
|
+
from .api_event import ApiEvent
|
|
7
|
+
from .frames import (
|
|
8
|
+
FrameBase, FramePasswordEnterConfirmation, FramePasswordEnterRequest,
|
|
9
|
+
PasswordEnterConfirmationStatus)
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from pyvlx import PyVLX
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class PasswordEnter(ApiEvent):
|
|
16
|
+
"""Class for handling login to API."""
|
|
17
|
+
|
|
18
|
+
def __init__(self, pyvlx: "PyVLX", password: str):
|
|
19
|
+
"""Initialize login class."""
|
|
20
|
+
super().__init__(pyvlx=pyvlx)
|
|
21
|
+
self.password = password
|
|
22
|
+
self.success = False
|
|
23
|
+
|
|
24
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
25
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
26
|
+
if not isinstance(frame, FramePasswordEnterConfirmation):
|
|
27
|
+
return False
|
|
28
|
+
if frame.status == PasswordEnterConfirmationStatus.FAILED:
|
|
29
|
+
PYVLXLOG.warning(
|
|
30
|
+
'Failed to authenticate with password "%s****"', self.password[:2]
|
|
31
|
+
)
|
|
32
|
+
self.success = False
|
|
33
|
+
if frame.status == PasswordEnterConfirmationStatus.SUCCESSFUL:
|
|
34
|
+
self.success = True
|
|
35
|
+
return True
|
|
36
|
+
|
|
37
|
+
def request_frame(self) -> FramePasswordEnterRequest:
|
|
38
|
+
"""Construct initiating frame."""
|
|
39
|
+
return FramePasswordEnterRequest(password=self.password)
|
pyvlx/api/reboot.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Module for handling the Reboot to API."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from pyvlx.log import PYVLXLOG
|
|
5
|
+
|
|
6
|
+
from .api_event import ApiEvent
|
|
7
|
+
from .frames import (
|
|
8
|
+
FrameBase, FrameGatewayRebootConfirmation, FrameGatewayRebootRequest)
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyvlx import PyVLX
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Reboot(ApiEvent):
|
|
15
|
+
"""Class for handling Reboot to API."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, pyvlx: "PyVLX"):
|
|
18
|
+
"""Initialize Reboot class."""
|
|
19
|
+
super().__init__(pyvlx=pyvlx)
|
|
20
|
+
self.pyvlx = pyvlx
|
|
21
|
+
self.success = False
|
|
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 isinstance(frame, FrameGatewayRebootConfirmation):
|
|
26
|
+
PYVLXLOG.warning("KLF200 is rebooting")
|
|
27
|
+
self.success = True
|
|
28
|
+
return True
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
def request_frame(self) -> FrameGatewayRebootRequest:
|
|
32
|
+
"""Construct initiating frame."""
|
|
33
|
+
return FrameGatewayRebootRequest()
|
pyvlx/api/session_id.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""Module for generating a unique session_id."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
_last_session_id = 0
|
|
5
|
+
MAX_SESSION_ID = 65535
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_new_session_id() -> int:
|
|
9
|
+
"""Generate new session_id."""
|
|
10
|
+
global _last_session_id # pylint: disable=global-statement
|
|
11
|
+
_last_session_id = _last_session_id + 1
|
|
12
|
+
if _last_session_id > MAX_SESSION_ID:
|
|
13
|
+
_last_session_id = 1
|
|
14
|
+
return _last_session_id
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def set_session_id(session_id: int) -> None:
|
|
18
|
+
"""Set session id to value."""
|
|
19
|
+
global _last_session_id # pylint: disable=global-statement
|
|
20
|
+
_last_session_id = session_id
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"""Module for changing a node name."""
|
|
2
|
+
from typing import TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from .api_event import ApiEvent
|
|
5
|
+
from .frames import (
|
|
6
|
+
FrameBase, FrameSetNodeNameConfirmation, FrameSetNodeNameRequest,
|
|
7
|
+
SetNodeNameConfirmationStatus)
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from pyvlx import PyVLX
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SetNodeName(ApiEvent):
|
|
14
|
+
"""Class for changing the name of a node via API."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, pyvlx: "PyVLX", node_id: int, name: str):
|
|
17
|
+
"""Initialize class."""
|
|
18
|
+
super().__init__(pyvlx=pyvlx)
|
|
19
|
+
self.node_id = node_id
|
|
20
|
+
self.name = name
|
|
21
|
+
self.success = False
|
|
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, FrameSetNodeNameConfirmation):
|
|
26
|
+
return False
|
|
27
|
+
self.success = frame.status == SetNodeNameConfirmationStatus.OK
|
|
28
|
+
return True
|
|
29
|
+
|
|
30
|
+
def request_frame(self) -> FrameSetNodeNameRequest:
|
|
31
|
+
"""Construct initiating frame."""
|
|
32
|
+
return FrameSetNodeNameRequest(node_id=self.node_id, name=self.name)
|
pyvlx/api/set_utc.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Module for setting UTC time within gateway."""
|
|
2
|
+
import time
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from .api_event import ApiEvent
|
|
6
|
+
from .frames import FrameBase, FrameSetUTCConfirmation, FrameSetUTCRequest
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from pyvlx import PyVLX
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SetUTC(ApiEvent):
|
|
13
|
+
"""Class for setting UTC time within gateway."""
|
|
14
|
+
|
|
15
|
+
def __init__(self, pyvlx: "PyVLX", timestamp: float = time.time()):
|
|
16
|
+
"""Initialize SetUTC class."""
|
|
17
|
+
super().__init__(pyvlx=pyvlx)
|
|
18
|
+
self.timestamp = timestamp
|
|
19
|
+
self.success = False
|
|
20
|
+
|
|
21
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
22
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
23
|
+
if not isinstance(frame, FrameSetUTCConfirmation):
|
|
24
|
+
return False
|
|
25
|
+
self.success = True
|
|
26
|
+
return True
|
|
27
|
+
|
|
28
|
+
def request_frame(self) -> FrameSetUTCRequest:
|
|
29
|
+
"""Construct initiating frame."""
|
|
30
|
+
timestamp = int(self.timestamp)
|
|
31
|
+
return FrameSetUTCRequest(timestamp=timestamp)
|
|
@@ -0,0 +1,48 @@
|
|
|
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, FrameStatusRequestConfirmation, FrameStatusRequestNotification,
|
|
7
|
+
FrameStatusRequestRequest)
|
|
8
|
+
from .session_id import get_new_session_id
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from pyvlx import PyVLX
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class StatusRequest(ApiEvent):
|
|
15
|
+
"""Class for retrieving node informationfrom API."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, pyvlx: "PyVLX", node_id: int):
|
|
18
|
+
"""Initialize SceneList class."""
|
|
19
|
+
super().__init__(pyvlx=pyvlx)
|
|
20
|
+
self.node_id = node_id
|
|
21
|
+
self.success = False
|
|
22
|
+
self.notification_frame: Optional[FrameStatusRequestNotification] = None
|
|
23
|
+
self.session_id: Optional[int] = None
|
|
24
|
+
|
|
25
|
+
async def handle_frame(self, frame: FrameBase) -> bool:
|
|
26
|
+
"""Handle incoming API frame, return True if this was the expected frame."""
|
|
27
|
+
if (
|
|
28
|
+
isinstance(frame, FrameStatusRequestConfirmation)
|
|
29
|
+
and frame.session_id == self.session_id
|
|
30
|
+
):
|
|
31
|
+
# We are still waiting for StatusRequestNotification
|
|
32
|
+
return False
|
|
33
|
+
if (
|
|
34
|
+
isinstance(frame, FrameStatusRequestNotification)
|
|
35
|
+
and frame.session_id == self.session_id
|
|
36
|
+
):
|
|
37
|
+
self.notification_frame = frame
|
|
38
|
+
self.success = True
|
|
39
|
+
return True
|
|
40
|
+
return False
|
|
41
|
+
|
|
42
|
+
def request_frame(self) -> FrameStatusRequestRequest:
|
|
43
|
+
"""Construct initiating frame."""
|
|
44
|
+
self.session_id = get_new_session_id()
|
|
45
|
+
return FrameStatusRequestRequest(
|
|
46
|
+
session_id=self.session_id,
|
|
47
|
+
node_ids=[self.node_id]
|
|
48
|
+
)
|
pyvlx/config.py
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Module for configuration."""
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
3
|
+
|
|
4
|
+
import yaml
|
|
5
|
+
|
|
6
|
+
from .exception import PyVLXException
|
|
7
|
+
from .log import PYVLXLOG
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from pyvlx import PyVLX
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Config:
|
|
14
|
+
"""Object for configuration."""
|
|
15
|
+
|
|
16
|
+
DEFAULT_PORT = 51200
|
|
17
|
+
|
|
18
|
+
def __init__(self,
|
|
19
|
+
pyvlx: "PyVLX",
|
|
20
|
+
path: Optional[str] = None,
|
|
21
|
+
host: Optional[str] = None,
|
|
22
|
+
password: Optional[str] = None,
|
|
23
|
+
port: Optional[int] = None):
|
|
24
|
+
"""Initialize Config class."""
|
|
25
|
+
self.pyvlx = pyvlx
|
|
26
|
+
self.host = host
|
|
27
|
+
self.password = password
|
|
28
|
+
self.port = port or self.DEFAULT_PORT
|
|
29
|
+
if path is not None:
|
|
30
|
+
self.read_config(path)
|
|
31
|
+
|
|
32
|
+
def read_config(self, path: str) -> None:
|
|
33
|
+
"""Read configuration file."""
|
|
34
|
+
PYVLXLOG.info("Reading config file: %s", path)
|
|
35
|
+
try:
|
|
36
|
+
with open(path, "r", encoding="utf-8") as filehandle:
|
|
37
|
+
doc = yaml.safe_load(filehandle)
|
|
38
|
+
self.test_configuration(doc, path)
|
|
39
|
+
self.host = cast(str, doc["config"]["host"])
|
|
40
|
+
self.password = cast(str, doc["config"]["password"])
|
|
41
|
+
if "port" in doc["config"]:
|
|
42
|
+
self.port = doc["config"]["port"]
|
|
43
|
+
except FileNotFoundError as not_found:
|
|
44
|
+
raise PyVLXException("file does not exist: {0}".format(not_found)) from not_found
|
|
45
|
+
|
|
46
|
+
@staticmethod
|
|
47
|
+
def test_configuration(doc: Any, path: str) -> None:
|
|
48
|
+
"""Test if configuration file is sane."""
|
|
49
|
+
if "config" not in doc:
|
|
50
|
+
raise PyVLXException("no element config found in: {0}".format(path))
|
|
51
|
+
if "host" not in doc["config"]:
|
|
52
|
+
raise PyVLXException("no element host found in: {0}".format(path))
|
|
53
|
+
if "password" not in doc["config"]:
|
|
54
|
+
raise PyVLXException("no element password found in: {0}".format(path))
|