Don't know if anyone has done anything with these "Smart Plugs" , but I am doing a little private project
for a Museum in Australia where it takes an hour to walk around and turn all the lights on/off.
It is a large acreage property with heritage equipment and displays.
The HS110 seems very popular in all parts of the world.
Someone has reverse engineered the software in it (it runs on Linux) to verify
the ability to withstand hacking.
That resulted in a .py script that allows you to talk to it from a PC and control all the functions.
So obviously it failed the hacking test.
https://www.softscheck.com/en/reverse-e ... ink-hs110/
Code: Select all
#!/usr/bin/env python2
#
# TP-Link Wi-Fi Smart Plug Protocol Client
# For use with TP-Link HS-100 or HS-110
#
# by Lubomir Stroetmann
# Copyright 2016 softScheck GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import socket
import argparse
from struct import pack
version = 0.2
# Check if hostname is valid
def validHostname(hostname):
try:
socket.gethostbyname(hostname)
except socket.error:
parser.error("Invalid hostname.")
return hostname
# Predefined Smart Plug Commands
# For a full list of commands, consult tplink_commands.txt
commands = {'info' : '{"system":{"get_sysinfo":{}}}',
'on' : '{"system":{"set_relay_state":{"state":1}}}',
'off' : '{"system":{"set_relay_state":{"state":0}}}',
'cloudinfo': '{"cnCloud":{"get_info":{}}}',
'wlanscan' : '{"netif":{"get_scaninfo":{"refresh":0}}}',
'time' : '{"time":{"get_time":{}}}',
'schedule' : '{"schedule":{"get_rules":{}}}',
'countdown': '{"count_down":{"get_rules":{}}}',
'antitheft': '{"anti_theft":{"get_rules":{}}}',
'reboot' : '{"system":{"reboot":{"delay":1}}}',
'reset' : '{"system":{"reset":{"delay":1}}}',
'energy' : '{"emeter":{"get_realtime":{}}}'
}
# Encryption and Decryption of TP-Link Smart Home Protocol
# XOR Autokey Cipher with starting key = 171
def encrypt(string):
key = 171
result = pack('>I', len(string))
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
# Parse commandline arguments
parser = argparse.ArgumentParser(description="TP-Link Wi-Fi Smart Plug Client v" + str(version))
parser.add_argument("-t", "--target", metavar="<hostname>", required=True, help="Target hostname or IP address", type=validHostname)
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("-c", "--command", metavar="<command>", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands)
group.add_argument("-j", "--json", metavar="<JSON string>", help="Full JSON string of command to send")
args = parser.parse_args()
# Set target IP, port and command to send
ip = args.target
port = 9999
if args.command is None:
cmd = args.json
else:
cmd = commands[args.command]
# 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
print "Received: ", decrypt(data[4:])
except socket.error:
quit("Cound not connect to host " + ip + ":" + str(port))
and it can still be controlled from a Wifi network. I have tested that.
I am interested in writing a small program that the Museum staff can use to control the lights,
so that it is not a number of people with the "Kasa" app on their phone doing conflicting functions.
Initially I looked at Joshy's SNC but I am not knowledgeable enough on the Ethernet & Wifi differences to convert that.
The other option is to call the script from a shell , but really don't like that.
Because I have never used python, the conversion of the script is beyond me, unless I get some good pointers.
The script itself does not look to complex, but the syntax gets me befuddled.
Additionally the functions it calls may not be available to a FB program or have to be called in a different way.
Using sncSmallNetworkPrinter seems the easiest to try out, but
the command for turning On is {"system":{"set_relay_state":{"state":0}}}
and putting that in Quotes wont compile. Additionally the command has to be encrypted with Key=171
and I don’t understand the syntax of that section either.
Have tried putting that in different format where it will compile, but the HS110 does not respond.
Also I will have to check the License before I proceed with this.
Any Suggestions ??
Regards