1. 4FIPS
  2. PHOTOS
  3. VIDEOS
  4. CODE
  5. FORUMS
  6. ABOUT

4FipS.com Forums

Forums dedicated to the projects hosted at 4FipS.com

Skip to content

Controlling the TP-Link HS110 smart plug with Domoticz

> About coding, hacking, photography, and such...

Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Sun Oct 01, 2017 9:04 pm

Although there are plenty of smart plugs currently available on the market, my choice was, as usual, hugely constrained by the requirement of maximum hackability of such a device. So I've decided to pick up the TP-Link HS110 smart plug, mainly because of this article: Reverse Engineering the TP-Link HS110, which describes many aspects of the plug in great detail, and also shows how to operate the plug using just a simple Python script (tplink-smartplug.py), so the integration with the home automation system of your choice (Domoticz in my case) is going be pretty straightforward.

Image

First thing you should do is to reserve an IP address for your smart plug on your router. For this, you'll need plug's MAC address, which is written on the backside of the device (alternatively you can figure out the MAC address inside the companion Kasa application).

Then you can use tplink-smartplug.py to turn on/off the plug simply like so:
Code: Select all
python ./tplink-smartplug.py -t <IP> -c on

which gives the below response:
Code: Select all
Sent:      {"system":{"set_relay_state":{"state":1}}}
Received:  {"system":{"set_relay_state":{"err_code":0}}}

You can also read the real-time power consumption info via (HS110 only):
Code: Select all
python ./tplink-smartplug.py -t <IP> -j '{"emeter":{"get_realtime":{}}}'

which gives:
Code: Select all
Sent:      {"emeter":{"get_realtime":{}}}
Received:  {"emeter":{"get_realtime":{"current":0.041124,"voltage":237.504900,"power":9.341753,"total":0.001000,"err_code":0}}}

The nice thing about this plug is that it is operated simply via sending JSON requests, so it can be easily commanded and queried for various information. For example, I'm going to use the above real-time power consumption info for monitoring when my washing machine finishes its job (I'll keep this for next time though).

The final step is to integrate the plug with Domoticz (in my case running on a Raspberry Pi). For this you will need to copy the control script into '~/domoticz/scripts/' and make it executable. This can be achieved via:

Code: Select all
cp ./tplink-smartplug.py ~/domoticz/scripts/
sudo chmod +x ~/domoticz/scripts/tplink-smartplug.py

Then you can open Domoticz in your web browser, go to "Setup/Hardware" and add a new virtual hardware of the "Dummy" type. After that click on "Create Virtual Sensors" of the newly created virtual hardware, the bellow popup will appear:

Image

Name the newly created sensor, and select "Switch" as its type. After that you will need to edit the switch and add the on/off actions:

Code: Select all
script:///home/pi/domoticz/scripts/tplink-smartplug.py -t <IP> -c on
script:///home/pi/domoticz/scripts/tplink-smartplug.py -t <IP> -c off

Image

That's it! Your switch is now ready.

Related articles:
Home automation with Domoticz, ESP8266 and BME280
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Controlling the TP-Link HS110 smart plug with Domoticz

Sponsor

Sponsor
 

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Wed Apr 04, 2018 8:44 pm

Hello,
how to get info on consumption in domoticz? because I've been on it for 3 days and no tutorial works correctly even by hacking the code while I get the consumer information when I type "{"emeter":{"get_realtime":{}}}"
thanks
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Wed Apr 04, 2018 9:59 pm

Hi,

Unfortunately, I haven't tried to propagate the consumption info from HS110 into Domoticz yet, although it's on my list for some time. However looking at this thread it seems it shouldn't be that difficult (there's even a Python script included). A small annoyance is that Demoticz is unable to query HS110 consumption info directly, so as a workaround it is necessary to setup a script that is scheduled to run periodically either by itself or by the operating system, lets say every minute. The script queries the HS110 state and parses the resulting JSON in order to extract the consumption info (that's basically what tplink-smartplug.py does), the consumption info is then inserted into another HTTP request and sent to Domoticz, which updates the virtual sensor of the type 'Electric (Instant+Counter)'.

Hope it helps.

(I might look into this later when I find some spare time. I'll definitely update this thread if there's any progress).
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Thu Apr 05, 2018 3:59 pm

Thank you for answering me so quickly.
So I'll explain everything I did and you can tell me if I made a mistake but I followed this tutorial.
I created the virtual button as below:
[img]
https://www.dropbox.com/s/m2sdtfmtj2i0r ... e.PNG?dl=0
[/img]

I created a file called "test.py" and I copied it to him:

Code: Select all
#!/usr/bin/env python
#
# TP-Link Wi-Fi Smart Plug Protocol Client
# For use with TP-Link HS110: energy monitor
#
# Gets current power (W) and cumulative energy (kWh)
# and sends to Domoticz

import socket
import argparse
import json
import urllib
import urllib2

# ip, port, and command for HS110
ip = '192.168.1.29'
port = 9999
cmd = '{"emeter":{"get_realtime":{}}}'

# Domoticz command stub and IDx of HS110
baseURL = 'http://192.168.1.24:8080/json.htm?type=command&param=udevice&nvalue=0'
HSIdx = 28

# Encryption and Decryption of TP-Link Smart Home Protocol
# XOR Autokey Cipher with starting key = 171
def encrypt(string):
   key = 171
   result = "\0\0\0\0"
   for i in string:
      a = key ^ ord(i)
      key = a
      result += chr(a)
   return result

def decrypt(string):
   key = 171
   result = ""
   for i in string:
      a = key ^ ord(i)
      key = ord(i)
      result += chr(a)
   return result

def domoticzrequest (url):
   request = urllib2.Request(url)
#   request.add_header("Authorization", "Basic %s" % base64string)
   response = urllib2.urlopen(request)
   return None;

# Send command and receive reply
try:
   sock_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   sock_tcp.connect((ip, port))
   sock_tcp.send(encrypt(cmd))
   data = sock_tcp.recv(2048)
   sock_tcp.close()
   
#   print "Sent:     ", cmd
   result = decrypt(data[4:])
   jsonData = json.loads(result)
#   print "Received: "
#   print json.dumps(jsonData, indent=4, sort_keys=True)
   power = jsonData['emeter']['get_realtime']['power']
   total = jsonData['emeter']['get_realtime']['total'] * 1000
#   print power, total
except socket.error:
   quit("Cound not connect to host " + ip + ":" + str(port))

# Send data to Domoticz
try:
    url = baseURL + "&idx=%s&svalue=%s;%s" % (HSIdx, power, total)
    domoticzrequest(url)
except urllib2.URLError, e:
   print e.code


so I replaced the ip address of the plug with the associated port 9999 and I changed the ip address of my domoticz with the associated port 8080.

After I did:
Code: Select all
crontab -e
*/5**** sudo python /home/pi/domoticz/scripts/python/test.py >/dev/null 2>&1


I do not see where I made the mistake. Thank you for giving me feedback on what you thought.
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Thu Apr 05, 2018 10:43 pm

I went through your steps quickly and it looks good to me. I would try to run the script directly (without crontab) to see if it produces any error (you can also uncomment the print statements to see how the script progresses).
Code: Select all
python /home/pi/domoticz/scripts/python/test.py

If there are no errors it means Domoticz has received the HTTP request and it should show current consumption info or print an error to the log.
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Fri Apr 06, 2018 2:13 pm

Thank you for watching. I had already done this command because I searched a lot before asking for help and I get this error:
Code: Select all
Traceback (most recent call last):
  File "/home/pi/domoticz/scripts/python/test.py", line 74, in <module>   
    print e.code
AttributeError: 'URLError' object has no attribute 'code'

And here I admit that I'm blocking.
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Fri Apr 06, 2018 3:02 pm

Try to replace this:
Code: Select all
except urllib2.URLError, e:
   print e.code

With this:
Code: Select all
except urllib2.HTTPError, e:
    print e.code
except urllib2.URLError, e:
    print e.args

This should give better info about the error.

(I'm going to try your script over the weekend...)
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Fri Apr 06, 2018 5:08 pm

I get:
Code: Select all
(error(110, 'connection timed out') ,)



I am nevertheless some of my addresses because the switch via domoticz works.
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Fri Apr 06, 2018 8:34 pm

I believe you are very close to success. There seems to be a networking problem when sending data to Domoticz ('connection timed out' is quite strange on a local network, I would try to run the script a couple of times to see if the problem persists).

I have tested your script (with changed IPs, ports, device index, and uncommented print) and it seems to work fine for me, it prints:
Code: Select all
Sent:      {"emeter":{"get_realtime":{}}}
Received:
{
    "emeter": {
        "get_realtime": {
            "current": 0.050626,
            "err_code": 0,
            "power": 5.156992,
            "total": 47.638,
            "voltage": 239.229237
        }
    }
}
5.156992 47638.0

and the information is successfully passed to Domoticz:
Image
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Mon Apr 09, 2018 3:17 pm

I tried to leave that code and at the execution of
Code: Select all
python /home/pi/domoticz/scripts/python/test.py


I have an error 401. I am short of idea but thanks for the help
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby FipS on Tue Apr 10, 2018 9:21 pm

HTTP Error 401 means UNAUTHORIZED, which is strange if you are running locally...

As a last resort, try to paste this url to your web browser:

Code: Select all
http://192.168.1.24:8080/json.htm?type=command&param=udevice&nvalue=0&idx=28&svalue=123;456

(double check '192.168.1.24:8080' and idx=28 are the correct values for your configuration)

This should send the data directly to Domoticz and update the electricity panel, the web browser should print out this:

Code: Select all
{
   "status" : "OK",
   "title" : "Update Device"
}

If this does not work than the problem is not in the script but rather in your network or Domoticz configuration.
User avatar
FipS
Site Admin
 
Posts: 156
Joined: Wed Nov 12, 2008 9:49 pm
Location: Prague

Re: Controlling the TP-Link HS110 smart plug with Domoticz

Postby Flo00719 on Wed Apr 11, 2018 8:24 pm

Hello, thank you for continuing to help me :) actually I had the:
Code: Select all
{
   "status" : "OK",
   "title" : "Update Device"
}


And domoticz it is well updated
I do not see where the error is in the script
Flo00719
 
Posts: 6
Joined: Wed Apr 04, 2018 7:34 pm


Return to 4FipS.com General Discussion & Blog

Who is online

Users browsing this forum: No registered users and 12 guests