Inspired from the Internet Switch tutorial by Talha which was based on ESP8266, I thought of doing the same on Raspberry Pi instead.
So that is what we are going to do in this tutorial. We are going to use Raspberry Pi and Grandeur to build an internet switch. In other words, we will be controlling an LED connected to a GPIO pin of the RPi from our web app which we'll build with Grandeur as our back-end. Our web app will send ON/OFF command to the Cloud which our RPi will listen to and will consequently update the voltage on its LED pin.Why Grandeur?
If we do not use a managed backend, we would have to integrate an MQTT server and client API between our app and our hardware device (RPi) to let the realtime communications happen between them. And if we have multiple RPis and we want to signal some of them to turn ON their LEDs and others to stay OFF, MQTT's pub/sub would do it for us.
But if we need to store logs too, let's say when was RPi1's LED turned ON or OFF and who did it, we'd need to integrate a database (mySQL or mongoDB) with our system too. Similarly adding file storage, OTA, and other such features would keep increasing the number of integrations we need to do and so the complexity of our system.
Let us dive into our project now.Setting up our Raspberry Pi OS
First of all, let's set up our Raspberry Pi with OS. You can follow these steps to set up your new RPi:
- Download Raspberry Pi Imager from here and install it.
- Attach your SD card with your PC and run the RPi imager.
- Choose the OS you want to run your RPi on. I wanted to use RPi in headless mode without its desktop GUI to keep things as light as possible and not attaching a screen to the RPi. So I installed Raspbian Lite.
- Choose your SD card and click Write.
- Once the writing is complete, remove and insert the SD card back, if on mac, or leave it be on windows.
- Open the SD card (named boot) from explorer, create a new file named wpa_supplicant.conf and place the following in it and replace the angle brackets with corresponding parameters (Read this for details):
country=<Insert 2 letter ISO 3166-1 country code here>
ssid="<Name of your wireless LAN>"
psk="<Password for your wireless LAN>"
- Create an empty file named ssh in boot. This will allow you to connect to your RPi's terminal from your PC through ssh (secure shell), without needing a separate screen.
- Eject the SD card and remove it from your PC. Insert it into the RPi and power it up. The RPi will connect with your WiFi by using the WiFi configurations you provided in the wpa_supplicant.conf file.
- In your PC, open terminal and run the
pingcommand to check if the RPi has come online using the SSID and PSK you provided in wpa_supplicant.conf file:
- If pinging is successful, it means RPi is connected to your router's access point. You can now ssh into your RPi. pi is the default user account in Raspbian which you can log into it by running:
If it asks for password, use "raspberry".
- Now that you are connected to Raspbian's terminal, update its repositories and python version you want use.
Step 1: Getting Started
sudo apt-get update
sudo apt-get install python3 python3-env
We'll follow the same steps as Talha did in his Internet Switch tutorial. For reference, here is a checklist of things you have to do to set up your project on Grandeur:
- Create a new project by visiting Grandeur dashboard web app.
- Visit settings page, get your project's API key, and generate the access credentials as shown below. We will be in need of the API key and access credentials while building our app.
- Create a new user account from the accounts tab. We will later sign into our app with the email and password we create now. This is another cool feature of Grandeur: multiple users can use your app by signing in with their emails and passwords. Each user can pair and interact with its own devices. Authentication is built at the core of Grandeur. User creation is illustrated below:
- Now create a new device through devices page. This operation generates a new device ID which we'll use while writing code for our hardware. So technically, each device that communicates with the cloud needs to have a unique ID. Your device is like your digital asset with a unique ID and you will use this ID whenever you communicate to your device from your app. Device registration also generates an access token. Don't forget to copy it for it is required in hardware code to establish source authenticity of device requests. It won't be accessible after closing the dialog. Device creation is illustrated below:
- A user cannot interact with a device unless it's paired with it. Pairing a device makes the user the admin of the device — which means the user can fetch/update its paired devices variables. There are two ways you can pair your device: 1) using the Cloud Dashboard, or 2) through the web app by using
pairDevice()function of the device API. This second way has a very strong significance if you look at it from production point of view. Like you can now ship your hardware products, and your users can sign in to your app and claim ownership of a hardware device they buy from your store by pairing it. Here's how you can pair your device with a user using the Cloud Dashboard:
This is it. You can follow the hello world tutorial of Grandeur to get more details about each step.Step 2: Hardware Program
Since we defined a
state variable in parms while creating our device model from Cloud Dashboard, we'll ask the Cloud to send us any updates in our device parms on our RPi-end which consequently will be giving us update to
state. For this purpose, we'll use the Py SDK of Grandeur. The objective is when our program is run, it listens for any change in the
state variable. If it's value changes to 1, this program turns our LED on GPIO17 ON, otherwise OFF. Let's do it.
After doing ssh into our RPi, let's create a virtual environment first for the device program of our project to keep its packages and libraries isolated from the global ones:
python3 -m venv "Pi Switch"
Then activate the virtual environment
source Pi\ Switch/bin/active
We install RPi's GPIO package to help control RPi's GPIO pins and grandeur package for communication with the Cloud.
pip install RPI.GPIO gpiozero grandeur
Then we create a new hardware.py file and write our device program in it.
Here's our python program code: 🤖
The logic is very simple. We define the event handler functions first.
onConnectionis called when the program gets successful in establishing a secure connection with the Cloud.
handleParmsUpdateis called when the Cloud notifies the RPi of an update in a parms variable (
statein this case).
handleParmsis called when the Cloud sends all parms variables in response to calling
Once the event handlers are defined, we start the connection setup by calling
grandeur.init function with our project's API key and device token, and then specify our device by passing device ID to
project.device. We set up our previously defined event handlers for proper events by calling
while 1 loop prevents the program from exiting. You can write in here the code that you want to repeatedly execute — like reading a GPIO after every 5 seconds.
What this program does is when it's run, it starts establishing real time channel with the Cloud. When the connection is fully established, it gets the device parms from the Cloud for initializing RPi's LED pin with
handleParms function). Calling
onParms makes it listen for any future updates in parms variables. As soon as any such update occurs, the Cloud sends it to the RPi which updates the state of its LED pin (see
Our app contains two files
index.html where we design the layout of the page and
When the app loads it presents the login screen. When the user inserts its account credentials and logs in, the app establishes the real-time communication channel with the Cloud using the API key, access key and token which we got in the Getting Started section. On logging in, the app gets a list of all devices paired with this user account from the Cloud. And when the user clicks a device button, the app calls its corresponding
toggleLED function and sends a request to the Cloud to update the
state variable to the toggled value.
Here we are finally. Let's test what we have build. For this purpose, while being in ssh in our RPi and our project environment activated, we run our
hardware.py file with the following command:
We start seeing live output in the terminal below our command. But we have to run our web app to toggle our RPi device state. For that we run a local server with Grandeur CLI. The command line interface helps us with testing by running a local server. Simply download it from npm (you need nodejs, for now). Run the following command in your terminal:
npm install grandeur-cli -g # Installs the cli in your computer
Then go into the directory of your web app and run the following commands in your terminal:
grandeur init # Command associates your directory with your project
and finally run the server:
This has been documented very well in the official tutorial.
There's a security measure. You cannot send data from your app to the Cloud unless you whitelist your domain (the address that is shown in the browser's URL bar when you open your app — http://localhost:3000 if you are running
grandeur serve command) from the Cloud Dashboard. This prevents all the unidentified sources from accessing your Cloud project's data in case you lose your access key.
This is it 💥. Now you can log into your app, click on toggle button of your device, and watch the LED on RPi follow you in real time.
Woohoo 👉 Our own web app to control our RPi's LED.
So in this tutorial we created an internet switch using Raspberry Pi. We built an app through which we sent data to our RPi and toggled an LED attached to it. Now you can extend it in so many ways, like you can connect a relay to the LED pin and even control your appliances in real-time. I hope it went well but if there is some kind of confusion, you can always reach me out.
Here's their website link just in case you want to give Grandeur a shot. Do let me know about your feedback in comments.
Till next time.