From 0c1d8b6efe3481cb165ddabd32ca34c058708c79 Mon Sep 17 00:00:00 2001 From: Bas Nijholt Date: Mon, 11 Nov 2019 19:39:43 +0100 Subject: [PATCH] implement SyncSmartDevice and sort imports and use absolute imports --- pyHS100/cli.py | 15 ++++++--------- pyHS100/discover.py | 19 ++++++++----------- pyHS100/protocol.py | 2 +- pyHS100/smartbulb.py | 4 ++-- pyHS100/smartdevice.py | 31 ++++++++++++++++++++++++++++++- pyHS100/smartplug.py | 8 ++++++-- pyHS100/smartstrip.py | 6 +++--- 7 files changed, 56 insertions(+), 29 deletions(-) diff --git a/pyHS100/cli.py b/pyHS100/cli.py index cc40eda1..20979153 100755 --- a/pyHS100/cli.py +++ b/pyHS100/cli.py @@ -1,21 +1,18 @@ """pyHS100 cli tool.""" import asyncio -import sys -import click import logging +import sys from pprint import pformat as pf +import click + if sys.version_info < (3, 4): print("To use this script you need python 3.4 or newer! got %s" % sys.version_info) sys.exit(1) -from pyHS100 import ( - SmartDevice, - SmartPlug, - SmartBulb, - SmartStrip, - Discover, -) # noqa: E402 +from pyHS100 import SmartPlug # noqa: E402 +from pyHS100 import Discover, SmartBulb, SmartDevice, SmartStrip + pass_dev = click.make_pass_decorator(SmartDevice) diff --git a/pyHS100/discover.py b/pyHS100/discover.py index c0ca6bb7..bf42926c 100755 --- a/pyHS100/discover.py +++ b/pyHS100/discover.py @@ -1,16 +1,13 @@ -import socket -import logging import json -from typing import Dict, Type, Optional +import logging +import socket +from typing import Dict, Optional, Type -from pyHS100 import ( - TPLinkSmartHomeProtocol, - SmartDevice, - SmartPlug, - SmartBulb, - SmartStrip, - SmartDeviceException, -) +from pyHS100.protocol import TPLinkSmartHomeProtocol +from pyHS100.smartbulb import SmartBulb +from pyHS100.smartdevice import SmartDevice, SmartDeviceException +from pyHS100.smartplug import SmartPlug +from pyHS100.smartstrip import SmartStrip _LOGGER = logging.getLogger(__name__) diff --git a/pyHS100/protocol.py b/pyHS100/protocol.py index 8bf945c4..b2df8e04 100755 --- a/pyHS100/protocol.py +++ b/pyHS100/protocol.py @@ -1,7 +1,7 @@ import asyncio import json -import struct import logging +import struct from typing import Any, Dict, Union _LOGGER = logging.getLogger(__name__) diff --git a/pyHS100/smartbulb.py b/pyHS100/smartbulb.py index 719b1f11..69edd8b4 100644 --- a/pyHS100/smartbulb.py +++ b/pyHS100/smartbulb.py @@ -1,8 +1,8 @@ -from pyHS100 import DeviceType, SmartDevice, SmartDeviceException -from .protocol import TPLinkSmartHomeProtocol import re from typing import Any, Dict, Tuple +from pyHS100.protocol import TPLinkSmartHomeProtocol +from pyHS100.smartdevice import DeviceType, SmartDevice, SmartDeviceException TPLINK_KELVIN = { "LB130": (2500, 9000), diff --git a/pyHS100/smartdevice.py b/pyHS100/smartdevice.py index 389681d1..76589100 100755 --- a/pyHS100/smartdevice.py +++ b/pyHS100/smartdevice.py @@ -14,13 +14,15 @@ You may obtain a copy of the license at http://www.apache.org/licenses/LICENSE-2.0 """ import asyncio +import inspect +import functools import logging from collections import defaultdict from datetime import datetime, timedelta from enum import Enum from typing import Any, Dict, Optional -from .protocol import TPLinkSmartHomeProtocol +from pyHS100.protocol import TPLinkSmartHomeProtocol _LOGGER = logging.getLogger(__name__) @@ -116,6 +118,7 @@ class SmartDevice: self.cache = defaultdict(lambda: defaultdict(lambda: None)) self._device_type = DeviceType.Unknown self.ioloop = ioloop or asyncio.get_event_loop() + self.sync = SyncSmartDevice(self) def _result_from_cache(self, target, cmd) -> Optional[Dict]: """Return query result from cache if still fresh. @@ -604,3 +607,29 @@ class SmartDevice: asyncio.run(self.is_on()), asyncio.run(self.get_state_information()), ) + + +class SyncSmartDevice: + """A synchronous SmartDevice speaker class. + This has the same methods as `SyncSmartDevice`, however, it wraps all async + methods and call them in a blocking way. + + Taken from https://github.com/basnijholt/media_player.kef/ + """ + + def __init__(self, async_device): + self.async_device = async_device + + def __getattr__(self, attr): + method = getattr(self.async_device, attr) + if method is None: + raise AttributeError(f"'SyncSmartDevice' object has no attribute '{attr}.'") + if inspect.iscoroutinefunction(method): + + @functools.wraps(method) + def wrapped(*args, **kwargs): + return asyncio.run(method(*args, **kwargs)) + + return wrapped + else: + return method diff --git a/pyHS100/smartplug.py b/pyHS100/smartplug.py index f983ed2c..1a172b24 100644 --- a/pyHS100/smartplug.py +++ b/pyHS100/smartplug.py @@ -2,8 +2,12 @@ import datetime import logging from typing import Any, Dict -from pyHS100 import SmartDevice, DeviceType, SmartDeviceException -from .protocol import TPLinkSmartHomeProtocol +from pyHS100.protocol import TPLinkSmartHomeProtocol +from pyHS100.smartdevice import ( + DeviceType, + SmartDevice, + SmartDeviceException, +) _LOGGER = logging.getLogger(__name__) diff --git a/pyHS100/smartstrip.py b/pyHS100/smartstrip.py index 0c90c5b2..0f9092db 100755 --- a/pyHS100/smartstrip.py +++ b/pyHS100/smartstrip.py @@ -3,9 +3,9 @@ import datetime import logging from typing import Any, Dict, Optional, Union -from pyHS100 import DeviceType, EmeterStatus, SmartDeviceException, SmartPlug - -from .protocol import TPLinkSmartHomeProtocol +from pyHS100.protocol import TPLinkSmartHomeProtocol +from pyHS100.smartdevice import DeviceType, EmeterStatus, SmartDeviceException +from pyHS100.smartplug import SmartPlug _LOGGER = logging.getLogger(__name__)