Click here to Skip to main content
13,591,489 members
Click here to Skip to main content
Add your own
alternative version

Stats

13.8K views
1.1K downloads
17 bookmarked
Posted 5 Feb 2017
Licenced GPL3

How to Control TP-Link Smart Plug HS1XX

, 27 Dec 2017
Rate this:
Please Sign up or sign in to vote.
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.

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)

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

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

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.

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:

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:

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)

Share

About the Author

Alberto M.
Software Developer
Spain Spain
No Biography provided

You may also be interested in...

Pro

Comments and Discussions

 
QuestionConsistent return of "Not a TP-Link device or TimeOut" Pin
Member 1319728310-Feb-18 19:48
memberMember 1319728310-Feb-18 19:48 
AnswerRe: Consistent return of "Not a TP-Link device or TimeOut" Pin
Alberto M.20-Feb-18 8:06
memberAlberto M.20-Feb-18 8:06 
QuestionPower consumption information functionality Pin
Yuri Murakami14-Jan-18 9:09
memberYuri Murakami14-Jan-18 9:09 
QuestionGetAllDevices Pin
Member 135831025-Jan-18 5:35
memberMember 135831025-Jan-18 5:35 
AnswerRe: GetAllDevices Pin
Alberto M.7-Jan-18 5:57
memberAlberto M.7-Jan-18 5:57 
GeneralRe: GetAllDevices Pin
Member 135831029-Jan-18 4:58
memberMember 135831029-Jan-18 4:58 
GeneralRe: GetAllDevices Pin
Yuri Murakami13-Feb-18 13:07
memberYuri Murakami13-Feb-18 13:07 
GeneralRe: GetAllDevices Pin
Alberto M.14-Feb-18 9:38
memberAlberto M.14-Feb-18 9:38 
QuestionGreat article, but.. Pin
Phebous28-Dec-17 18:06
memberPhebous28-Dec-17 18:06 
AnswerRe: Great article, but.. Pin
Alberto M.28-Dec-17 23:00
memberAlberto M.28-Dec-17 23:00 
GeneralRe: Great article, but.. Pin
dandy721-Jan-18 7:13
memberdandy721-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
memberMember 1338001726-Aug-17 22:53 
AnswerRe: Controling via Cloud also possible? Pin
Alberto M.28-Aug-17 1:59
memberAlberto M.28-Aug-17 1:59 
AnswerRe: Controling via Cloud also possible? Pin
dandy721-Jan-18 7:16
memberdandy721-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.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web03 | 2.8.180618.1 | Last Updated 27 Dec 2017
Article Copyright 2017 by Alberto M.
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid