Setup a Raspberry Pi as internet of things to connect to the AWS IoT core and build a web page with two buttons to trigger the RF remote plug. The web page is built with Django framework.
In this project, you will learn the basic concepts of IoT and get hands-on experience about how to make communications between IoT thing and AWS IoT Core service.
Here is the video to demonstrate this project in Chinese with some keynotes subtitle in English.
- Background
- Hardware
- Prepare Raspberry Pi
- Use Pi to control the RF plug
- Setup an IoT thing in AWS
- Connect Pi to AWS IoT Core Service
- Communicate with AWS IoT Core Service endpoint
- Final Test
The RF plug is a power outlet controlled by a remote running under a radio frequency of 315/433mHz; but it does not support "cell phone control" through the internet. I want to learn how to build IoT service with Amazon AWS, so I started this project. The final result is to use cell phone to scan a QR code, then a webpage with 'On' and 'Off' buttons will show on the phone. You can click the On/Off button to control the RF plug.
The structure of the project likes below:
-
Raspberry Pi (the one I used is Pi 3 Model B)
-
FR Module, you can find it in many places at a very low price https://www.amazon.com/dp/B01DKC2EY4
-
Breadboard and wires https://www.amazon.com/dp/B07H7V1X7Y/
-
Using Raspberry Pi Imager to install Raspberry Pi OS Lite and enable SSH connection
# Use default username:pi and password:raspberry to login $ sudo systemctl enable ssh $ sudo systemctl start ssh
-
Connect RF modules to the Pi
-
Install the [rpi-rf] module on Pi to operate the RF modules
$ sudo apt-get update $ sudo apt-get upgrade $ sudo apt-get install git $ sudo apt-get install -y python3-setuptools # install pi.gpio $ sudo apt-get install python3-dev python3-rpi.gpio # Suggest to install rpi-rf from the source code $ git clone https://github.com/milaq/rpi-rf.git $ cd rpi-rf $ sudo python3 setup.py install
-
Catch the control code from the RF remote controller.
$ cd ~/rpi-rf/script # get the RF control code $ ./rpi-rf_receive # Button On:[INFO] rpi-rf_receive: 1340675 [pulselength 172, protocol 1] # Button Off:[INFO] rpi-rf_receive: 1340684 [pulselength 171, protocol 1]
-
Send RF control code from Pi to control the plug
$ rpi-rf_send -p 170 -t 1 1340675 # turn on the plug $ rpi-rf_send -p 170 -t 1 1340684 # turn off the plug
Following this instruction: Create AWS IoT resources
* Pay attention to the 'region' selections, make sure all the operations are done in the same AWS region*
Thing: my_thing
Policy: iotplug_policy
Download Certifications and rename them to
private.pem.key
public.pem.key(not used in these examples)
device.pem.crt
Amazon-root-CA-1.pem
HTTPS Endpoint:
abcdef12345-ats.iot.us-west-2.amazonaws.com
Amazon provides many AWS IoT SDK options, such as Python, Javascript, Java, C++, and Embedded C.
# login to the pi. Replace the ip address with yours
$ ssh pi@192.168.1.104
$ sudo apt-get install cmake
$ sudo apt-get install libssl-dev
# install Python version of AWS IoT SDK
# Highly recommend to install this SDK from the source code
$ git clone https://github.com/aws/aws-iot-device-sdk-python-v2.git
$ python3 -m pip install ./aws-iot-device-sdk-python-v2
# upload certifications to this 'certs' folder on the pi
$ mkdir certs
# exit from the pi
$ exit
# upload certifications
$ scp -r private.pem.key pi@192.168.1.104:/home/pi/certs/
$ scp -r device.pem.crt pi@192.168.1.104:/home/pi/certs/
$ scp -r Amazon-root-CA-1.pem pi@192.168.1.104:/home/pi/certs/
# login back to the pi
$ ssh pi@192.168.1.104
$ cd aws-iot-device-sdk-python-v2/samples/
# run the sample code
$ python3 pubsub.py --topic topic_1 --root-ca ~/certs/Amazon-root-CA-1.pem --cert ~/certs/device.pem.crt --key ~/certs/private.pem.key --endpoint abcdef12345-ats.iot.us-west-2.amazonaws.com
# you are going to see something like this:
# Subscribing to topic 'topic_1'...
# Subscribed with QoS.AT_LEAST_ONCE
# Sending messages until program killed
# Publishing message to topic 'topic_1': Hello World! [1]
# Received message from topic 'topic_1': b'Hello World! [1]'
# Publishing message to topic 'topic_1': Hello World! [2]
# Received message from topic 'topic_1': b'Hello World! [2]'
# ...
Modify the file pubsub.py
in the sample folder and add the rpi-rf script into it. The infinity loop will receive published message from the IoT cloud through MQTT protocol. Base on the published message, this code will trigger the rpi-rf script to turn on or turn off the plug. Here is the code snippet. Please check out iot_plug.py in this repository for more details.
# RF control command send by rpi-rf
cmd_on = 'rpi-rf_send -p 170 -t 1 1340675'
cmd_off = 'rpi-rf_send -p 170 -t 1 1340684'
def power_on():
response_text = os.popen(cmd_on).readlines()
for i in response_text:
print("Plug is On")
def power_off():
response_text = os.popen(cmd_off).readlines()
for i in response_text:
print("Plug is Off")
def on_message_received(topic, payload, **kwargs):
print("Received message from topic '{}': {}".format(topic, payload))
data =payload.decode("utf-8")
if data == "turn_on":
power_on()
elif data == "turn_off":
power_off()
else:
pass
...
if __name__ == '__main__':
...
subscribe_future, packet_id = mqtt_connection.subscribe(
topic=args.topic,
qos=mqtt.QoS.AT_LEAST_ONCE,
callback=on_message_received)
...
The Pi is already connected to the IoT Core service with MQTT protocol and wait for the control command. We need to use an app or a service to the IoT Core to send commands. You can access the control or other features that the AWS IoT Core services provide by using the AWS CLI, the AWS SDK for your preferred language, or by calling the REST API directly. In this project, I will send command through REST API by a single page app running on a Django server.
I used Heroku to deploy the Django server. Here is the instruction: heroku / python-getting-started. After you have the Django webserver running, we can start building the IoT Plug app. You can find the source code in the django folder.
-
Create a Django app called 'iotplug'
-
Create control.py to send out HTTPS request to IoT Server endpoint
def control_plug(command):
# define command-line parameters
# replace with your own endpoint url and put your own certifications in the my_thing folder
endpoint = "abcdef12345-ats.iot.us-west-2.amazonaws.com"
topic = "topic_1"
cert = "iotplug/my_thing/device.pem.crt"
key = "iotplug/my_thing/private.pem.key"
message = command
# create and format values for HTTPS request
publish_url = 'https://' + endpoint + ':8443/topics/' + topic + '?qos=1'
publish_msg = message.encode('utf-8')
publish = requests.request('POST',
publish_url,
data=publish_msg,
cert=[cert, key])
# print results
print("Response status: ", str(publish.status_code))
if publish.status_code == 200:
return("Response body:", publish.text)
-
Build the control.html template with two buttons to trigger the HTTPS requests
-
[optional] Build the qrcode.html to show a QR code to link to the control.html. It's very convenient for the user to have a quick access to the control page by scanning the QR code.
Use the cellphone to open the control page or scan the QR code page to lead you to this page. Click the on or off button, you are able to control the plug through AWS IoT Core Service.