Merge pull request #76 from rytilahti/extend_tests

Extend tests
This commit is contained in:
Georgi Kirichkov 2017-08-06 15:36:40 +03:00 committed by GitHub
commit d851540380
5 changed files with 154 additions and 110 deletions

View File

@ -9,8 +9,10 @@ if sys.version_info < (3, 4):
sys.version_info)
sys.exit(1)
from pyHS100 import (SmartDevice, SmartPlug, SmartBulb,
TPLinkSmartHomeProtocol, Discover) # noqa: E402
from pyHS100 import (SmartDevice,
SmartPlug,
SmartBulb,
Discover) # noqa: E402
pass_dev = click.make_pass_decorator(SmartDevice)

View File

@ -338,12 +338,12 @@ class SmartDevice(object):
Retrive current energy readings from device.
:returns: current readings or False
:rtype: dict, False
False if device has no energy meter or error occured
:rtype: dict, None
None if device has no energy meter or error occured
:raises SmartDeviceException: on error
"""
if not self.has_emeter:
return False
return None
return self._query_helper(self.emeter_type, "get_realtime")
@ -355,12 +355,12 @@ class SmartDevice(object):
:param month: month for which to retrieve statistcs (default: this
month)
:return: mapping of day of month to value
False if device has no energy meter or error occured
None if device has no energy meter or error occured
:rtype: dict
:raises SmartDeviceException: on error
"""
if not self.has_emeter:
return False
return None
if year is None:
year = datetime.datetime.now().year
@ -384,12 +384,12 @@ class SmartDevice(object):
:param year: year for which to retrieve statistics (default: this year)
:return: dict: mapping of month to value
False if device has no energy meter
None if device has no energy meter
:rtype: dict
:raises SmartDeviceException: on error
"""
if not self.has_emeter:
return False
return None
response = self._query_helper(self.emeter_type, "get_monthstat",
{'year': year})
@ -412,7 +412,7 @@ class SmartDevice(object):
:raises SmartDeviceException: on error
"""
if not self.has_emeter:
return False
return None
self._query_helper(self.emeter_type, "erase_emeter_stat", None)
@ -425,11 +425,11 @@ class SmartDevice(object):
Get the current power consumption in Watt.
:return: the current power consumption in Watt.
False if device has no energy meter.
None if device has no energy meter.
:raises SmartDeviceException: on error
"""
if not self.has_emeter:
return False
return None
response = self.get_emeter_realtime()
if self.emeter_units:

View File

@ -58,7 +58,7 @@ sysinfo_hs100 = {'system': {'get_sysinfo':
'latitude': 12.2,
'led_off': 0,
'longitude': 12.2,
'mac': '50:C7:BF:xx:xx:xx',
'mac': '50:C7:BF:11:22:33',
'model': 'HS100(EU)',
'oemId': '812A90EB2FCF306A993FAD8748024B07',
'on_time': 255419,
@ -71,7 +71,7 @@ sysinfo_hs105 = {'system': {'get_sysinfo':
{'sw_ver': '1.0.6 Build 160722 Rel.081616',
'hw_ver': '1.0', 'type': 'IOT.SMARTPLUGSWITCH',
'model': 'HS105(US)',
'mac': '50:C7:BF:xx:xx:xx',
'mac': '50:C7:BF:11:22:33',
'dev_name': 'Smart Wi-Fi Plug Mini',
'alias': 'TP-LINK_Smart Plug_CF0B',
'relay_state': 0,
@ -198,70 +198,73 @@ sysinfo_lb130 = {'system': {'get_sysinfo':
'smartlife.iot.common.emeter': emeter_units_support,
}
sysinfo_lb110 = {'sys_info': {'emeter':
{'err_code': -2001,
'err_msg': 'Module not support'},
'system':
{'get_sysinfo':
{'active_mode': 'schedule',
'alias': 'Downstairs Light',
'ctrl_protocols':
{'name': 'Linkie',
'version': '1.0'},
'description': 'Smart Wi-Fi LED Bulb '
'with Dimmable Light',
'dev_state': 'normal',
'deviceId':
'80120B3D03E0B639CDF33E3CB1466490187FEF32',
'disco_ver': '1.0',
'err_code': 0,
'heapsize': 309908,
'hwId': '111E35908497A05512E259BB76801E10',
'hw_ver': '1.0',
'is_color': 0,
'is_dimmable': 1,
'is_factory': False,
'is_variable_color_temp': 0,
'light_state':
{'dft_on_state':
{'brightness': 92,
'color_temp': 2700,
'hue': 0,
'mode': 'normal',
'saturation': 0},
'on_off': 0},
'mic_mac': '50C7BF7BE306',
'mic_type': 'IOT.SMARTBULB',
'model': 'LB110(EU)',
'oemId':
'A68E15472071CB761E5CCFB388A1D8AE',
'preferred_state': [{'brightness': 100,
'color_temp': 2700,
'hue': 0,
'index': 0,
'saturation': 0},
{'brightness': 58,
'color_temp': 2700,
'hue': 0,
'index': 1,
'saturation': 0},
{'brightness': 25,
'color_temp': 2700,
'hue': 0,
'index': 2,
'saturation': 0},
{'brightness': 1,
'color_temp': 2700,
'hue': 0,
'index': 3,
'saturation': 0}],
'rssi': -61,
'sw_ver': '1.5.5 Build 170623 '
'Rel.090105'
}
}
}
}
sysinfo_lb110 = {'system': {
'sys_info':
{'emeter':
{'err_code': -2001,
'err_msg': 'Module not support'},
'system':
{'get_sysinfo':
{'active_mode': 'schedule',
'alias': 'Downstairs Light',
'ctrl_protocols':
{'name': 'Linkie',
'version': '1.0'},
'description': 'Smart Wi-Fi LED Bulb '
'with Dimmable Light',
'dev_state': 'normal',
'deviceId':
'80120B3D03E0B639CDF33E3CB1466490187FEF32',
'disco_ver': '1.0',
'err_code': 0,
'heapsize': 309908,
'hwId': '111E35908497A05512E259BB76801E10',
'hw_ver': '1.0',
'is_color': 0,
'is_dimmable': 1,
'is_factory': False,
'is_variable_color_temp': 0,
'light_state':
{'dft_on_state':
{'brightness': 92,
'color_temp': 2700,
'hue': 0,
'mode': 'normal',
'saturation': 0},
'on_off': 0},
'mic_mac': '50C7BF7BE306',
'mic_type': 'IOT.SMARTBULB',
'model': 'LB110(EU)',
'oemId':
'A68E15472071CB761E5CCFB388A1D8AE',
'preferred_state': [{'brightness': 100,
'color_temp': 2700,
'hue': 0,
'index': 0,
'saturation': 0},
{'brightness': 58,
'color_temp': 2700,
'hue': 0,
'index': 1,
'saturation': 0},
{'brightness': 25,
'color_temp': 2700,
'hue': 0,
'index': 2,
'saturation': 0},
{'brightness': 1,
'color_temp': 2700,
'hue': 0,
'index': 3,
'saturation': 0}],
'rssi': -61,
'sw_ver': '1.5.5 Build 170623 '
'Rel.090105'
}
}
}
}}
def error(cls, target, cmd="no-command", msg="default msg"):
return {target: {cmd: {"err_code": -1323, "msg": msg}}}

View File

@ -3,7 +3,7 @@ from voluptuous import Schema, Invalid, All, Range
from functools import partial
from .. import SmartBulb, SmartDeviceException
from .fakes import FakeTransportProtocol, sysinfo_lb130
from .fakes import FakeTransportProtocol, sysinfo_lb130, sysinfo_lb110
BULB_IP = '192.168.250.186'
SKIP_STATE_TESTS = False
@ -23,6 +23,7 @@ def check_mode(x):
class TestSmartBulb(TestCase):
SYSINFO = sysinfo_lb130
# these schemas should go to the mainlib as
# they can be useful when adding support for new features/devices
# as well as to check that faked devices are operating properly.
@ -80,7 +81,7 @@ class TestSmartBulb(TestCase):
def setUp(self):
self.bulb = SmartBulb(BULB_IP,
protocol=FakeTransportProtocol(sysinfo_lb130))
protocol=FakeTransportProtocol(self.SYSINFO))
def tearDown(self):
self.bulb = None
@ -91,7 +92,7 @@ class TestSmartBulb(TestCase):
def test_initialize_invalid_connection(self):
bulb = SmartBulb('127.0.0.1',
protocol=FakeTransportProtocol(sysinfo_lb130,
protocol=FakeTransportProtocol(self.SYSINFO,
invalid=True))
with self.assertRaises(SmartDeviceException):
bulb.sys_info['model']
@ -187,3 +188,7 @@ class TestSmartBulb(TestCase):
def test_rssi(self):
self.sysinfo_schema({'rssi': self.bulb.rssi}) # wrapping for vol
class TestSmartBulbLB110(TestSmartBulb):
SYSINFO = sysinfo_lb110

View File

@ -1,11 +1,15 @@
from unittest import TestCase, skip, skipIf
from voluptuous import Schema, Invalid, All, Range
from voluptuous import Schema, Invalid, All, Any, Range
from functools import partial
import datetime
import re
from .. import SmartPlug, SmartDeviceException
from .fakes import FakeTransportProtocol, sysinfo_hs110, sysinfo_hs105
from .fakes import (FakeTransportProtocol,
sysinfo_hs100,
sysinfo_hs105,
sysinfo_hs110,
sysinfo_hs200)
PLUG_IP = '192.168.250.186'
SKIP_STATE_TESTS = False
@ -24,13 +28,14 @@ def check_mac(x):
def check_mode(x):
if x in ['schedule']:
if x in ['schedule', 'none']:
return x
raise Invalid("invalid mode {}".format(x))
class TestSmartPlug(TestCase):
class TestSmartPlugHS110(TestCase):
SYSINFO = sysinfo_hs110
# these schemas should go to the mainlib as
# they can be useful when adding support for new features/devices
# as well as to check that faked devices are operating properly.
@ -44,26 +49,29 @@ class TestSmartPlug(TestCase):
'hwId': str,
'hw_ver': str,
'icon_hash': str,
'latitude': All(float, Range(min=-90, max=90)),
'led_off': check_int_bool,
'longitude': All(float, Range(min=-180, max=180)),
'latitude': Any(All(float, Range(min=-90, max=90)), None),
'latitude_i': Any(All(float, Range(min=-90, max=90)), None),
'longitude': Any(All(float, Range(min=-180, max=180)), None),
'longitude_i': Any(All(float, Range(min=-180, max=180)), None),
'mac': check_mac,
'model': str,
'oemId': str,
'on_time': int,
'relay_state': int,
'rssi': All(int, Range(max=0)),
'rssi': Any(int, None), # rssi can also be positive, see #54
'sw_ver': str,
'type': str,
'mic_type': str,
'updating': check_int_bool,
})
current_consumption_schema = Schema({
current_consumption_schema = Schema(Any({
'voltage': All(float, Range(min=0, max=300)),
'power': All(float, Range(min=0)),
'total': All(float, Range(min=0)),
'current': All(float, Range(min=0)),
})
}, None))
tz_schema = Schema({
'zone_str': str,
@ -74,7 +82,7 @@ class TestSmartPlug(TestCase):
def setUp(self):
self.plug = SmartPlug(PLUG_IP,
protocol=FakeTransportProtocol(sysinfo_hs110))
protocol=FakeTransportProtocol(self.SYSINFO))
def tearDown(self):
self.plug = None
@ -85,7 +93,7 @@ class TestSmartPlug(TestCase):
def test_initialize_invalid_connection(self):
plug = SmartPlug('127.0.0.1',
protocol=FakeTransportProtocol(sysinfo_hs110,
protocol=FakeTransportProtocol(self.SYSINFO,
invalid=True))
with self.assertRaises(SmartDeviceException):
plug.sys_info['model']
@ -152,31 +160,45 @@ class TestSmartPlug(TestCase):
self.assertFalse(self.plug.has_emeter)
def test_get_emeter_realtime(self):
self.current_consumption_schema((self.plug.get_emeter_realtime()))
if self.plug.has_emeter:
self.current_consumption_schema((self.plug.get_emeter_realtime()))
else:
self.assertEqual(self.plug.get_emeter_realtime(), None)
def test_get_emeter_daily(self):
self.assertEqual(self.plug.get_emeter_daily(year=1900, month=1), {})
if self.plug.has_emeter:
self.assertEqual(self.plug.get_emeter_daily(year=1900, month=1),
{})
k, v = self.plug.get_emeter_daily().popitem()
self.assertTrue(isinstance(k, int))
self.assertTrue(isinstance(v, float))
k, v = self.plug.get_emeter_daily().popitem()
self.assertTrue(isinstance(k, int))
self.assertTrue(isinstance(v, float))
else:
self.assertEqual(self.plug.get_emeter_daily(year=1900, month=1),
None)
def test_get_emeter_monthly(self):
self.assertEqual(self.plug.get_emeter_monthly(year=1900), {})
if self.plug.has_emeter:
self.assertEqual(self.plug.get_emeter_monthly(year=1900), {})
d = self.plug.get_emeter_monthly()
k, v = d.popitem()
self.assertTrue(isinstance(k, int))
self.assertTrue(isinstance(v, float))
d = self.plug.get_emeter_monthly()
k, v = d.popitem()
self.assertTrue(isinstance(k, int))
self.assertTrue(isinstance(v, float))
else:
self.assertEqual(self.plug.get_emeter_monthly(year=1900), None)
@skip("not clearing your stats..")
def test_erase_emeter_stats(self):
self.fail()
def test_current_consumption(self):
x = self.plug.current_consumption()
self.assertTrue(isinstance(x, float))
self.assertTrue(x >= 0.0)
if self.plug.has_emeter:
x = self.plug.current_consumption()
self.assertTrue(isinstance(x, float))
self.assertTrue(x >= 0.0)
else:
self.assertEqual(self.plug.current_consumption(), None)
def test_identify(self):
ident = self.plug.identify()
@ -221,14 +243,26 @@ class TestSmartPlug(TestCase):
def test_location(self):
self.sysinfo_schema(self.plug.location)
def test_location_i(self):
plug_i = SmartPlug(PLUG_IP,
protocol=FakeTransportProtocol(sysinfo_hs105))
self.sysinfo_schema(plug_i.location)
def test_rssi(self):
self.sysinfo_schema({'rssi': self.plug.rssi}) # wrapping for vol
def test_mac(self):
self.sysinfo_schema({'mac': self.plug.mac}) # wrapping for val
# TODO check setting?
class TestSmartPlugHS100(TestSmartPlugHS110):
SYSINFO = sysinfo_hs100
class TestSmartPlugHS200(TestSmartPlugHS110):
SYSINFO = sysinfo_hs200
class TestSmartPlugHS105(TestSmartPlugHS110):
SYSINFO = sysinfo_hs105
def test_location_i(self):
plug_i = SmartPlug(PLUG_IP,
protocol=FakeTransportProtocol(self.SYSINFO))
self.sysinfo_schema(plug_i.location)