From 7457ad48f8a1d0041044ef05a6f3943a9b5c5dce Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Fri, 26 May 2017 16:11:03 +0200 Subject: [PATCH] extract shared types (exceptions, enums), add module level doc, rename exception to be generic --- pyHS100/__init__.py | 17 ++++++++++++++++- pyHS100/pyHS100.py | 26 ++++++-------------------- pyHS100/tests/fakes.py | 4 ++-- pyHS100/tests/test_bulb.py | 6 +++--- pyHS100/tests/test_pyHS100.py | 6 +++--- pyHS100/types.py | 15 +++++++++++++++ 6 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 pyHS100/types.py diff --git a/pyHS100/__init__.py b/pyHS100/__init__.py index 51a64d35..b3f75b8c 100644 --- a/pyHS100/__init__.py +++ b/pyHS100/__init__.py @@ -1,5 +1,20 @@ +""" +This module provides a way to interface with TP-Link's smart home devices, +such as smart plugs (HS1xx), wall switches (HS2xx), and light bulbs (LB1xx). + +All common, shared functionalities are available through `SmartDevice` class:: + + x = SmartDevice("192.168.1.1") + print(x.sys_info) + +For device type specific actions `SmartBulb` or `SmartPlug` must be used instead. + +Module-specific errors are raised as `SmartDeviceException` and are expected +to be handled by the user of the library. +""" # flake8: noqa from .smartplug import SmartPlug -from .pyHS100 import SmartPlugException, SmartDevice +from .pyHS100 import SmartDevice +from .types import SmartDeviceException from .smartbulb import SmartBulb from .protocol import TPLinkSmartHomeProtocol diff --git a/pyHS100/pyHS100.py b/pyHS100/pyHS100.py index d215b10e..7f0cdd65 100644 --- a/pyHS100/pyHS100.py +++ b/pyHS100/pyHS100.py @@ -16,27 +16,13 @@ http://www.apache.org/licenses/LICENSE-2.0 import datetime import logging import socket -import enum +from .types import SmartDeviceException from .protocol import TPLinkSmartHomeProtocol _LOGGER = logging.getLogger(__name__) -class SmartPlugException(Exception): - """ - SmartPlugException gets raised for errors reported by the plug. - """ - pass - - -class DeviceType(enum.Enum): - Unknown = -1, - Plug = 0, - Switch = 1 - Bulb = 2 - - class SmartDevice(object): # possible device features FEATURE_ENERGY_METER = 'ENE' @@ -76,16 +62,16 @@ class SmartDevice(object): request={target: {cmd: arg}} ) except Exception as ex: - raise SmartPlugException('Communication error') from ex + raise SmartDeviceException('Communication error') from ex if target not in response: - raise SmartPlugException("No required {} in response: {}" - .format(target, response)) + raise SmartDeviceException("No required {} in response: {}" + .format(target, response)) result = response[target] if "err_code" in result and result["err_code"] != 0: - raise SmartPlugException("Error on {}.{}: {}" - .format(target, cmd, result)) + raise SmartDeviceException("Error on {}.{}: {}" + .format(target, cmd, result)) result = result[cmd] del result["err_code"] diff --git a/pyHS100/tests/fakes.py b/pyHS100/tests/fakes.py index f2f28be1..81f40a19 100644 --- a/pyHS100/tests/fakes.py +++ b/pyHS100/tests/fakes.py @@ -1,5 +1,5 @@ from ..protocol import TPLinkSmartHomeProtocol -from .. import SmartPlugException +from .. import SmartDeviceException import logging @@ -250,7 +250,7 @@ class FakeTransportProtocol(TPLinkSmartHomeProtocol): def query(self, host, request, port=9999): if self.invalid: - raise SmartPlugException("Invalid connection, can't query!") + raise SmartDeviceException("Invalid connection, can't query!") proto = self.proto diff --git a/pyHS100/tests/test_bulb.py b/pyHS100/tests/test_bulb.py index ef24651a..9618a1d6 100644 --- a/pyHS100/tests/test_bulb.py +++ b/pyHS100/tests/test_bulb.py @@ -2,7 +2,7 @@ from unittest import TestCase, skip, skipIf from voluptuous import Schema, Invalid, All, Range from functools import partial -from .. import SmartBulb, SmartPlugException +from .. import SmartBulb, SmartDeviceException from .fakes import FakeTransportProtocol, sysinfo_lb130 BULB_IP = '192.168.250.186' @@ -93,11 +93,11 @@ class TestSmartBulb(TestCase): bulb = SmartBulb('127.0.0.1', protocol=FakeTransportProtocol(sysinfo_lb130, invalid=True)) - with self.assertRaises(SmartPlugException): + with self.assertRaises(SmartDeviceException): bulb.sys_info['model'] def test_query_helper(self): - with self.assertRaises(SmartPlugException): + with self.assertRaises(SmartDeviceException): self.bulb._query_helper("test", "testcmd", {}) # TODO check for unwrapping? diff --git a/pyHS100/tests/test_pyHS100.py b/pyHS100/tests/test_pyHS100.py index 87314d27..ab0f013a 100644 --- a/pyHS100/tests/test_pyHS100.py +++ b/pyHS100/tests/test_pyHS100.py @@ -4,7 +4,7 @@ from functools import partial import datetime import re -from .. import SmartPlug, SmartPlugException +from .. import SmartPlug, SmartDeviceException from .fakes import FakeTransportProtocol, sysinfo_hs110, sysinfo_hs105 PLUG_IP = '192.168.250.186' @@ -87,11 +87,11 @@ class TestSmartPlug(TestCase): plug = SmartPlug('127.0.0.1', protocol=FakeTransportProtocol(sysinfo_hs110, invalid=True)) - with self.assertRaises(SmartPlugException): + with self.assertRaises(SmartDeviceException): plug.sys_info['model'] def test_query_helper(self): - with self.assertRaises(SmartPlugException): + with self.assertRaises(SmartDeviceException): self.plug._query_helper("test", "testcmd", {}) # TODO check for unwrapping? diff --git a/pyHS100/types.py b/pyHS100/types.py new file mode 100644 index 00000000..85d07efa --- /dev/null +++ b/pyHS100/types.py @@ -0,0 +1,15 @@ +import enum + + +class SmartDeviceException(Exception): + """ + SmartPlugException gets raised for errors reported by the plug. + """ + pass + + +class DeviceType(enum.Enum): + Unknown = -1, + Plug = 0, + Switch = 1 + Bulb = 2