In this post, I explain how you can use an AWS IoT Enterprise button to turn on and off a TP-Link HS100 Smart Plug using Lambda functions. The Smart Plug in turn powers up a pond pump which pumps water to the plants in my (wife’s) balcony garden.
The AWS IoT Button is a programmable button based on the Amazon Dash Button hardware. This simple Wi-Fi device is easy to configure and designed for developers to get started with AWS IoT Core, AWS Lambda, Amazon DynamoDB, Amazon SNS, and many other Amazon Web Services without writing device-specific code.
You can code the button’s logic in the cloud to configure button clicks to count or track items, call or alert someone, start or stop something, order services, or even provide feedback. For example, you can click the button to unlock or start a car, open your garage door, call a cab, call your spouse or a customer service representative, track the use of common household chores, medications or products, or remotely control your home appliances.
The high level steps involved in building this solution are as follows:
- Figure out how the Smart Plug REST APIs work
- Write the Lambda functions to turn on and off the plug
- Configure your AWS IoT Button
- Setting up the garden pump
Figure out how the Smart Plug REST APIs work
The APIs for the TP-Link smart smart plug aren’t quite documented. With some help from the internet, I figured out how my plug responds to API calls, using an app called Insomnia. (You could also use Postman)
- First, send a POST to https://wap.tplinkcloud.com in JSON format to authenticate and get a token. The UUID key can contain any arbitrary value. You can generate a UUIDv4 key here. Here is an example:
- You should receive a response that contains a token. Copy this value to your clipboard.
- Send another POST request calling the getDeviceList method. This time, append the token parameter to the URL as follows: https://wap.tplinkcloud.com?token=ca0f00de-AbCdEfOASrmMW7Xqracf69c
In the body of the request, enter the following JSON:
- There are two important bits of information you’ll need from the response to getDeviceList, namely deviceId and appServerUrl.
- Form another POST request, this time send the request to the appServerUrl that was returned in the previous step, and append the token you received in step 2. For example: https://eu-wap.tplinkcloud.com?token=ca0f00de-AbCdEfOASrmMW7Xqracf69c[cc lang=”yaml”]
- You will notice that setting the state key to 1, turns on the smart plug. If you send the same request with state set to 0, it turns off the plug. You now know everything you need to start writing AWS Lambda functions to control your smart plug.
Write the AWS Lambda function that toggles your plug status when invoked
In order to simplify things, I’ll just create one Lambda function that toggles the relay_state of the smart plug. This means that the Lambda function will turn on the plug if it is found to be off, and turn off the plug if it is found to be on.
- Set the environment variables. In the code sample I’ve provided below, the Kasa app password is expected to be an OS environment variable. You’ll need to define that in the AWS Lambda console. This is not ideal, but there aren’t many ways to make it work. You could also put the deviceId as an environment variable instead of determining it in code, as it remains constant. However, in order for the code to be re-usable I’m determining it at each execution in the code block.
- Write the lambda_function.py code:
- Test your Lambda function, using the Test feature on the top of the AWS Lambda console. Your plug should toggle on and off with each execution.
Configure your AWS IoT button
It’s time to now configure your AWS IoT button to trigger the Lambda function you just created.
- If you are using an AWS IoT Enterprise button, use the AWS IoT 1-Click app on your mobile device. The app is available for Apple and Android. For regular IoT buttons you could use other methods as described in the AWS documentation.
- Connect the button to your WiFi network, and configure IoT button to trigger the Lambda function you created in the previous section.
- Much of the configuration is automated, the certificates will be configured and IoT rules required will be in place.
- Verify that the AWS Lambda console shows the AWS IoT trigger. You should also see this in the IoT 1-Click mobile app.
- Test your AWS Iot Button. When you click the button, the smart plug should toggle ON or OFF with each button press. The LED on the IoT Button blinks white when it’s working and a solid green when the command executes successfully.
Setting up the Garden Pump
Now for the fun part. You’ll need:
- A plastic reservoir with lid. You can get a large plastic container from IKEA or Home Box. Make sure it doesn’t have holes (for wheels) etc, as you’ll be filling this up with water. A lid is desirable to prevent water loss by evaporation.
- A submersible pond/aquarium pump. Pro tip: Get one with higher rating if you’ll run a longer length of hose.
- Length of hose and fittings/accessories. I bought this from Amazon and it had all that I needed.
- A drill or other tool that lets you make holes on the lid of the reservoir.
- A electrical outlet close to the reservoir (or suitable electrical extension).
- And in case you forgot – you’ll need a TP-Link HS100 Smart Plug and an AWS IoT button.
- WiFi: The smart plug needs to be within range of your Home WiFi. Note: Your AWS IoT Button does NOT have to be on the same WiFi, it can even be in another country and you could remotely water your plants over the internet!
Here’s a video detailing the setup. Have fun!
Important note/disclaimer: Water is a good conductor of electricity and there is risk of serious injury/death by electrocution if you do not follow common precautions. Do not put your hand into the reservoir with the power turned on. Always unplug the pump from the electric plug before putting any part of your body inside the reservoir. Use good quality pumps and wiring. Do not immerse any electrical component inside the reservoir except a submersible pump. Always follow manufacturer’s instructions. I cannot be held responsible or liable for any loss, injury or death that occurs by following these instructions.