Click here to Skip to main content
15,881,588 members
Articles / Desktop Programming / WPF
Tip/Trick

How to Control TP-Link Smart Plug HS1XX

Rate me:
Please Sign up or sign in to vote.
5.00/5 (18 votes)
27 Dec 2017GPL33 min read 63.2K   3.6K   22   46
How to control TP-Link Smart Plug (HS100 or HS110) with C#

What is TP-Link Smart Plug?

The TP-Link Smart Plug (HS100 or HS110) is a cheap home device that allows you to remotely control the power state of your devices.

This company provides two applications to control the smart plug, for Android and IOS, but not for Windows. That's the reason I made my own library.

Important note: It works only with Wi-Fi at 2.4 GHz.

Image 1

For more information, visit TP-Link Smart Plug HS110.

Introduction

In this article, I want to show how to control this device, using the Microsoft .NET Framework and WPF.

After the device configuration to connect it to our network (I won't explain how because it isn't necessary for this article), we will be able to connect to the smart plug using the port 9999 and the TCP/IP protocol (also using UDP, but I only use this one to discover all connected devices)

Image 2

Image 3

The commands used to communicate are simply encrypted JSON commands.

Encrypt and Decrypt Command Messages

The first byte of the plaintext is XORed with the key (0xAB), and later, the key is set to the plaintext byte. During the next iteration, the next plaintext byte is XORed with the previous plaintext byte. The decryption is the same, with the keystream made out of cyphertext bytes.

Note: In TCP communications, the first 4 bytes of the raw json message must be 0x00, and for decrypt the received message, we should discard the first 4 bytes.

Encryption Method

C#
internal static byte[] EncryptMessage(byte[] pMessage, ProtocolType pProtocolType)
{
    List<byte> mBuffer = new List<byte>();
    int key = 0xAB;

    if ((pMessage != null) && (pMessage.Length > 0))
    {
        //Añadimos el prefijo del mensaje
		if (pProtocolType == ProtocolType.TCP)
		{
			mBuffer.Add(0x00);
			mBuffer.Add(0x00);
			mBuffer.Add(0x00);
			mBuffer.Add(0x00);
		}

		//Codificamos el mensaje
		for (int i = 0; i < pMessage.Length; i++)
        {
            byte b = (byte)(key ^ pMessage[i]);
            key = b;
            mBuffer.Add(b);
        }
    }

    return mBuffer.ToArray();
}

Decryption Method

C#
internal static byte[] DecryptMessage(byte[] pMessage, ProtocolType pProtocolType)
{
    List<byte> mBuffer = new List<byte>();
    int key = 0xAB;

	//Skip the first 4 bytes in TCP communications (4 bytes header)
	byte header = (pProtocolType == ProtocolType.UDP) ? (byte)0x00 : (byte)0x04;

    if ((pMessage != null) && (pMessage.Length > 0))
    {
        for (int i = header; i < pMessage.Length; i++)
        {
            byte b = (byte)(key ^ pMessage[i]);
            key = pMessage[i];
            mBuffer.Add(b);
        }
    }

    return mBuffer.ToArray();
}

Inside the Library

The library that I made, at this moment, only supports the following functions:

  1. Recover the smart plug info (States, Hardware ID, Software ID, ...)
  2. Can switch the led state (On/Off)
  3. Can switch the relay state (On/Off)
  4. Can search the devices in our network
  5. Can manage the count down (Turn On/Off the device after X time, delete current count down, ...)
  6. Reboot and Reset the device
  7. Set device alias
  8. Setup new devices (you should connect to your smart plug in access point mode)
  9. Discover all connected devices (using TCP scanner or UDP broadcast)

This library uses a third party library "Newtonsoft Json", and it's linked to the project using Nuget.

Image 4

Class diagram explanation:

  • ORANGE: Device info and single actions to change something in the device (no answer required)
  • BLUE: Actions to get the device time
  • GREEN: Count down information and actions
  • PURPLE: Available Wireless access points

The class HS1XX is the main entry point. We should declare an instance to start the device management.

Using the Code

To use the library, we just need to declare a new instance of the class HS1XX:

C#
HS1XX mHS1XXManager = 
    new HS1XX(IPAddress.Parse("192.168.1.32"), 10000, 0, 0); //For example 192.168.1.32

Note: I recommend using a big timeout for connection, and set to 0 the timeout to receive and send commands. The reason is because sometimes, the device takes a long time to perform the actions.

After that, we can use this instance to send actions and receive the device information.

Example:

C#
HS1XX mHS1XXManager = new HS1XX(IPAddress.Parse("192.168.1.32"), 10000, 0, 0);
DeviceInfo dev_info = mHS1XXManager.GetDeviceInfo();
MessageBox.Show(dev_info.Alias);

Comments

  • This is a non official library and non official application, you can execute under your responsibilities.
  • The TP-Link firmware is under GPL license, so you can download it from the official web.
  • Before writing this article, I asked to TP-Link support if any problem exists about writing an article where I will show how to make a custom app. (They said, that there isn't any problem, because firmware is under GPL).

History

  • 27/12/2017
    • Added new functionality to discover all HS1XX devices using UDP broadcast
  • 15/08/2017
    • Improved the function to get all HS1XX devices (now is faster)
    • Added new exceptions
    • Added the functionality to setup new devices
    • Added class to allow to get the device info using the ThreadPool
  • 05/02/2017
    • Initial release

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer
Spain Spain
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: Power consumption information functionality Pin
Alberto M.11-May-19 8:18
Alberto M.11-May-19 8:18 
QuestionGetAllDevices Pin
Member 135831025-Jan-18 5:35
Member 135831025-Jan-18 5:35 
AnswerRe: GetAllDevices Pin
Alberto M.7-Jan-18 5:57
Alberto M.7-Jan-18 5:57 
GeneralRe: GetAllDevices Pin
Member 135831029-Jan-18 4:58
Member 135831029-Jan-18 4:58 
GeneralRe: GetAllDevices Pin
Yuri Murakami13-Feb-18 13:07
Yuri Murakami13-Feb-18 13:07 
GeneralRe: GetAllDevices Pin
Alberto M.14-Feb-18 9:38
Alberto M.14-Feb-18 9:38 
QuestionGreat article, but.. Pin
Phebous28-Dec-17 18:06
Phebous28-Dec-17 18:06 
AnswerRe: Great article, but.. Pin
Alberto M.28-Dec-17 23:00
Alberto M.28-Dec-17 23:00 
Hi!
I don't belive that this device has a GPS (because exists some commands to setup location, and i suppose that its an external application who setup the location), i think that he obtains the location when you setup the device using the oficial app, or simply when you use the oficial application (like update searches).

I discovered some parts using reverse engineering with wireshark, and codes from other people in other programming languages.

GeneralRe: Great article, but.. Pin
dandy721-Jan-18 7:13
dandy721-Jan-18 7:13 
QuestionMy vote of 5! Pin
jediYL22-Sep-17 15:31
professionaljediYL22-Sep-17 15:31 
QuestionControling via Cloud also possible? Pin
Member 1338001726-Aug-17 22:53
Member 1338001726-Aug-17 22:53 
AnswerRe: Controling via Cloud also possible? Pin
Alberto M.28-Aug-17 1:59
Alberto M.28-Aug-17 1:59 
AnswerRe: Controling via Cloud also possible? Pin
dandy721-Jan-18 7:16
dandy721-Jan-18 7:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.