Control TP-Link smart plugs with tplink-smarthome-api

2021.01.05

TP-Link's IoT products such as smart plugs can be controlled directly from devices like Raspberry Pi on the same LAN by using an open-source Node.js library called tplink-smarthome-api. In this article, How to operate the TP-Link smart plug using the tplink-smarthome-api will be explained.

(この記事の日本語版はこちら)

Preparation

I used Raspberry Pi 3B+ for running the tplink-smarthome-api. A smart Plug HS105 was used as the TP-Link device to be controlled.

The hardware and software configuration is as follows:

  • Raspberry Pi 3B+
    • OS: Raspbian Buster
    • node: v10.21.0
    • tplink-smarthome-api: 3.1.0
  • HS105
    • hardware version: 2.0
    • F/W version: 1.0.7

Refer to the instruction paper that comes with the smart plug and set up the plug itself to be ready for use.

Install tplink-smarthome-api on the Raspberry Pi.

npm install tplink-smarthome-api

Here I explain the code to turn on/off the smart plug with tplink-smarthome-api. You can easily check how it works on Node's REPL. First, load the NPM module of tplink-smarthome-api and get an instance of the Client class.

> client = new (require('tplink-smarthome-api').Client)();

Specify the registered name of the device to be controlled in plugName variable. The registered name is the name you gave your plug when you registered it with the TP-Link's Kasa application.

> plugName = 'smartplug001';

Execute the startDiscovery method of the Client class to start searching for plugs that are ready to be operated on the LAN. A device object to operate the found device is set as the argument of the callback executed when the device is found. The registered name is set to alias of the device information object retrieved by the getSysInfo method of the device object. startDiscovery method will continue to search for devices until client.stopDiscovery() is executed, so when all the devices you want to find are found, execute stopDiscovery to end the device search.

> plug = undefined;
> client.startDiscovery().on('device-online', async (device) => {
    info = await device.getSysInfo();
    plug = device;
    if (info.alias === plugName) {
        console.log('stopping device discovery...');
        client.stopDiscovery();
    }
})

To turn on/off a smart plug, execute the setPowerState method of the device object of the found smart plug.

> plug.setPowerState(false) # Turn the plug off
> plug.setPowerState(true) # Turn the plug on

The following video shows the result of using tplink-smarthome-api on a Raspyberry Pi 3B+ to turn on and off a TP-Link HS105 smart plug on LAN. The actual plug was turned on and off when I execute the setPowerState() method from the Node's REPL. The on/off state of the device on the Kasa app was also properly synchronized.

Conclusion

How to operate the TP-Link smart plug on LAN using the tplink-smarthome-api was explained. TP-Link devices can be remotely controlled over the Internet via TP-Link's server by using the TP-Link's Kasa app or IFTTT, so tplink-smarthome-api may not be needed in general. However, If you have a home server or similar environment and want to hack some home automation things, tplink-smarthome-api may be useful. Enjoy your hacking!

Appendix

Solving the error when executing "npm search tplink-smarthome-api"

When I ran npm search tplink-smarthome-api on my Raspberry Pi, I got the following error.

$ npm search tplink-smarthome-api
npm WARN npm npm does not support Node.js v10.21.0
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8, 9.
npm WARN npm You can find the latest version at https://nodejs.org/
NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
tplink-smarthome-api      | TP-Link Smart Home…  | =plasticrake    | 2020-10-13 | 3.1.0    | tplink kasa hs100 hs10

I referred to this Japanese article and changed the owner of the npm directory to my user then I was able to solve the error.

$ sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}

References