You've just made my office lamp blinks. š”
How does that happen?
The requirement is fairly simple: we need to send a signal from anywhere in the world to the internet-enabled device in order to make it behave as we want. We are not intended here to implement large-scale solution and complicate things.
There are technically many ways to meet our requirement ā from building the solution from scratch up to using one of off-the-shelfs cloud services. But we donāt care about them. We just need to experiment with the āinternet of thingsā: how to control a device from anywhere in the world.
This article is not for you if you want an enterprise-level solution for your IoT project, in case you have thousands of devices to control, with critical requirements and several security concerns.
The Hardware
Iām going to use Raspberry PI for easiness. Although you can use your internet-enabled controller (Arduino with ESP module, NodeMCU, WeMosā¦ etc).
The Software
1. Web-based user interface
A simple user interface for the end-user in order to control the device from. I built it for you.
2. PubNub
Pubnub is used to deliver messages between our control unit (the web-based user interface) and the device. You can think of it as a cloud-service that provide publish-subscribe messaging pattern.
In this pattern, thereās a publisher who can publish / send messages through certain channels. And a subscriber who can subscribe / listen to those channels. Whenever a message is published through channel x, all the subscribers of channel x will receive the message.
In our case:
- The user publishes (sends) messages through a channel named
commands
. - The Raspberry PI is interested in subscribing for, (receiving), messages from the
commands
channel. - Every message sent through the
commands
channel, is received from the Raspberry PI. And then the Raspberry PI is able to behave based on the received message.
Create PubNub account
You need to have PubNub account, itās free. Create an account, then create an app, and keep the credentials (subscribe
and publish
keys) with you.
Setting up PubNub with Raspberry PI
Since I’m using Raspberry PI, Iām going to use the Python SDK for PubNub, You can use the suitable SDK for your controller..
In your Raspberry PI you can install it from the command line:
pip install 'pubnub>=4.4.0'
Now we need to subscribe for all the messages that are sent through a channel called messages
, the following code should configure PubNub client based on the constants SUBSCRIBE_KEY
(which is available in your account) and CHANNEL
(the name of the channel).
import sys
import time
sys.path.append('/usr/local/lib/python3.7/site-packages')
from pubnub.pnconfiguration import PNConfiguration
from pubnub.callbacks import SubscribeCallback
from pubnub.pubnub import PubNub
SUBSCRIBE_KEY = 'sub-c-fee6fbae-4fb6-11ea-80a4-42690e175160'
CHANNEL = 'messages'
# Setting up PubNub
pnconfig = PNConfiguration()
pnconfig.subscribe_key = SUBSCRIBE_KEY
pubnub = PubNub(pnconfig)
pubnub.add_listener(SubscribeCallback())
pubnub.subscribe().channels(CHANNEL).execute()
class SubscribeCallback(SubscribeCallback):
def message(self, pubnub, message):
print(f'Received message: {message.message}')
if message.message == 'blink':
blink()
def blink():
print('I should blink.')
Now whenever you run this code (from an IDE or using the command line python pubnub.py
), each message sent from PubNub over the messages
channel will be printed out.
Setting up PubNub with Web client
Here’s a Web-based user-interface of which we can control the Raspberry PI from. PubNub provides many SDKs for variety of platforms, you can integrate it with any platform you like.
However, I built the web client for you, you can find the source code in the Github repo (client.html
). Or you can just use the one below:
Insert your publish and subscribe keys in the first two fields, then insert the channel name of which youād like to send the messages through.
The name of the channel should exactly match the one the Raspberry PI subscribes to.
Test it
If everything above is implemented, once you you hit the Send button, the message should be received on the Raspberry PI side. Nothing fancy for the time being, it only prints a message to the console.
Blinking LED
Letās make a physical reaction to the received message. The simplest thing is to connect an LED and make it blinks. You may, in the future, replace the LED with any other āsystemā; it could you an espresso machine making a cup of coffee, your room lamp turning it on and off.. or any controllable device.
Hardware connection
The Raspberry PI comes with many pins you can use (GPIO). We are interested in connecting the LED to the negative pin (the ground, pin 39), and a positive pin (high voltage: pin 40 / GPIO 21).
Letās get back to the Python code and make the changes to make the LED blinks. Iām going to use a library called GPIO Zero in order to setup the LED connections. First we need to import the LED module, and the sleep function:
from gpiozero import LED
from time import sleep
Letās define an LED object, as we mentioned above, weāre using the pin GPIO 21.
led = LED(21)
Now instead of printing a message, letās replace it with the following code:
led.on() # turn on the led
sleep(1) # then wait 1 second
led.off() # then turn it off
If the received message is blink
, the LED will blink.
How to improve?
-
Telemetry data
What we have done is sending commands from control unit to the device. But what if we want to send telemetry data from the device to the control unit? The same concept, reversed. The Raspberry PI publishes message over certain channel and the control unit subscribes to it. Once a message is received, itās your choice, for example, to save it to a database or to display it to the users in real-time.
-
Control high-power devices
What if you want to control high-power devices, like a room lamp? This could be implemented using a relay.
-
Customized control unit
You can build the control unit on any platform PubNub supports. I choose the web since itās accessible from any device. You can build your own for mobile applications, or to enhance the web client further with advanced user interface that satisfies your needs. And you can deploy the it to be accessible from anywhere. Zeit or Netlify are excellent choices.
LED blinks on website visits
Last month, I tweeted a video (and published it on Reddit) showing an LED blinks whenever someone visits my website. Several people reached out asking how. It’s the same implementation of the above, I only send the message to the Raspberry PI when the website is loaded.