Controlling a Wifi Plug over the network using TCP Messages

We recently purchased some TP-Link HS100 Kasa Smart Wi-Fi Plugs to allow us to remotely turn on speaker amps to support our outdoor speaker systems. Turning the amps on each time by going to the physical amp location in the racks located all across the campus was very inconvenient, so this was a great upgrade.

This is what the plug looks like.

It pairs with an app called Kasa to allow you to turn the outlets on and off pretty easily, however in our testing, we couldn’t get it to work with more than one smartphone. Plus, we didn’t want volunteers to have to install this app on their phone, or provide a phone just to run this app.

The TP-Link protocol has been reverse engineered pretty well, so I had hopes that this would be a quick and easy project, and it was! The core protocol uses JSON to communicate, however it is obfuscated heavily to the user and you have to send a hexadecimal payload to it in the end in order to trigger an action.

Once we set up the devices as recommended through the app to use our internal network WiFi, I had our IT department create IP address reservations based on the MAC addresses of the outlets, so that they would always have the same IP address. If you use these plugs, I recommend doing that in your setup as well.

Then, I researched the protocol and figured out what the hexadecimal payloads needed to be to power it on and off. I didn’t really care about any of the other status settings. Just a simple on and off.

Here is the function needed to do that, written in ogScript for Ross Dashboard:

function tellOutlet(address, port, protocol, command)
    var enabled = ogscript.getObject('outletEnabled');

    if (enabled)
            case "TPLINK-HS100":
                var payload_on_hex = "0000002AD0F281F88BFF9AF7D5EF94B6C5A0D48BF99CF091E8B7C4B0D1A5C0E2D8A381F286E793F6D4EEDFA2DFA2";
                var payload_off_hex = "0000002AD0F281F88BFF9AF7D5EF94B6C5A0D48BF99CF091E8B7C4B0D1A5C0E2D8A381F286E793F6D4EEDEA3DEA3";
                var sendCommand = "";
                if (command == "on")
                    sendCommand = payload_on_hex;
                else if (command == "off")
                    sendCommand = payload_off_hex;
                rosstalk.sendAsBytes(address, port, sendCommand, callback);
                ogscript.debug("Outlet turned " + command + ".");

The key function here is the RossTalk SendAsBytes command which sends the TCP message as hexadecimal data.

Once I did a test and was satisfied it was working properly, I built out custom panels that use our master production control system, so now volunteers can easily turn the amps on or off by just clicking a button!

I also built a stand-alone version in case anyone else could benefit from it.

Screen Shot 2018-07-25 at 4.06.54 PM.png
The buttons are first disabled when you open the panel until you’ve configured the outlet in the setup tab.
Screen Shot 2018-07-25 at 4.07.00 PM.png
In the setup tab, you can configure the outlet IP address, the port (the default is 9999), and choose the protocol. Currently, the panel only supports the TP-Link HS100/101 models.
Screen Shot 2018-07-25 at 4.06.42 PM.png
Just click On or Off to toggle the outlet!

The panel is up on my Github repository, if you’d like to download it.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s