diff --git a/libs/lib/xaal/lib/config.py b/libs/lib/xaal/lib/config.py index 9a4cf6f396746f49866314b71ae49806a7319276..0989bc5b396f9244e394e22b10e264ac20345fe1 100644 --- a/libs/lib/xaal/lib/config.py +++ b/libs/lib/xaal/lib/config.py @@ -27,7 +27,7 @@ else: self.conf_dir = os.path.expanduser("~") + '/.xaal' -def load_config(name='xaal.ini'): +def load_config(name: str ='xaal.ini'): filename = os.path.join(self.conf_dir, name) if not os.path.isfile(filename): print("Unable to load xAAL config file [%s]" % filename) diff --git a/libs/lib/xaal/lib/helpers.py b/libs/lib/xaal/lib/helpers.py index d2b4849604cb3f93bc2c381c991363930f47c70a..a03f904a8596a65398a06bb73559b4ead284a099 100644 --- a/libs/lib/xaal/lib/helpers.py +++ b/libs/lib/xaal/lib/helpers.py @@ -7,6 +7,7 @@ import logging import logging.handlers import os import time +from typing import Optional, Any import coloredlogs from decorator import decorator @@ -30,16 +31,16 @@ def timeit(method, *args, **kwargs): logger.debug('%r (%r, %r) %2.6f sec' % (method.__name__, args, kwargs, te-ts)) return result -def set_console_title(value): +def set_console_title(value: str): # set xterm title print("\x1B]0;xAAL => %s\x07" % value, end='\r') -def setup_console_logger(level=config.log_level): +def setup_console_logger(level: str = config.log_level): fmt = '%(asctime)s %(name)-25s %(funcName)-18s %(levelname)-8s %(message)s' #fmt = '[%(name)s] %(funcName)s %(levelname)s: %(message)s' coloredlogs.install(level=level,fmt=fmt) -def setup_file_logger(name,level=config.log_level, filename = None): +def setup_file_logger(name: str,level: str =config.log_level, filename: Optional[str] = None): filename = filename or os.path.join(config.log_path,'%s.log' % name) formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s') handler = logging.handlers.RotatingFileHandler(filename, 'a', 10000, 1, 'utf8') @@ -56,7 +57,7 @@ def setup_file_logger(name,level=config.log_level, filename = None): # # Default arguments console_log and file_log are (and should) never be used. # --------------------------------------------------------------------------- -def run_package(pkg_name, pkg_setup, console_log = True, file_log=False): +def run_package(pkg_name: str, pkg_setup: Any, console_log: bool = True, file_log: bool =False): if console_log: set_console_title(pkg_name) setup_console_logger() diff --git a/libs/lib/xaal/lib/messages.py b/libs/lib/xaal/lib/messages.py index 343e0a0c15d6dc422eaa59dd55c7f9349847f44d..6280144f566429b82a1a45e90aba5763ee3cfb83 100644 --- a/libs/lib/xaal/lib/messages.py +++ b/libs/lib/xaal/lib/messages.py @@ -18,6 +18,7 @@ # along with xAAL. If not, see <http://www.gnu.org/licenses/>. # +from xaal.lib.types import DeviceT from . import tools from . import config from .bindings import UUID @@ -32,12 +33,32 @@ import pysodium import struct import sys +from typing import Any, Optional, TYPE_CHECKING + +if TYPE_CHECKING: + from .devices import Device + + import logging logger = logging.getLogger(__name__) ALIVE_ADDR = UUID("00000000-0000-0000-0000-000000000000") +class MessageType(Enum): + NOTIFY = 0 + REQUEST = 1 + REPLY = 2 + + +class MessageAction(Enum): + ALIVE = "alive" + IS_ALIVE = "is_alive" + ATTRIBUTES_CHANGE = "attributes_change" + GET_ATTRIBUTES = "get_attributes" + GET_DESCRIPTION = "get_description" + + class MessageFactory(object): """Message Factory: - Build xAAL message @@ -47,7 +68,7 @@ class MessageFactory(object): def __init__(self, cipher_key): self.cipher_key = cipher_key # key encode / decode message built from passphrase - def encode_msg(self, msg): + def encode_msg(self, msg: 'Message'): """Apply security layer and return encode MSG in CBOR :param msg: xAAL msg instance :type msg: Message @@ -82,7 +103,7 @@ class MessageFactory(object): pkt = cbor.dumps(result) return pkt - def decode_msg(self, data, filter_func=None): + def decode_msg(self, data: bytes, filter_func: Any =None) -> Optional['Message']: """Decode incoming CBOR data and De-Ciphering :param data: data received from the multicast bus :type data: cbor @@ -160,7 +181,14 @@ class MessageFactory(object): ##################################################### # MSG builder ##################################################### - def build_msg(self, dev=None, targets=[], msg_type=None, action=None, body=None): + def build_msg( + self, + dev: Optional[Device] = None, + targets: list = [], + msg_type: Optional[MessageType] = None, + action: Optional[str] = None, + body: Optional[dict] = None, + ): """the build method takes in parameters : -A device -The list of targets of the message @@ -187,7 +215,7 @@ class MessageFactory(object): data = self.encode_msg(message) return data - def build_alive_for(self, dev, timeout=0): + def build_alive_for(self, dev: Device, timeout: int =0) -> bytes: """Build Alive message for a given device timeout = 0 is the minimum value """ @@ -196,7 +224,7 @@ class MessageFactory(object): message = self.build_msg(dev=dev, targets=[], msg_type=MessageType.NOTIFY, action=MessageAction.ALIVE.value, body=body) return message - def build_error_msg(self, dev, errcode, description=None): + def build_error_msg(self, dev: Device, errcode:int , description: Optional[str] =None): """Build a Error message""" message = Message() body = {} @@ -207,19 +235,6 @@ class MessageFactory(object): return message -class MessageType(Enum): - NOTIFY = 0 - REQUEST = 1 - REPLY = 2 - - -class MessageAction(Enum): - ALIVE = "alive" - IS_ALIVE = "is_alive" - ATTRIBUTES_CHANGE = "attributes_change" - GET_ATTRIBUTES = "get_attributes" - GET_DESCRIPTION = "get_description" - class Message(object): """Message object used for incomming & outgoint message""" @@ -237,11 +252,11 @@ class Message(object): self.body = {} # message body @property - def targets(self): + def targets(self) -> list: return self.__targets @targets.setter - def targets(self, values): + def targets(self, values: list): if not isinstance(values, list): raise MessageError("Expected a list for targetsList, got %s" % (type(values),)) for uid in values: @@ -249,7 +264,7 @@ class Message(object): raise MessageError("Bad target addr: %s" % uid) self.__targets = values - def targets_as_string(self): + def targets_as_string(self) -> list: return [str(k) for k in self.targets] def dump(self): @@ -271,57 +286,57 @@ class Message(object): r.append(["body", tmp]) print(tabulate(r, headers=["Fied", "Value"], tablefmt="psql")) - def __repr__(self): + def __repr__(self) -> str: return f"<xaal.Message {id(self):x} {self.source} {self.dev_type} {self.msg_type} {self.action}>" - def is_request(self): + def is_request(self) -> bool: if MessageType(self.msg_type) == MessageType.REQUEST: return True return False - def is_reply(self): + def is_reply(self) -> bool: if MessageType(self.msg_type) == MessageType.REPLY: return True return False - def is_notify(self): + def is_notify(self) -> bool: if MessageType(self.msg_type) == MessageType.NOTIFY: return True return False - def is_alive(self): + def is_alive(self) -> bool: if self.is_notify() and self.action == MessageAction.ALIVE.value: return True return False - def is_request_isalive(self): + def is_request_isalive(self) -> bool: if self.is_request() and self.action == MessageAction.IS_ALIVE.value: return True return False - def is_attributes_change(self): + def is_attributes_change(self) -> bool: if self.is_notify() and self.action == MessageAction.ATTRIBUTES_CHANGE.value: return True return False - def is_get_attribute_reply(self): + def is_get_attribute_reply(self) -> bool: if self.is_reply() and self.action == MessageAction.GET_ATTRIBUTES.value: return True return False - def is_get_description_reply(self): + def is_get_description_reply(self) -> bool: if self.is_reply() and self.action == MessageAction.GET_DESCRIPTION.value: return True return False -def build_nonce(data): +def build_nonce(data: tuple) -> bytes: """ Big-Endian, time in seconds and time in microseconds """ nonce = struct.pack('>QL', data[0], data[1]) return nonce -def build_timestamp(): +def build_timestamp() -> list: """Return array [seconds since epoch, microseconds since last seconds] Time = UTC+0000""" epoch = datetime.datetime.fromtimestamp(0, datetime.UTC) timestamp = datetime.datetime.now(datetime.UTC) - epoch