mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-22 19:23:34 +00:00
Release 0.3.0 (#88)
* update the changelog * revise README, fixes #86 * bump the version * final changelog update for 0.3.0
This commit is contained in:
parent
44424c1182
commit
b80923061f
150
CHANGELOG
150
CHANGELOG
@ -1,6 +1,156 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
0.3.0 (2017-09-14)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
This is the first release after a while and aims to improve the robustness all-around.
|
||||||
|
To make this happen we have decided to break the API and drop the support for Python 2.
|
||||||
|
|
||||||
|
API break:
|
||||||
|
* Python2 support has been dropped.
|
||||||
|
* pyHS100/pyHS100.py has been splitted to smartdevice.py, smartplug.py and smartbulb.py, no one should have ever accessed these directly though.
|
||||||
|
* SmartPlugException is no more, SmartDeviceException is used by both SmartPlug and SmartBulb
|
||||||
|
* Discovery has been moved from TPLinkSmartHomeProtocol into its own class for easier 3rd party use.
|
||||||
|
* SmartDevice's identify() and `features` will emit a warning when used. These will likely be dropped or revised in the future and their use should be avoided.
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
|
||||||
|
* CLI tool supports device discovery and is usable without specifying device type or IP for testing
|
||||||
|
* CLI tool supports changing bulb-specific settings
|
||||||
|
* Library support & unit tests are extended to cover more devices.
|
||||||
|
- Supported plugs: HS100, HS105, HS110
|
||||||
|
- Supported switches: HS200
|
||||||
|
- Supported bulbs: LB100, LB110, LB120, LB130
|
||||||
|
|
||||||
|
- Bump the version. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Revise README, fixes #86. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Update the changelog. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Local test clean (#96) [Sean Gollschewsky]
|
||||||
|
|
||||||
|
* Add ignores for working coverage/tox/IDE files.
|
||||||
|
|
||||||
|
* Allow tox not to fail if python version is not available.
|
||||||
|
|
||||||
|
- Move SmartDeviceException to SmartDevice, and remove types.py complet…
|
||||||
|
(#95) [Teemu R]
|
||||||
|
|
||||||
|
* move SmartDeviceException to SmartDevice, and remove types.py completely. fixes #94
|
||||||
|
|
||||||
|
* do not import skipIf anymore
|
||||||
|
|
||||||
|
- Move has_emeter implementation from SmartDevice to SmartPlug, avoid
|
||||||
|
using features() internally (#93) [Teemu R]
|
||||||
|
|
||||||
|
* move has_emeter implementation from SmartDevice to SmartPlug, avoid using features() internally
|
||||||
|
|
||||||
|
* add stacklevel to deprecation warnings to see where they are really called
|
||||||
|
|
||||||
|
* make tests pass on a real device. if PLUG_IP is not None, the tests will be run on a device at the defined IP address
|
||||||
|
|
||||||
|
- Add typing hints to make it easier for 3rd party developers to use the
|
||||||
|
library (#90) [Teemu R]
|
||||||
|
|
||||||
|
* add typing hints to make it easier for 3rd party developers to use the library
|
||||||
|
|
||||||
|
* remove unused devicetype enum to support python3.3
|
||||||
|
|
||||||
|
* add python 3.3 to travis and tox, install typing module in setup.py
|
||||||
|
- Execute coveralls only on travis, fixes #84 (#91) [Teemu R]
|
||||||
|
|
||||||
|
- Make flake8 pass by some rewording. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Make hound a bit more happier. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Deprecate features and identify, use state_information in __repr__ instead of identify. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Fix smartbulb hsv documentation, values are degrees and percentages instead of 0-255. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Another try, just with module name. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Make tox run pytest-cov, add coveralls. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Prevent failure if device's sysinfo does not have a "feature" attribute. (#77) [Sean Gollschewsky]
|
||||||
|
|
||||||
|
- Allow None for rssi, add a missing newline to fakes.py. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Add hs100 tests. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Make tests to test against all known device variants. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Remove unused tplinksmarthomeprotocol import. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Fix hs105 mac to pass the test, wrap sysinfo_lb110 properly inside 'system' [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Return None instead of False for emeter related actions. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Wrap sysinfo to defaultdict to return None for keys which do not exist, makes unsupported keys not to fail hard (#72) [Teemu R]
|
||||||
|
|
||||||
|
- Add hs100 example to fakes.py, thanks to Semant1ka on #67 (#74) [Teemu R]
|
||||||
|
|
||||||
|
- Discover refactoring, enhancements to the cli tool (#71) [Teemu R]
|
||||||
|
|
||||||
|
* Discover refactoring, enhancements to the cli tool
|
||||||
|
|
||||||
|
* Discover tries to detect the type of the device from sysinfo response
|
||||||
|
* Discover.discover() returns an IP address keyed dictionary,
|
||||||
|
values are initialized instances of the automatically detected device type.
|
||||||
|
|
||||||
|
* When no IP is given, autodetect all supported devices and print out their states
|
||||||
|
* When only IP but no type is given, autodetect type and make a call based on that information.
|
||||||
|
* One can define --bulb or --plug to skip the detection.
|
||||||
|
|
||||||
|
* renamed pyHS100.py -> smartdevice.py
|
||||||
|
|
||||||
|
* SmartPlugException -> SmartDeviceException in comments
|
||||||
|
|
||||||
|
* fix mic_type check
|
||||||
|
|
||||||
|
* make time() return None on failure as we don't know which devices support getting the time and it's used in the cli tool
|
||||||
|
|
||||||
|
* hw_info: check if key exists before accessing it, add mic_mac and mic_type
|
||||||
|
|
||||||
|
* Check for mic_mac on mac, based on work by kdschloesser on issue #59
|
||||||
|
|
||||||
|
* make hound happy, __init__ on SmartDevice cannot error out so removing 'raises' documentation
|
||||||
|
|
||||||
|
- Add LB110 sysinfo (#75) [Sean Gollschewsky]
|
||||||
|
|
||||||
|
* Add LB110 sysinfo
|
||||||
|
|
||||||
|
* Linting.
|
||||||
|
|
||||||
|
- Add @pass_dev to hsv, adjust ranges (#70) [Teemu R]
|
||||||
|
|
||||||
|
* add @pass_dev to hsv command, it was always broken
|
||||||
|
|
||||||
|
* Hue goes up to 360, saturation and value are up to 100(%)
|
||||||
|
|
||||||
|
- Extract shared types (exceptions, enums), add module level doc, rename exception to be generic. [Teemu Rytilahti]
|
||||||
|
|
||||||
|
- Add check to ensure devices with lat/lon with `_i` suffix are supported (#54) (#56) [Matt LeBrun]
|
||||||
|
|
||||||
|
* Add check to ensure devices with lat/lon with `_i` suffix are supported (#54)
|
||||||
|
|
||||||
|
* Add .gitignore for posterity
|
||||||
|
|
||||||
|
- Generalize smartdevice class and add bulb support for the cli tool (#50) [Teemu R]
|
||||||
|
|
||||||
|
Fixes #48 and #51. The basic functionality should work on all types of supported devices, for bulb specific commands it is currently necessary to specify ```--bulb```.
|
||||||
|
|
||||||
|
- Refactor and drop py2 support (#49) [Teemu R]
|
||||||
|
|
||||||
|
* move is_off property to SmartDevice, implement is_on for bulb and use it
|
||||||
|
|
||||||
|
* refactor by moving smartbulb and smartplug to their own classes
|
||||||
|
|
||||||
|
* drop python2 compatibility, make flake8 happy
|
||||||
|
|
||||||
|
* travis: remove 2.7, add 3.6
|
||||||
|
|
||||||
0.2.4.2 (2017-04-08)
|
0.2.4.2 (2017-04-08)
|
||||||
--------------------
|
--------------------
|
||||||
- Add installation requirement for future package. [Teemu Rytilahti]
|
- Add installation requirement for future package. [Teemu Rytilahti]
|
||||||
|
199
README.md
199
README.md
@ -1,55 +1,157 @@
|
|||||||
# pyHS100
|
# pyHS100
|
||||||
|
|
||||||
Python Library to control TPLink smart plugs (HS100, HS105, HS110, HS200) and TPLink smart bulbs (LB1xx).
|
[![PyPI version](https://badge.fury.io/py/pyHS100.svg)](https://badge.fury.io/py/pyHS100)
|
||||||
|
[![Build Status](https://travis-ci.org/GadgetReactor/pyHS100.svg?branch=master)](https://travis-ci.org/GadgetReactor/pyHS100)
|
||||||
|
[![Coverage Status](https://coveralls.io/repos/github/GadgetReactor/pyHS100/badge.svg?branch=master)](https://coveralls.io/github/GadgetReactor/pyHS100?branch=master)
|
||||||
|
|
||||||
|
Python Library to control TPLink smart plugs/switches and smart bulbs.
|
||||||
|
|
||||||
|
**Supported devices**
|
||||||
|
|
||||||
|
* Plugs
|
||||||
|
* HS100
|
||||||
|
* HS105
|
||||||
|
* HS110
|
||||||
|
* Wall switches
|
||||||
|
* HS200
|
||||||
|
* Bulbs
|
||||||
|
* LB100
|
||||||
|
* LB110
|
||||||
|
* LB120
|
||||||
|
* LB130
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
The package is shipped with a console tool named pyhs100, please refer to ```pyhs100 --help``` for detailed usage.
|
The package is shipped with a console tool named pyhs100, please refer to ```pyhs100 --help``` for detailed usage.
|
||||||
<b>Note: The tool does not currently support bulb-specific commands, please feel free to prepare a pull request!</b>
|
The device to which the commands are sent is chosen by `PYHS100_IP` environment variable or passing `--ip <address>` as an option.
|
||||||
|
To see what is being sent to and received from the device, specify option `--debug`.
|
||||||
|
|
||||||
|
To avoid discovering the devices when executing commands its type can be passed by specifying either `--plug` or `--bulb`,
|
||||||
|
if no type is given its type will be discovered automatically with a small delay.
|
||||||
|
Some commands (such as reading energy meter values and setting color of bulbs) additional parameters are required,
|
||||||
|
which you can find by adding `--help` after the command, e.g. `pyhs100 emeter --help` or `pyhs100 hsv --help`.
|
||||||
|
|
||||||
|
If no command is given, the `state` command will be executed to query the device state.
|
||||||
|
|
||||||
|
|
||||||
## Discovering devices
|
## Discovering devices
|
||||||
|
|
||||||
```
|
The devices can be discovered either by using `pyhs100 discover` or by calling `pyhs100` without any parameters.
|
||||||
$ pyhs100 discover
|
In both cases supported devices are discovered from the same broadcast domain, and their current state will be queried and printed out.
|
||||||
|
|
||||||
Discovering devices for 5 seconds
|
|
||||||
Found device: {'ip': '192.168.250.186',
|
|
||||||
'port': 9999,
|
|
||||||
'sys_info': {'emeter': {'get_realtime': {'current': 0.013309,
|
|
||||||
<snip>
|
|
||||||
```
|
```
|
||||||
|
$ pyhs100
|
||||||
## Querying the state
|
No --bulb nor --plug given, discovering..
|
||||||
```
|
Discovering devices for 3 seconds
|
||||||
$ pyhs100 --ip 192.168.250.186
|
|
||||||
|
|
||||||
== My Smart Plug - HS110(EU) ==
|
== My Smart Plug - HS110(EU) ==
|
||||||
Device state: OFF
|
Device state: ON
|
||||||
LED state: False
|
IP address: 192.168.x.x
|
||||||
Time: 1970-01-01 01:52:35
|
LED state: False
|
||||||
On since: 2017-03-19 17:09:16.408657
|
On since: 2017-03-26 18:29:17.242219
|
||||||
|
== Generic information ==
|
||||||
|
Time: 1970-06-22 02:39:41
|
||||||
Hardware: 1.0
|
Hardware: 1.0
|
||||||
Software: 1.0.8 Build 151101 Rel.24452
|
Software: 1.0.8 Build 151101 Rel.24452
|
||||||
MAC (rssi): 50:C7:BF:XX:XX:XX (-61)
|
MAC (rssi): 50:C7:BF:XX:XX:XX (-77)
|
||||||
Location: {'longitude': XXXX, 'latitude': XXXX}
|
Location: {'latitude': XXXX, 'longitude': XXXX}
|
||||||
== Emeter ==
|
== Emeter ==
|
||||||
Current state: {'power': 0, 'total': 0.001, 'current': 0.013552, 'voltage': 223.394238}
|
Current state: {'total': 133.082, 'power': 100.418681, 'current': 0.510967, 'voltage': 225.600477}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Basic controls
|
||||||
|
|
||||||
|
All devices support a variety of common commands, including:
|
||||||
|
* `state` which returns state information
|
||||||
|
* `on` and `off` for turning the device on or off
|
||||||
|
* `emeter` (where applicable) to return energy consumption information
|
||||||
|
* `sysinfo` to return raw system information which is used by e.g. `state`, useful for debugging and when adding support for new device types
|
||||||
|
|
||||||
|
## Energy meter
|
||||||
|
|
||||||
|
Passing no options to `emeter` command will return the current consumption.
|
||||||
|
Possible options include `--year` and `--month` for retrieving historical state,
|
||||||
|
and reseting the counters is done with `--erase`.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pyhs100 emeter
|
||||||
|
== Emeter ==
|
||||||
|
Current state: {'total': 133.105, 'power': 108.223577, 'current': 0.54463, 'voltage': 225.296283}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plug-specific commands
|
||||||
|
|
||||||
|
At the moment only switching the state of the LED is implemented.
|
||||||
|
**Feel free to submit patches as pull requests for further features!**
|
||||||
|
### Controlling the LED
|
||||||
|
|
||||||
|
`led` command can be used to control whether the LED light on front of the plug is on or off.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ pyhs100 --plug led
|
||||||
|
LED state: False
|
||||||
|
$ pyhs100 --plug led 1
|
||||||
|
Turning led to True
|
||||||
|
```
|
||||||
|
|
||||||
|
## Bulb-specific commands
|
||||||
|
|
||||||
|
At the moment setting brightness, color temperature and color (in HSV) is supported.
|
||||||
|
The commands are straightforward, so feel free to check `--help` for instructions how to use them.
|
||||||
|
|
||||||
|
**Feel free to submit patches as pull requests to add more functionality (e.g. scenes)!**
|
||||||
|
|
||||||
# Library usage
|
# Library usage
|
||||||
|
|
||||||
|
The public API is well documented, but here are some examples to get you started.
|
||||||
For all available API functions run ```help(SmartPlug)``` or ```help(SmartBulb)```.
|
For all available API functions run ```help(SmartPlug)``` or ```help(SmartBulb)```.
|
||||||
|
|
||||||
|
## Discovering devices
|
||||||
|
|
||||||
|
`Discover` class' `discover()` can be used to discover supported devices,
|
||||||
|
which returns a dictionary keyed with the IP address whose value hold a ready-to-use instance of the detected device type.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```python
|
||||||
|
from pyHS100 import Discover
|
||||||
|
|
||||||
|
for dev in Discover.discover().values():
|
||||||
|
print(dev)
|
||||||
|
```
|
||||||
|
```
|
||||||
|
$ python3 example.py
|
||||||
|
<SmartPlug at 192.168.XXX.XXX (My Smart Plug), is_on: True - dev specific: {'LED state': True, 'On since': datetime.datetime(2017, 3, 26, 18, 29, 17, 52073)}>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Querying basic information
|
||||||
|
|
||||||
|
*Please note that most property getters do I/O (e.g. fetching the system information) on each call.
|
||||||
|
If you want to avoid unnecessary communication with the device please use `get_sysinfo` and handle parsing of information by yourself.*
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from pyHS100 import SmartPlug, SmartBulb
|
from pyHS100 import SmartPlug, SmartBulb
|
||||||
from pprint import pformat as pf
|
from pprint import pformat as pf
|
||||||
|
|
||||||
plug = SmartPlug("192.168.250.186")
|
plug = SmartPlug("192.168.XXX.XXX")
|
||||||
print("Alias, type and supported features: %s" % (plug.identify(),))
|
|
||||||
print("Hardware: %s" % pf(plug.hw_info))
|
print("Hardware: %s" % pf(plug.hw_info))
|
||||||
print("Full sysinfo: %s" % pf(plug.get_sysinfo())) # this prints lots of information about the device
|
print("Full sysinfo: %s" % pf(plug.get_sysinfo())) # this prints lots of information about the device
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## State & switching
|
||||||
|
|
||||||
|
Devices can be turned on and off by either calling appropriate methods on the device object,
|
||||||
|
or by assigning a new state to `state` property.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print("Current state: %s" % plug.state)
|
||||||
|
plug.turn_off()
|
||||||
|
plug.turn_on()
|
||||||
|
```
|
||||||
|
|
||||||
|
```python
|
||||||
|
plug.state = "ON"
|
||||||
|
plug.state = "OFF"
|
||||||
|
```
|
||||||
|
|
||||||
## Time information
|
## Time information
|
||||||
```python
|
```python
|
||||||
print("Current time: %s" % plug.time)
|
print("Current time: %s" % plug.time)
|
||||||
@ -62,29 +164,50 @@ print("Alias: %s" % plug.alias)
|
|||||||
plug.alias = "My New Smartplug"
|
plug.alias = "My New Smartplug"
|
||||||
```
|
```
|
||||||
|
|
||||||
## State & switching
|
## Getting emeter status (if applicable)
|
||||||
```python
|
|
||||||
print("Current state: %s" % plug.state)
|
|
||||||
plug.turn_off()
|
|
||||||
plug.turn_on()
|
|
||||||
```
|
|
||||||
or
|
|
||||||
```python
|
|
||||||
plug.state = "ON"
|
|
||||||
plug.state = "OFF"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Getting emeter status (on HS110)
|
|
||||||
```python
|
```python
|
||||||
print("Current consumption: %s" % plug.get_emeter_realtime())
|
print("Current consumption: %s" % plug.get_emeter_realtime())
|
||||||
print("Per day: %s" % plug.get_emeter_daily(year=2016, month=12))
|
print("Per day: %s" % plug.get_emeter_daily(year=2016, month=12))
|
||||||
print("Per month: %s" % plug.get_emeter_monthly(year=2016))
|
print("Per month: %s" % plug.get_emeter_monthly(year=2016))
|
||||||
```
|
```
|
||||||
|
|
||||||
## Switching the led
|
## Plug-specific
|
||||||
|
|
||||||
|
### Switching the led (plugs only)
|
||||||
```python
|
```python
|
||||||
print("Current LED state: %s" % plug.led)
|
print("Current LED state: %s" % plug.led)
|
||||||
plug.led = False # turn off led
|
plug.led = False # turn off led
|
||||||
print("New LED state: %s" % plug.led)
|
print("New LED state: %s" % plug.led)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Bulb-specific API
|
||||||
|
|
||||||
|
The bulb API is likewise straightforward, so please refer to its API documentation.
|
||||||
|
Information about supported features can be queried by using properties prefixed with `is_`, e.g. `is_dimmable`.
|
||||||
|
|
||||||
|
### Setting the brightness
|
||||||
|
|
||||||
|
The `brightness` property works in percentages.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(bulb.brightness)
|
||||||
|
if bulb.is_dimmable:
|
||||||
|
bulb.brightness = 100
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting the color temperature
|
||||||
|
```python
|
||||||
|
print(bulb.color_temp)
|
||||||
|
if bulb.is_variable_color_temp:
|
||||||
|
bulb.color_temp = 3000
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setting the color
|
||||||
|
|
||||||
|
Hue is given in degrees (0-360) and saturation and value in percentage.
|
||||||
|
|
||||||
|
```python
|
||||||
|
print(bulb.hsv)
|
||||||
|
if bulb.is_color:
|
||||||
|
bulb.hsv = (180, 100, 100) # set to cyan
|
||||||
|
```
|
2
setup.py
2
setup.py
@ -1,7 +1,7 @@
|
|||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
setup(name='pyHS100',
|
setup(name='pyHS100',
|
||||||
version='0.2.4.2',
|
version='0.3.0',
|
||||||
description='Interface for TPLink HS100 Smart Plugs.',
|
description='Interface for TPLink HS100 Smart Plugs.',
|
||||||
url='https://github.com/GadgetReactor/pyHS100',
|
url='https://github.com/GadgetReactor/pyHS100',
|
||||||
author='Sean Seah (GadgetReactor)',
|
author='Sean Seah (GadgetReactor)',
|
||||||
|
Loading…
Reference in New Issue
Block a user