From ce697db8e7384d14a2c8b5456876e7e3ebead7ab Mon Sep 17 00:00:00 2001 From: "jason.b.anderson" Date: Mon, 16 Jan 2017 20:35:30 -0600 Subject: [PATCH] Update and rename tplink-smartplug.py to tplink_smartplug.py --- tplink-smartplug.py | 99 --------------------------------------- tplink_smartplug.py | 111 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 99 deletions(-) delete mode 100644 tplink-smartplug.py create mode 100644 tplink_smartplug.py diff --git a/tplink-smartplug.py b/tplink-smartplug.py deleted file mode 100644 index 3a2fde8..0000000 --- a/tplink-smartplug.py +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env python -# -# 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 - -version = 0.1 - -# Check if IP is valid -def validIP(ip): - try: - socket.inet_pton(socket.AF_INET, ip) - except socket.error: - parser.error("Invalid IP Address.") - return ip - -# 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}}}' -} - -# 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 - -# Parse commandline arguments -parser = argparse.ArgumentParser(description="TP-Link Wi-Fi Smart Plug Client v" + str(version)) -parser.add_argument("-t", "--target", metavar="", required=True, help="Target IP Address", type=validIP) -group = parser.add_mutually_exclusive_group(required=True) -group.add_argument("-c", "--command", metavar="", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands) -group.add_argument("-j", "--json", metavar="", 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)) diff --git a/tplink_smartplug.py b/tplink_smartplug.py new file mode 100644 index 0000000..18be326 --- /dev/null +++ b/tplink_smartplug.py @@ -0,0 +1,111 @@ +#!/usr/bin/env python +# +# 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 + +version = 0.2 + +def validIP(ip): + try: + socket.inet_pton(socket.AF_INET, ip) + except socket.error: + parser.error("Invalid IP Address.") + return ip + +def get_commands(): + # Predefined Smart Plug Commands + # For a full list of commands, consult tplink_commands.txt + return {'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}}}' + } + +# 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 tplink_smartplug(cmd,ip,port=9999,mode='command'): + import socket + + if mode == 'command': + commands = get_commands() + cmd = commands[cmd] + else: + cmd = cmd + + # 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() + + except socket.error: + quit("Cound not connect to host " + ip + ":" + str(port)) + + + +if __name__ == '__main__': + + commands=get_commands() + + parser = argparse.ArgumentParser(description="TP-Link Wi-Fi Smart Plug Client v" + str(version)) + parser.add_argument("-t", "--target", metavar="", required=True, help="Target IP Address", type=validIP) + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("-c", "--command", metavar="", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands) + group.add_argument("-j", "--json", metavar="", 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 + tplink_smartplug(cmd,ip,port=port,mode='json') + else: + cmd = args.command + tplink_smartplug(cmd,ip,port=port,mode='command')