MikeF wrote: ↑Monday 03 October 2016 11:58
I have now created a python script to send energy data from the TP-Link HS110 Smart Plug to Domoticz:
- Spoiler: show
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 = '<IP of HS110>'
port = 9999
cmd = '{"emeter":{"get_realtime":{}}}'
# Domoticz command stub and IDx of HS110
baseURL = 'http://<Domoticz IP:port>/json.htm?type=command¶m=udevice&nvalue=0'
HSIdx = <Domoticz IDx of HS110>
# 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
Create a virtual sensor with sensor type 'Electric (Instant+Counter)', and insert its IDx and the IP addresses of your HS110 and Domoticz server in the script. Then set up a crontab entry to run the script every 5 or 10 minutes, as you prefer.
It will appear in the Utilities page - here's an example:
Can't get it to work. When I run ./tplink-smartplug-energy.py, I get the following back:
Traceback (most recent call last):
File "./tplink-smartplug-energy.py", line 72, in <module>
domoticzrequest(url)
File "./tplink-smartplug-energy.py", line 47, in domoticzrequest
response = urllib2.urlopen(request)
File "/usr/lib/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 429, in open
response = self._open(req, data)
File "/usr/lib/python2.7/urllib2.py", line 447, in _open
'_open', req)
File "/usr/lib/python2.7/urllib2.py", line 407, in _call_chain
result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 1228, in http_open
return self.do_open(httplib.HTTPConnection, req)
File "/usr/lib/python2.7/urllib2.py", line 1167, in do_open
h = http_class(host, timeout=req.timeout, **http_conn_args)
File "/usr/lib/python2.7/httplib.py", line 736, in __init__
(self.host, self.port) = self._get_hostport(host, port)
File "/usr/lib/python2.7/httplib.py", line 777, in _get_hostport
raise InvalidURL("nonnumeric port: '%s'" % host[i+1:])
httplib.InvalidURL: nonnumeric port: 'port>'
Any help would help