Skip to content

Commit

Permalink
Merge pull request #2 from Julius2342/master
Browse files Browse the repository at this point in the history
update
  • Loading branch information
pawlizio committed Jun 26, 2020
2 parents 161379e + 790ee7a commit 71bc9cf
Show file tree
Hide file tree
Showing 106 changed files with 1,624 additions and 878 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
reports=no

[MESSAGES CONTROL]
disable=C0111,duplicate-code,fixme,locally-disabled,too-few-public-methods,too-many-arguments,too-many-instance-attributes
disable=C0111,bad-continuation,duplicate-code,fixme,locally-disabled,too-few-public-methods,too-many-arguments,too-many-instance-attributes

[REPORTS]
output-format=colorized
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ pypi:
@twine upload dist/*

pylint:
@pylint -j 8 --rcfile=.pylintrc pyvlx test/*.py *.py examples/*.py
@pylint --rcfile=.pylintrc pyvlx test/*.py *.py examples/*.py

pydocstyle:
@pydocstyle pyvlx test/*.py test/*.py *.py examples/*.py
Expand Down
3 changes: 1 addition & 2 deletions examples/monitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
import asyncio
import logging

from pyvlx import PyVLX
from pyvlx.log import PYVLXLOG
from pyvlx import PyVLX, PYVLXLOG


async def main(loop):
Expand Down
26 changes: 22 additions & 4 deletions pyvlx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,30 @@
from .lightening_device import Light, LighteningDevice
from .nodes import Nodes
from .opening_device import (
Blade, Blind, GarageDoor, Gate, OpeningDevice, RollerShutter, Window, Awning)
Awning,
Blade,
Blind,
GarageDoor,
Gate,
OpeningDevice,
RollerShutter,
Window,
)
from .parameter import (
CurrentIntensity, CurrentPosition, Intensity, Parameter, Position,
SwitchParameter, SwitchParameterOff, SwitchParameterOn, UnknownIntensity,
UnknownPosition)
CurrentIntensity,
CurrentPosition,
Intensity,
Parameter,
Position,
SwitchParameter,
SwitchParameterOff,
SwitchParameterOn,
UnknownIntensity,
UnknownPosition,
)

# flake8: noqa
from .pyvlx import PyVLX
from .log import PYVLXLOG
from .scene import Scene
from .scenes import Scenes
38 changes: 29 additions & 9 deletions pyvlx/activate_scene.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
"""Module for retrieving scene list from API."""
from .api_event import ApiEvent
from .frames import (
ActivateSceneConfirmationStatus, FrameActivateSceneConfirmation,
FrameActivateSceneRequest, FrameCommandRemainingTimeNotification,
FrameCommandRunStatusNotification, FrameSessionFinishedNotification)
ActivateSceneConfirmationStatus,
FrameActivateSceneConfirmation,
FrameActivateSceneRequest,
FrameCommandRemainingTimeNotification,
FrameCommandRunStatusNotification,
FrameSessionFinishedNotification,
)
from .session_id import get_new_session_id


class ActivateScene(ApiEvent):
"""Class for activating scene via API."""

def __init__(self, pyvlx, scene_id, wait_for_completion=True, timeout_in_seconds=60):
def __init__(
self, pyvlx, scene_id, wait_for_completion=True, timeout_in_seconds=60
):
"""Initialize SceneList class."""
super().__init__(pyvlx=pyvlx, timeout_in_seconds=timeout_in_seconds)
self.success = False
Expand All @@ -20,22 +26,36 @@ def __init__(self, pyvlx, scene_id, wait_for_completion=True, timeout_in_seconds

async def handle_frame(self, frame):
"""Handle incoming API frame, return True if this was the expected frame."""
if isinstance(frame, FrameActivateSceneConfirmation) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameActivateSceneConfirmation)
and frame.session_id == self.session_id
):
if frame.status == ActivateSceneConfirmationStatus.ACCEPTED:
self.success = True
return not self.wait_for_completion
if isinstance(frame, FrameCommandRemainingTimeNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameCommandRemainingTimeNotification)
and frame.session_id == self.session_id
):
# Ignoring FrameCommandRemainingTimeNotification
return False
if isinstance(frame, FrameCommandRunStatusNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameCommandRunStatusNotification)
and frame.session_id == self.session_id
):
# At the moment I don't reall understand what the FrameCommandRunStatusNotification is good for.
# Ignoring these packets for now
return False
if isinstance(frame, FrameSessionFinishedNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameSessionFinishedNotification)
and frame.session_id == self.session_id
):
return True
return False

def request_frame(self):
"""Construct initiating frame."""
self.session_id = get_new_session_id()
return FrameActivateSceneRequest(scene_id=self.scene_id, session_id=self.session_id)
return FrameActivateSceneRequest(
scene_id=self.scene_id, session_id=self.session_id
)
17 changes: 12 additions & 5 deletions pyvlx/alias_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from .exception import PyVLXException


class AliasArray():
class AliasArray:
"""Object for storing alias array."""

def __init__(self, raw=None):
Expand All @@ -13,14 +13,17 @@ def __init__(self, raw=None):

def __str__(self):
"""Return human readable string."""
return ", ".join("{:02x}{:02x}={:02x}{:02x}".format(c[0][0], c[0][1], c[1][0], c[1][1]) for c in self.alias_array_)
return ", ".join(
"{:02x}{:02x}={:02x}{:02x}".format(c[0][0], c[0][1], c[1][0], c[1][1])
for c in self.alias_array_
)

def __bytes__(self):
"""Get raw bytes of alias array."""
ret = bytes([len(self.alias_array_)])
for alias in self.alias_array_:
ret += alias[0] + alias[1]
ret += bytes((5-len(self.alias_array_))*4)
ret += bytes((5 - len(self.alias_array_)) * 4)
return ret

def parse_raw(self, raw):
Expand All @@ -31,6 +34,10 @@ def parse_raw(self, raw):
raise PyVLXException("AliasArray::invalid_size", size=len(raw))
nbr_of_alias = raw[0]
if nbr_of_alias > 5:
raise PyVLXException("AliasArray::invalid_nbr_of_alias", nbr_of_alias=nbr_of_alias)
raise PyVLXException(
"AliasArray::invalid_nbr_of_alias", nbr_of_alias=nbr_of_alias
)
for i in range(0, nbr_of_alias):
self.alias_array_.append((raw[i*4+1:i*4+3], raw[i*4+3:i*4+5]))
self.alias_array_.append(
(raw[i*4+1:i*4+3], raw[i*4+3:i*4+5])
)
12 changes: 6 additions & 6 deletions pyvlx/api_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import asyncio


class ApiEvent():
class ApiEvent:
"""Base class for waiting a specific frame from API connection."""

def __init__(self, pyvlx, timeout_in_seconds=10):
Expand All @@ -17,8 +17,7 @@ def __init__(self, pyvlx, timeout_in_seconds=10):

async def do_api_call(self):
"""Start. Sending and waiting for answer."""
self.pyvlx.connection.register_frame_received_cb(
self.response_rec_callback)
self.pyvlx.connection.register_frame_received_cb(self.response_rec_callback)
await self.send_frame()
await self.start_timeout()
await self.response_received_or_timeout.wait()
Expand All @@ -27,15 +26,15 @@ async def do_api_call(self):

async def handle_frame(self, frame):
"""Handle incoming API frame, return True if this was the expected frame."""
raise NotImplementedError('handle_frame has to be implemented')
raise NotImplementedError("handle_frame has to be implemented")

async def send_frame(self):
"""Send frame to API connection."""
await self.pyvlx.send_frame(self.request_frame())

def request_frame(self):
"""Construct initiating framw."""
raise NotImplementedError('send_frame has to be implemented')
raise NotImplementedError("send_frame has to be implemented")

async def response_rec_callback(self, frame):
"""Handle frame. Callback from internal api connection."""
Expand All @@ -49,7 +48,8 @@ def timeout(self):
async def start_timeout(self):
"""Start timeout."""
self.timeout_handle = self.pyvlx.connection.loop.call_later(
self.timeout_in_seconds, self.timeout)
self.timeout_in_seconds, self.timeout
)

async def stop_timeout(self):
"""Stop timeout."""
Expand Down
50 changes: 34 additions & 16 deletions pyvlx/command_send.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
"""Module for retrieving scene list from API."""
from pyvlx.api_event import ApiEvent
from pyvlx.frames import (
CommandSendConfirmationStatus, FrameCommandRemainingTimeNotification,
FrameCommandRunStatusNotification, FrameCommandSendConfirmation,
FrameCommandSendRequest, FrameSessionFinishedNotification)
CommandSendConfirmationStatus,
FrameCommandRemainingTimeNotification,
FrameCommandRunStatusNotification,
FrameCommandSendConfirmation,
FrameCommandSendRequest,
FrameSessionFinishedNotification,
)
from pyvlx.session_id import get_new_session_id


class CommandSend(ApiEvent):
"""Class for sending command to API."""

def __init__(
self,
pyvlx,
node_id,
parameter,
active_parameter=0,
wait_for_completion=True,
timeout_in_seconds=60,
**functional_parameter):
self,
pyvlx,
node_id,
parameter,
active_parameter=0,
wait_for_completion=True,
timeout_in_seconds=60,
**functional_parameter
):
"""Initialize SceneList class."""
super().__init__(pyvlx=pyvlx, timeout_in_seconds=timeout_in_seconds)
self.success = False
Expand All @@ -31,18 +36,30 @@ def __init__(

async def handle_frame(self, frame):
"""Handle incoming API frame, return True if this was the expected frame."""
if isinstance(frame, FrameCommandSendConfirmation) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameCommandSendConfirmation)
and frame.session_id == self.session_id
):
if frame.status == CommandSendConfirmationStatus.ACCEPTED:
self.success = True
return not self.wait_for_completion
if isinstance(frame, FrameCommandRemainingTimeNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameCommandRemainingTimeNotification)
and frame.session_id == self.session_id
):
# Ignoring FrameCommandRemainingTimeNotification
return False
if isinstance(frame, FrameCommandRunStatusNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameCommandRunStatusNotification)
and frame.session_id == self.session_id
):
# At the moment I don't reall understand what the FrameCommandRunStatusNotification is good for.
# Ignoring these packets for now
return False
if isinstance(frame, FrameSessionFinishedNotification) and frame.session_id == self.session_id:
if (
isinstance(frame, FrameSessionFinishedNotification)
and frame.session_id == self.session_id
):
return True
return False

Expand All @@ -54,4 +71,5 @@ def request_frame(self):
parameter=self.parameter,
active_parameter=self.active_parameter,
session_id=self.session_id,
**self.functional_parameter)
**self.functional_parameter
)
26 changes: 13 additions & 13 deletions pyvlx/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,24 +21,24 @@ def __init__(self, pyvlx, path=None, host=None, password=None, port=None):

def read_config(self, path):
"""Read configuration file."""
PYVLXLOG.info('Reading config file: %s', path)
PYVLXLOG.info("Reading config file: %s", path)
try:
with open(path, 'r') as filehandle:
with open(path, "r") as filehandle:
doc = yaml.safe_load(filehandle)
self.test_configuration(doc, path)
self.host = doc['config']['host']
self.password = doc['config']['password']
if 'port' in doc['config']:
self.port = doc['config']['port']
self.host = doc["config"]["host"]
self.password = doc["config"]["password"]
if "port" in doc["config"]:
self.port = doc["config"]["port"]
except FileNotFoundError as ex:
raise PyVLXException('file does not exist: {0}'.format(ex))
raise PyVLXException("file does not exist: {0}".format(ex))

@staticmethod
def test_configuration(doc, path):
"""Test if configuration file is sane."""
if 'config' not in doc:
raise PyVLXException('no element config found in: {0}'.format(path))
if 'host' not in doc['config']:
raise PyVLXException('no element host found in: {0}'.format(path))
if 'password' not in doc['config']:
raise PyVLXException('no element password found in: {0}'.format(path))
if "config" not in doc:
raise PyVLXException("no element config found in: {0}".format(path))
if "host" not in doc["config"]:
raise PyVLXException("no element host found in: {0}".format(path))
if "password" not in doc["config"]:
raise PyVLXException("no element password found in: {0}".format(path))
3 changes: 2 additions & 1 deletion pyvlx/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ async def connect(self):
lambda: tcp_client,
host=self.config.host,
port=self.config.port,
ssl=self.create_ssl_context())
ssl=self.create_ssl_context(),
)
self.connected = True

def register_frame_received_cb(self, callback):
Expand Down
12 changes: 9 additions & 3 deletions pyvlx/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ def __init__(self, description, **kwargs):
self.parameter = kwargs

def _format_parameter(self):
return " ".join(['%s="%s"' % (key, value) for (key, value) in sorted(self.parameter.items())])
return " ".join(
[
'%s="%s"' % (key, value)
for (key, value) in sorted(self.parameter.items())
]
)

def __str__(self):
"""Return object as readable string."""
return '<PyVLXException description="{0}" {1}/>' \
.format(self.description, self._format_parameter())
return '<PyVLXException description="{0}" {1}/>'.format(
self.description, self._format_parameter()
)
Loading

0 comments on commit 71bc9cf

Please sign in to comment.