Skip to content
TP-Link HS1xx smart plug API wrapper.
Branch: master
Clone or download
Pull request Compare This branch is even with vrachieru:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Version Version
TP-Link HS1xx smart plug API wrapper

About TP-Link SmartPlug

  • TP-Link Smart Plugs are power plugs that can be turned on and off remotely via an app
  • Can be operated either via cloud or lan
  • Offer energy monitoring and scheduling capabilities


  • Configure device
  • Query device information
  • Change plug state


$ pip3 install git+


$ git clone
$ pip3 install ./tplink-smartplug-api


Reading device information

from tplink_smartplug import SmartPlug

plug = SmartPlug('')

print('Name:      %s' %
print('Model:     %s' % plug.model)
print('Mac:       %s' % plug.mac)
print('Time:      %s' % plug.time)

print('Is on:     %s' % plug.is_on)
print('Nightmode: %s' % (not plug.led))
print('RSSI:      %s' % plug.rssi)
$ python3
Name:      Livingroom Floor Lamps
Model:     HS100(EU)
Mac:       50:C7:XX:XX:XX:XX
Time:      2018-11-06 14:14:00

Is on:     True
Nightmode: False
RSSI:      -59

Change state

from tplink_smartplug import SmartPlug

plug = SmartPlug('')

if plug.is_on:
    print('Plug turned off')
    print('Plug turned on')
$ python3
Plug turned off

$ python3
Plug turned on


A python client for the proprietary TP-Link Smart Home protocol to control TP-Link HS100 and HS110 WiFi Smart Plugs.
The SmartHome protocol runs on TCP port 9999 and uses a trivial XOR autokey encryption that provides no security.

The initial key (initialization vector) has a hardcoded value of -85 (= 171).
The first byte of the plaintext is XORed with the key. The key is then set to the plaintext byte.
During the next iteration, the next plaintext byte is XORed with the previous plaintext byte.

Decryption works the same, with the keystream made out of cyphertext bytes.
This is known as an autokey cipher and while it has better statistical properties than simple XOR encryption with a repeating key, it can be easily broken by known plaintext attacks.

There is no authentication mechanism and commands are accepted independent of device state (configured/unconfigured).

Commands are formatted using JSON, for example:

    "system": { 
        "get_sysinfo": {} 

Commands can be nested, for example:

    "system": {
        "get_sysinfo": {}
    "time": {
        "get_time": {}





You can’t perform that action at this time.