Developing an Energy Monitor with a Kasa HS300 Power Strip in Python — Part 1

Monitoring the energy consumption is the most typical smart home application. However, if you do not have any expert knowledge of circuits and power monitoring, making a DIY-style power socket for monitoring the energy consumption is not feasible. For the energy monitoring purpose, many smart plug solutions with mobile apps have been introduced to the market. However, most of them are not opening their APIs to the public and this makes it hard for DIYers to develop their own energy monitoring applications. HS110 model from TP-Link has been a great option for DIYers due to its cloud-based communication model. However, HS110 is not produced any more and HS300 power strip with 6 outlets seems to be the only option for the amateur developers.

In this story, I deal with how to develop a python application which downloads the realtime energy consumption caused by each device connected to the HS300 power strip.

In this story, Kasa Android app will be used for the user interface and I hope that the same practice can be applied to the iPhone client. The whole story is composed of two parts. The first part, which is this story, is about how you can communicate with TP-Link Cloud using HTTP POST requests to download the realtime energy usage data. The second part, which is to be published as a separate story, is about how to develop a python program to download the energy usage data from the TP-Link Cloud and how to visualize the energy usage data using TimescaleDB and Jupyter notebook.

he first step in the first part is buying an HS300 power strip, creating a Kasa account, and naming each outlet on the power strip. HS300 power strip is now available in Amazon with price of $69.99 (July 27, 2020). Once you get an HS300 power strip, download Kasa Smart mobile app from Google Play Store. You need this mobile app to create your Kasa cloud (or TP-Link) account, which is essential to access the energy consumption data. After downloading Kasa Smart app and create an account, please log in and connect your HS300 power strip to your Kasa Smart app. Giving different name to each outlet can make it easier to keep track of which device consumes how much energy.

Six different devices connected to my HS300 power strip

he second step is getting a token associated with your Kasa account for the authorized communication with TP-Link cloud. To enable Kasa users to control their devices in anywhere and anytime, the control and data communication related to Kasa products is mediated by the TP-Link cloud. To prevent anyone from accessing your resource in the cloud, Kasa platform allocates a token to your account, which is meant to be used only by you. For this authentication step, I used this page as a tutorial. To get a token, you need to first create a UUID (version 4) here. If you click “Generate a version 4 UUID” button, you will get a globally unique ID as below:

An example UUIDv4 generated by the webpage

If you have generated a unique UUIDv4, you need to send a POST request to the TP-Link cloud to get your token. To do so, you can use an easy-to-use app called Postman (link). Postman is an intuitive free software to compose an HTTP request and inspect the response. If you downloaded and executed Postman, create a new POST request such that:

  • The request type is set to POST
  • The request should have https://wap.tplinkcloud.com for its URL
  • In Header tab, you should add a {KEY:VALUE} pair, {Content-Type:application/json}, if it is not present.
  • In Body tab, select raw element and insert your account information with the UUIDv4 that was generated above. You can replace the bolded items below:
{"method": "login","params": {"appType": "Kasa_Android","cloudUserName": "YOUR_KASA_CLOUD_ID","cloudPassword": "YOUR_KASA_CLOUD_PW","terminalUUID": "YOUR_UUIDv4"}}

When you’re done, click “Send” button in the right. In Body tab, you will be able to see the response at the bottom. From the json data in the response body, you will see a key, “token”, and the corresponding value to it. You will use that token string when you access your resource in the TP-Link cloud.

he third step is to get a deviceID of your HS300 power strip. To do so, you can compose another POST request that invokes a TP-Link cloud method, called “getDeviceList”, with your token. In Postman, as you just did to get your token, create a new POST request such that:

  • The request type is POST
  • The request URL is: https://wap.tplinkcloud.com?token=YOUR_TOKEN
  • In Header tab, you should add a {KEY:VALUE} pair, {Content-Type:application/json}, if it is not present.
  • In Body, select raw, and add:
{"method":"getDeviceList"}

When you’re done, click send button. Then you will get a json data in the body of the response message, which contains the list of your registered Kasa products. If the HS300 power strip is the only registered Kasa product of yours, only its description will be shown. Out of all the {key:value} pairs, “deviceId” is all you need. Copy its string value and move to the next step.

he next step is to get six different IDs (called child_id) of the attached outlets to your power strip. Unlike the other Kasa smart plugs such as HS100 and HS110, HS300 has six outlets and the energy consumption by each outlet can be independently monitored. To incorporate such independent energy monitoring feature into your software, you should be able to specify which outlet you want to fetch the energy consumption data about. You can achieve this by sending another POST request to invoke “passthrough” method in the TP-Link cloud that have two parameters; one is the “deviceId” of your HS300 power strip, and another one is a cloud-side method, called “get_sysinfo”. To do so, create a new POST request such that:

  • The request type is POST
  • The request URL is: https://wap.tplinkcloud.com/?token=YOUR_TOKEN
  • In Header tab, you should add a {KEY:VALUE} pair, {Content-Type:application/json}, if it is not present.
  • In Body, select raw, and add:
{"method":"passthrough","params": {"deviceId": "YOUR_DEVICE_ID","requestData": "{\"system\":{\"get_sysinfo\":null}}}" }}

Please don’t forget that you need to put your deviceId to replace YOUR_DEVICE_ID above.

If you send the POST request, you will find a long json data in the body of the response message. From the json data, you will see a key, called “children”, that has a list items each of which corresponds to the outlet of your HS300 power strip. An interesting point is that, the ids of the outlets are nothing but deviceId + 00–05, which indicates the index of each outlet. If you define the alias of each outlet above, you will easily find which id corresponds to which outlet.

he last step of the first part of the story is downloading the realtime energy usage data from the TP-Link cloud. To achieve that, again, you can send a POST request to invoke the “passthrough” method as you just did. The only difference in this step is that you should add the ID of a specific outlet (called child_id) as an additional context and request data with “emeter” argument as below:

{"method":"passthrough","params": {"deviceId": "YOUR_DEVICE_ID","requestData": "{\"context\":{\"child_ids\":[\"CHILD_ID\"]},\"emeter\":{\"get_realtime\":null}}" }}

I assume that you now know how to create and send a new POST request which has the json data above in its body. If you send the POST request, you will find a json data in the response message, which contains four values related to the realtime energy usage: Voltage in mV, Current in mA, Power in mW, and Total Energy Consumption in wH. I verified that these values are consistent with the values that you can see in your mobile app.

I’m sure now you find out that the TP-Link cloud offers various methods via HTTP messaging protocol. If you want to learn more about the methods, you can visit this api document.

In part 1, we have learned how to manually download the realtime energy usage data using Postman. Now it’s time to automate the function and run a smart home energy monitoring application with a simple data visualization. In part 2, we’ll see how to achieve that in Python using TimescaleDB and Jupyter Notebook.

A computer scientist enthusiastic about enabling our surroundings smart and even autonomous! KAIST PhD, now at MIT as a Postdoc

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store