2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
pyHS100
|
|
|
|
Python library supporting TP-Link Smart Plugs/Switches (HS100/HS110/Hs200).
|
|
|
|
|
|
|
|
The communication protocol was reverse engineered by Lubomir Stroetmann and
|
|
|
|
Tobias Esser in 'Reverse Engineering the TP-Link HS110':
|
|
|
|
https://www.softscheck.com/en/reverse-engineering-tp-link-hs110/
|
|
|
|
|
|
|
|
This library reuses codes and concepts of the TP-Link WiFi SmartPlug Client
|
|
|
|
at https://github.com/softScheck/tplink-smartplug, developed by Lubomir
|
|
|
|
Stroetmann which is licensed under the Apache License, Version 2.0.
|
|
|
|
|
|
|
|
You may obtain a copy of the license at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
"""
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
import datetime
|
|
|
|
import json
|
2016-07-09 12:36:33 +00:00
|
|
|
import logging
|
|
|
|
import socket
|
2016-10-15 08:18:31 +00:00
|
|
|
import sys
|
2016-07-09 11:34:27 +00:00
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2016-07-09 12:36:33 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
class SmartPlugException(Exception):
|
|
|
|
"""
|
|
|
|
SmartPlugException gets raised for errors reported by the plug.
|
|
|
|
"""
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
class SmartPlug:
|
2016-11-21 22:18:12 +00:00
|
|
|
"""Representation of a TP-Link Smart Switch.
|
2016-07-09 12:36:33 +00:00
|
|
|
|
2016-07-09 11:34:27 +00:00
|
|
|
Usage example when used as library:
|
|
|
|
p = SmartPlug("192.168.1.105")
|
2016-11-21 23:39:17 +00:00
|
|
|
# print the devices alias
|
|
|
|
print(p.alias)
|
2016-07-09 11:34:27 +00:00
|
|
|
# change state of plug
|
|
|
|
p.state = "ON"
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
p.state = "OFF"
|
2016-07-09 11:34:27 +00:00
|
|
|
# query and print current state of plug
|
|
|
|
print(p.state)
|
2016-11-22 01:31:25 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
Errors reported by the device are raised as SmartPlugExceptions,
|
|
|
|
and should be handled by the user of the library.
|
|
|
|
|
2016-07-09 11:34:27 +00:00
|
|
|
Note:
|
|
|
|
The library references the same structure as defined for the D-Link Switch
|
|
|
|
"""
|
2016-12-04 22:00:56 +00:00
|
|
|
# switch states
|
|
|
|
SWITCH_STATE_ON = 'ON'
|
|
|
|
SWITCH_STATE_OFF = 'OFF'
|
|
|
|
SWITCH_STATE_UNKNOWN = 'UNKNOWN'
|
|
|
|
|
|
|
|
# possible device features
|
|
|
|
FEATURE_ENERGY_METER = 'ENE'
|
|
|
|
FEATURE_TIMER = 'TIM'
|
|
|
|
|
|
|
|
ALL_FEATURES = (FEATURE_ENERGY_METER, FEATURE_TIMER)
|
2016-07-09 11:34:27 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
def __init__(self, ip_address):
|
|
|
|
"""
|
|
|
|
Create a new SmartPlug instance, identified through its IP address.
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:param str ip_address: ip address on which the device listens
|
|
|
|
:raises SmartPlugException: when unable to communicate with the device
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
socket.inet_pton(socket.AF_INET, ip_address)
|
|
|
|
self.ip_address = ip_address
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
def initialize(self):
|
|
|
|
"""
|
|
|
|
(Re-)Initializes the state.
|
|
|
|
|
|
|
|
This should be called when the state of the plug is changed anyway.
|
|
|
|
|
|
|
|
:raises: SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
self.sys_info = self.get_sysinfo()
|
|
|
|
|
|
|
|
self._alias, self.model, self.features = self.identify()
|
|
|
|
|
|
|
|
def _query_helper(self, target, cmd, arg={}):
|
|
|
|
"""
|
|
|
|
Helper returning unwrapped result object and doing error handling.
|
|
|
|
|
|
|
|
:param target: Target system {system, time, emeter, ..}
|
|
|
|
:param cmd: Command to execute
|
|
|
|
:param arg: JSON object passed as parameter to the command, defaults to {}
|
|
|
|
:return: Unwrapped result for the call.
|
|
|
|
:rtype: dict
|
|
|
|
:raises SmartPlugException: if command was not executed correctly
|
|
|
|
"""
|
|
|
|
response = TPLinkSmartHomeProtocol.query(
|
|
|
|
host=self.ip_address,
|
|
|
|
request={target: {cmd: arg}}
|
|
|
|
)
|
|
|
|
|
|
|
|
result = response[target][cmd]
|
|
|
|
if result["err_code"] != 0:
|
|
|
|
raise SmartPlugException("Error on {}.{}: {}".format(target, cmd, result))
|
|
|
|
|
|
|
|
del result["err_code"]
|
|
|
|
|
|
|
|
return result
|
2016-07-09 11:34:27 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def state(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Retrieve the switch state
|
|
|
|
|
|
|
|
:returns: one of
|
|
|
|
SWITCH_STATE_ON
|
|
|
|
SWITCH_STATE_OFF
|
|
|
|
SWITCH_STATE_UNKNOWN
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:rtype: str
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
relay_state = self.sys_info['relay_state']
|
2016-10-19 07:53:21 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
if relay_state == 0:
|
2016-12-04 22:00:56 +00:00
|
|
|
return SmartPlug.SWITCH_STATE_OFF
|
2016-10-19 07:53:21 +00:00
|
|
|
elif relay_state == 1:
|
2016-12-04 22:00:56 +00:00
|
|
|
return SmartPlug.SWITCH_STATE_ON
|
2016-07-09 11:34:27 +00:00
|
|
|
else:
|
2016-11-22 01:31:25 +00:00
|
|
|
_LOGGER.warning("Unknown state %s returned.", relay_state)
|
2016-12-04 22:00:56 +00:00
|
|
|
return SmartPlug.SWITCH_STATE_UNKNOWN
|
2016-07-09 11:34:27 +00:00
|
|
|
|
|
|
|
@state.setter
|
|
|
|
def state(self, value):
|
|
|
|
"""
|
2016-11-22 01:31:25 +00:00
|
|
|
Set the new switch state
|
2016-07-09 11:34:27 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
:param value: one of
|
|
|
|
SWITCH_STATE_ON
|
|
|
|
SWITCH_STATE_OFF
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:raises ValueError: on invalid state
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
2016-12-04 22:00:56 +00:00
|
|
|
if value.upper() == SmartPlug.SWITCH_STATE_ON:
|
2016-11-22 01:31:25 +00:00
|
|
|
self.turn_on()
|
2016-12-04 22:00:56 +00:00
|
|
|
elif value.upper() == SmartPlug.SWITCH_STATE_OFF:
|
2016-10-18 07:59:30 +00:00
|
|
|
self.turn_off()
|
2016-07-09 11:34:27 +00:00
|
|
|
else:
|
2016-11-22 01:31:25 +00:00
|
|
|
raise ValueError("State %s is not valid.", value)
|
2016-07-09 11:34:27 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self.initialize()
|
|
|
|
|
2016-11-21 23:39:17 +00:00
|
|
|
def get_sysinfo(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Retrieve system information.
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:return: sysinfo
|
|
|
|
:rtype dict
|
|
|
|
:raises SmartPlugException: on error
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
return self._query_helper("system", "get_sysinfo")
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
@property
|
|
|
|
def is_on(self):
|
|
|
|
"""
|
|
|
|
Returns whether device is on.
|
2016-11-22 01:31:25 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:return: True if device is on, False otherwise
|
|
|
|
"""
|
|
|
|
return bool(self.sys_info['relay_state'])
|
|
|
|
|
|
|
|
@property
|
|
|
|
def is_off(self):
|
|
|
|
"""
|
|
|
|
Returns whether device is off.
|
|
|
|
|
|
|
|
:return: True if device is off, False otherwise.
|
|
|
|
:rtype: bool
|
|
|
|
"""
|
|
|
|
return not self.is_on
|
2016-11-22 01:31:25 +00:00
|
|
|
|
2016-10-13 15:31:34 +00:00
|
|
|
def turn_on(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Turn the switch on.
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self._query_helper("system", "set_relay_state", {"state": 1})
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self.initialize()
|
2016-10-13 15:31:34 +00:00
|
|
|
|
|
|
|
def turn_off(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Turn the switch off.
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self._query_helper("system", "set_relay_state", {"state": 0})
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self.initialize()
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 23:39:17 +00:00
|
|
|
@property
|
|
|
|
def has_emeter(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Checks feature list for energey meter support.
|
|
|
|
|
|
|
|
:return: True if energey meter is available
|
|
|
|
False if energymeter is missing
|
|
|
|
"""
|
2016-12-04 22:00:56 +00:00
|
|
|
return SmartPlug.FEATURE_ENERGY_METER in self.features
|
2016-11-21 23:39:17 +00:00
|
|
|
|
2016-10-13 15:31:34 +00:00
|
|
|
def get_emeter_realtime(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Retrive current energy readings from device.
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:returns: current readings or False
|
|
|
|
:rtype: dict, False
|
2016-11-22 01:31:25 +00:00
|
|
|
False if device has no energy meter or error occured
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 23:39:17 +00:00
|
|
|
if not self.has_emeter:
|
2016-10-18 07:59:30 +00:00
|
|
|
return False
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
return self._query_helper("emeter", "get_realtime")
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
def get_emeter_daily(self, year=None, month=None):
|
|
|
|
"""
|
|
|
|
Retrieve daily statistics for a given month
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
:param year: year for which to retrieve statistics (default: this year)
|
|
|
|
:param month: month for which to retrieve statistcs (default: this
|
|
|
|
month)
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:return: mapping of day of month to value
|
2016-11-22 01:31:25 +00:00
|
|
|
False if device has no energy meter or error occured
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:rtype: dict
|
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 23:39:17 +00:00
|
|
|
if not self.has_emeter:
|
2016-10-18 07:59:30 +00:00
|
|
|
return False
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
if year is None:
|
|
|
|
year = datetime.datetime.now().year
|
|
|
|
if month is None:
|
|
|
|
month = datetime.datetime.now().month
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
response = self._query_helper("emeter", "get_daystat",
|
|
|
|
{'month': month, 'year': year})
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
return {entry['day']: entry['energy']
|
|
|
|
for entry in response['day_list']}
|
2016-10-18 07:59:30 +00:00
|
|
|
|
|
|
|
def get_emeter_monthly(self, year=datetime.datetime.now().year):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Retrieve monthly statistics for a given year.
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
:param year: year for which to retrieve statistics (default: this year)
|
|
|
|
:return: dict: mapping of month to value
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
False if device has no energy meter
|
|
|
|
:rtype: dict
|
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 23:39:17 +00:00
|
|
|
if not self.has_emeter:
|
2016-10-18 07:59:30 +00:00
|
|
|
return False
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
response = self._query_helper("emeter", "get_monthstat",
|
|
|
|
{'year': year})
|
2016-10-18 07:59:30 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
return {entry['month']: entry['energy']
|
|
|
|
for entry in response['month_list']}
|
2016-10-13 15:31:34 +00:00
|
|
|
|
|
|
|
def erase_emeter_stats(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Erase energy meter statistics
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
:return: True if statistics were deleted
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
False if device has no energy meter.
|
|
|
|
:rtype: bool
|
|
|
|
:raises SmartPlugException: on error
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 23:39:17 +00:00
|
|
|
if not self.has_emeter:
|
2016-10-18 07:59:30 +00:00
|
|
|
return False
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self._query_helper("emeter", "erase_emeter_stat", None)
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
# As query_helper raises exception in case of failure, we have succeeded when we are this far.
|
|
|
|
return True
|
2016-10-13 15:31:34 +00:00
|
|
|
|
|
|
|
def current_consumption(self):
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
|
|
|
Get the current power consumption in Watt.
|
|
|
|
|
|
|
|
:return: the current power consumption in Watt.
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
False if device has no energy meter.
|
|
|
|
:raises SmartPlugException: on error
|
2016-11-22 01:31:25 +00:00
|
|
|
"""
|
2016-11-21 23:39:17 +00:00
|
|
|
if not self.has_emeter:
|
2016-10-19 07:28:48 +00:00
|
|
|
return False
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-10-18 07:59:30 +00:00
|
|
|
response = self.get_emeter_realtime()
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-22 01:31:25 +00:00
|
|
|
return response['power']
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 23:39:17 +00:00
|
|
|
def identify(self):
|
|
|
|
"""
|
|
|
|
Query device information to identify model and featureset
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:return: (alias, model, list of supported features)
|
|
|
|
:rtype: tuple
|
2016-11-21 23:39:17 +00:00
|
|
|
"""
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
alias = self.sys_info['alias']
|
|
|
|
model = self.sys_info['model']
|
|
|
|
features = self.sys_info['feature'].split(':')
|
2016-11-21 23:39:17 +00:00
|
|
|
|
|
|
|
for feature in features:
|
2016-12-04 22:00:56 +00:00
|
|
|
if feature not in SmartPlug.ALL_FEATURES:
|
2016-11-22 01:31:25 +00:00
|
|
|
_LOGGER.warning("Unknown feature %s on device %s.",
|
|
|
|
feature, model)
|
2016-11-21 23:39:17 +00:00
|
|
|
|
|
|
|
return alias, model, features
|
2016-11-21 22:18:12 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
@property
|
|
|
|
def alias(self):
|
|
|
|
"""
|
|
|
|
Get current device alias (name)
|
|
|
|
|
|
|
|
:return: Device name aka alias.
|
|
|
|
:rtype: str
|
|
|
|
"""
|
|
|
|
return self._alias
|
|
|
|
|
|
|
|
@alias.setter
|
|
|
|
def alias(self, alias):
|
|
|
|
"""
|
|
|
|
Sets the device name aka alias.
|
|
|
|
|
|
|
|
:param alias: New alias (name)
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
self._query_helper("system", "set_dev_alias", {"alias": alias})
|
|
|
|
|
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def led(self):
|
|
|
|
"""
|
|
|
|
Returns the state of the led.
|
|
|
|
|
|
|
|
:return: True if led is on, False otherwise
|
|
|
|
:rtype: bool
|
|
|
|
"""
|
|
|
|
return bool(1 - self.sys_info["led_off"])
|
|
|
|
|
|
|
|
@led.setter
|
|
|
|
def led(self, state):
|
|
|
|
"""
|
|
|
|
Sets the state of the led (night mode)
|
|
|
|
|
|
|
|
:param bool state: True to set led on, False to set led off
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
self._query_helper("system", "set_led_off", {"off": int(not state)})
|
|
|
|
|
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def icon(self):
|
|
|
|
"""
|
|
|
|
Returns device icon
|
|
|
|
|
|
|
|
Note: not working on HS110, but is always empty.
|
|
|
|
|
|
|
|
:return: icon and its hash
|
|
|
|
:rtype: dict
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
return self._query_helper("system", "get_dev_icon")
|
|
|
|
|
|
|
|
@icon.setter
|
|
|
|
def icon(self, icon):
|
|
|
|
"""
|
|
|
|
Content for hash and icon are unknown.
|
|
|
|
|
|
|
|
:param str icon: Icon path(?)
|
|
|
|
:raises NotImplementedError: when not implemented
|
|
|
|
:raises SmartPlugError: on error
|
|
|
|
"""
|
|
|
|
raise NotImplementedError("Values for this call are unknown at this point.")
|
|
|
|
# here just for the sake of completeness
|
|
|
|
# self._query_helper("system", "set_dev_icon", {"icon": "", "hash": ""})
|
|
|
|
# self.initialize()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def time(self):
|
|
|
|
"""
|
|
|
|
Returns current time from the device.
|
|
|
|
|
|
|
|
:return: datetime for device's time
|
|
|
|
:rtype: datetime.datetime
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
res = self._query_helper("time", "get_time")
|
|
|
|
return datetime.datetime(res["year"], res["month"], res["mday"],
|
|
|
|
res["hour"], res["min"], res["sec"])
|
|
|
|
|
|
|
|
@time.setter
|
|
|
|
def time(self, ts):
|
|
|
|
"""
|
|
|
|
Sets time based on datetime object.
|
|
|
|
Note: this calls set_timezone() for setting.
|
|
|
|
|
|
|
|
:param datetime.datetime ts: New date and time
|
|
|
|
:return: result
|
|
|
|
:type: dict
|
|
|
|
:raises NotImplemented: when not implemented.
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
raise NotImplementedError("Fails with err_code == 0 with HS110.")
|
|
|
|
""" here just for the sake of completeness / if someone figures out why it doesn't work.
|
|
|
|
ts_obj = {
|
|
|
|
"index": self.timezone["index"],
|
|
|
|
"hour": ts.hour,
|
|
|
|
"min": ts.minute,
|
|
|
|
"sec": ts.second,
|
|
|
|
"year": ts.year,
|
|
|
|
"month": ts.month,
|
|
|
|
"mday": ts.day,
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
response = self._query_helper("time", "set_timezone", ts_obj)
|
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
return response
|
|
|
|
"""
|
|
|
|
|
|
|
|
@property
|
|
|
|
def timezone(self):
|
|
|
|
"""
|
|
|
|
Returns timezone information
|
|
|
|
|
|
|
|
:return: Timezone information
|
|
|
|
:rtype: dict
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
return self._query_helper("time", "get_timezone")
|
|
|
|
|
|
|
|
@property
|
|
|
|
def hw_info(self):
|
|
|
|
"""
|
|
|
|
Returns information about hardware
|
|
|
|
|
|
|
|
:return: Information about hardware
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
|
|
|
keys = ["sw_ver", "hw_ver", "mac", "hwId", "fwId", "oemId", "dev_name"]
|
|
|
|
return {key: self.sys_info[key] for key in keys}
|
|
|
|
|
|
|
|
@property
|
|
|
|
def on_since(self):
|
|
|
|
"""
|
|
|
|
Returns pretty-printed on-time
|
|
|
|
|
|
|
|
:return: datetime for on since
|
|
|
|
:rtype: datetime
|
|
|
|
"""
|
|
|
|
return datetime.datetime.now() - \
|
|
|
|
datetime.timedelta(seconds=self.sys_info["on_time"])
|
|
|
|
|
|
|
|
@property
|
|
|
|
def location(self):
|
|
|
|
"""
|
|
|
|
Location of the device, as read from sysinfo
|
|
|
|
|
|
|
|
:return: latitude and longitude
|
|
|
|
:rtype: dict
|
|
|
|
"""
|
|
|
|
|
|
|
|
return {"latitude": self.sys_info["latitude"],
|
|
|
|
"longitude": self.sys_info["longitude"]}
|
|
|
|
|
|
|
|
@property
|
|
|
|
def rssi(self):
|
|
|
|
"""
|
|
|
|
Returns WiFi signal strenth (rssi)
|
|
|
|
|
|
|
|
:return: rssi
|
|
|
|
:rtype: int
|
|
|
|
"""
|
|
|
|
return self.sys_info["rssi"]
|
|
|
|
|
|
|
|
@property
|
|
|
|
def mac(self):
|
|
|
|
"""
|
|
|
|
Returns mac address
|
|
|
|
|
|
|
|
:return: mac address in hexadecimal with colons, e.g. 01:23:45:67:89:ab
|
|
|
|
:rtype: str
|
|
|
|
"""
|
|
|
|
return self.sys_info["mac"]
|
|
|
|
|
|
|
|
@mac.setter
|
|
|
|
def mac(self, mac):
|
|
|
|
"""
|
|
|
|
Sets new mac address
|
|
|
|
|
|
|
|
:param str mac: mac in hexadecimal with colons, e.g. 01:23:45:67:89:ab
|
|
|
|
:raises SmartPlugException: on error
|
|
|
|
"""
|
|
|
|
self._query_helper("system", "set_mac_addr", {"mac": mac})
|
|
|
|
|
|
|
|
self.initialize()
|
|
|
|
|
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
|
|
|
|
class TPLinkSmartHomeProtocol:
|
|
|
|
"""
|
|
|
|
Implementation of the TP-Link Smart Home Protocol
|
|
|
|
|
|
|
|
Encryption/Decryption methods based on the works of
|
|
|
|
Lubomir Stroetmann and Tobias Esser
|
|
|
|
|
|
|
|
https://www.softscheck.com/en/reverse-engineering-tp-link-hs110/
|
|
|
|
https://github.com/softScheck/tplink-smartplug/
|
|
|
|
|
|
|
|
which are licensed under the Apache License, Version 2.0
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
"""
|
2016-11-22 01:31:25 +00:00
|
|
|
initialization_vector = 171
|
2016-10-17 12:17:28 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
@staticmethod
|
|
|
|
def query(host, request, port=9999):
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 22:18:12 +00:00
|
|
|
Request information from a TP-Link SmartHome Device and return the
|
|
|
|
response.
|
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
:param str host: ip address of the device
|
|
|
|
:param int port: port on the device (default: 9999)
|
2016-11-21 22:18:12 +00:00
|
|
|
:param request: command to send to the device (can be either dict or
|
|
|
|
json string)
|
|
|
|
:return:
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 22:18:12 +00:00
|
|
|
if isinstance(request, dict):
|
|
|
|
request = json.dumps(request)
|
2016-10-15 08:18:31 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
sock.connect((host, port))
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
|
|
|
|
_LOGGER.debug("> (%i) %s", len(request), request)
|
2016-11-21 22:18:12 +00:00
|
|
|
sock.send(TPLinkSmartHomeProtocol.encrypt(request))
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
|
|
|
|
buffer = bytes()
|
|
|
|
while True:
|
|
|
|
chunk = sock.recv(4096)
|
|
|
|
buffer += chunk
|
|
|
|
if not chunk:
|
|
|
|
break
|
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
sock.shutdown(socket.SHUT_RDWR)
|
|
|
|
sock.close()
|
2016-10-13 15:31:34 +00:00
|
|
|
|
Read all data from the device, disable double-encoding, implement more APIs, refactor querying, update README (#11)
* Read from socket until no data available, disable double string encoding
HS110 sends sometimes datagrams in chunks especially for get_daystat,
this patch makes it to read until there is no more data to be read.
As json.dumps() does JSON encoding already, there's no need to str()
the year or month either.
* Add cli.py, a simple script to query devices for debugging purposes.
* allow easier importing with from pyHS100 import SmartPlug
* move cli.py to examples, add short usage into README.md
* Implement more available APIs, refactor querying code.
This commit adds access to new properties, both read & write, while keeping the old one (mostly) intact.
Querying is refactored to be done inside _query_helper() method,
which unwraps results automatically and rises SmartPlugException() in case of errors.
Errors are to be handled by clients.
New features:
* Setting device alias (plug.alias = "name")
* led read & write
* icon read (doesn't seem to return anything without cloud support at least), write API is not known, throws an exception currently
* time read (returns datetime), time write implemented, but not working even when no error is returned from the device
* timezone read
* mac read & write, writing is untested for now.
Properties for easier access:
* hw_info: return hw-specific elements from sysinfo
* on_since: pretty-printed from sysinfo
* location: latitude and longitued from sysinfo
* rssi: rssi from sysinfo
* Update README.md with examples of available features.
* Handle comments from mweinelt
* Refactor state handling, use booleans instead of strings
* Fix issues raised during the review.
Following issues are addressed by this commit:
* All API is more or less commented (including return types, exceptions, ..)
* Converted state to use
* Added properties is_on, is_off for those who don't want to check against strings.
* Handled most issues reported by pylint.
* Adjusted _query_helper() to strip off err_code from the result object.
* Fixed broken format() syntax for string formattings.
* Fix ci woes plus one typo.
* Do initialization after changing device properties, fix nits.
2016-12-12 09:13:45 +00:00
|
|
|
response = TPLinkSmartHomeProtocol.decrypt(buffer[4:])
|
|
|
|
_LOGGER.debug("< (%i) %s", len(response), response)
|
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
return json.loads(response)
|
2016-10-17 12:17:28 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
@staticmethod
|
|
|
|
def encrypt(request):
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-21 22:18:12 +00:00
|
|
|
Encrypt a request for a TP-Link Smart Home Device.
|
|
|
|
|
|
|
|
:param request: plaintext request data
|
|
|
|
:return: ciphertext request
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-22 01:31:25 +00:00
|
|
|
key = TPLinkSmartHomeProtocol.initialization_vector
|
2016-11-21 22:18:12 +00:00
|
|
|
buffer = ['\0\0\0\0']
|
2016-10-15 08:18:31 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
for char in request:
|
|
|
|
cipher = key ^ ord(char)
|
|
|
|
key = cipher
|
|
|
|
buffer.append(chr(cipher))
|
2016-10-15 08:18:31 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
ciphertext = ''.join(buffer)
|
|
|
|
if sys.version_info.major > 2:
|
|
|
|
ciphertext = ciphertext.encode('latin-1')
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
return ciphertext
|
2016-10-18 07:59:30 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
@staticmethod
|
|
|
|
def decrypt(ciphertext):
|
|
|
|
"""
|
|
|
|
Decrypt a response of a TP-Link Smart Home Device.
|
2016-10-18 07:59:30 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
:param ciphertext: encrypted response data
|
|
|
|
:return: plaintext response
|
2016-10-18 07:59:30 +00:00
|
|
|
"""
|
2016-11-22 01:31:25 +00:00
|
|
|
key = TPLinkSmartHomeProtocol.initialization_vector
|
2016-11-21 22:18:12 +00:00
|
|
|
buffer = []
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
if sys.version_info.major > 2:
|
|
|
|
ciphertext = ciphertext.decode('latin-1')
|
2016-10-13 15:31:34 +00:00
|
|
|
|
2016-11-21 22:18:12 +00:00
|
|
|
for char in ciphertext:
|
|
|
|
plain = key ^ ord(char)
|
|
|
|
key = ord(char)
|
|
|
|
buffer.append(chr(plain))
|
|
|
|
|
|
|
|
plaintext = ''.join(buffer)
|
|
|
|
|
|
|
|
return plaintext
|