A Personalized Exponential Technology

Arnav Shah
6 min readApr 29, 2020

The Internet of Things is the staple of Industry 4.0, along side AI, Cloud Computing, and Big Data. IoT takes traditionally offline objects, such as a chair, and applies sensors to them to improve the experience of the end user. Unlike data engineering, IoT allows for a seamless, personalized experience by actually acting upon real-time data.

Now, I know what you’re thinking. That’s a whole lot of buzzwords, but what does that actually mean; how is that beneficial? To make things easier, let’s go back to the chair example. How might we personalize the experience of a chair user to ensure maximum indulgence?

Well for starters, humans come in all shapes and sizes; what if we could make a chair that adapts to you, rather than the other way around? The chair would be made out of a highly flexible material and have tactile sensors imprinted into the material. When you sit in the chair, the tactile sensors would start firing off, indicating your body’s presence. Using a variety of motors, the chair would physically transform in order to best suit your body and posture, optimizing for health and comfort simultaneously.

Obviously, this example solves an extremely unimportant problem, and even may sound overkill, but it certainly makes one wonder what the future applications of the technology could be. Fortunately for you, IoT technology is progressing rapidly, and the “secret sauce” tools have even become available for the general public to learn and develop with. In this article, I’m going to teach you how to develop an essential — and affordable — alarm system to solve a problem faced by millions of people every day — theft.

Tutorial

Alrighty, so before we begin, I just want to clarify that this is a basic project. I’d only advise pursuing IoT development if you found this genuinely interesting. With that out of the way, let’s get started!

All (non-edge computing) IoT applications follow this general structure:

  1. Sensors are attached to an embedded communications system
  2. Sensors collect data real time
  3. Sensor data is uploaded to the cloud via a networking protocol
  4. Cloud sensor data is processed
  5. Processed data is sent to a user interface

This exceptionally simple step-by-step process ensures that sensor data is efficiently acted upon, while saving up enough resources on our embedded communications system to collect real-time and accurate data. The reason why this is so important is because on a device that can only be a maximum of 2cm long, we need to make efficient use of local resources and avoid CPU stress at all costs. By sending all of our data to the cloud, we delegate the task of data processing to the super computers up at Google, Amazon, and Microsoft.

Let’s see how that’s done in our context. First, head over to the AWS console, and log in or make an account. Next, search for the service labelled “IoT Core”. You should be currently looking at a dashboard that looks something like this:

Next, you’ll want to register a new device. In order to do that, navigate to the Onboard section in the left navigation pane. Under ‘Onboard a device’, click the blue Get started, followed by the blue Get started that appears in the next screen. Next, choose your local machine OS (Linux/OSX or Windows), and choose Python. Next, give your embedded communications system a name, and click the blue ‘Download for <YOUR_OS>’

Awesome! Next, you’ll want to send your connect_device_package folder to your embedded communications system. There's a number of ways to do that, so I won't go over it in this article.

Now on your embedded communications system, go into terminal and change directories to connect_device_package . Type the following:

$ chmod +x start.sh$ ./start.sh

Next, make a new file called basicPubSub.py and paste the following code:

'''
/*
* Copyright 2010-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* <http://aws.amazon.com/apache2.0>
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
'''
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
import RPi.GPIO as GPIO
import logging
import time
import argparse
import json
AllowedActions = ['both', 'publish', 'subscribe']# Custom MQTT message callback
def customCallback(client, userdata, message):
print("Received a new message: ")
print(message.payload)
print("from topic: ")
print(message.topic)
print("--------------\\n\\n")
# Read in command-line parameters
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--endpoint", action="store", required=True, dest="host", help="Your AWS IoT custom endpoint")
parser.add_argument("-r", "--rootCA", action="store", required=True, dest="rootCAPath", help="Root CA file path")
parser.add_argument("-c", "--cert", action="store", dest="certificatePath", help="Certificate file path")
parser.add_argument("-k", "--key", action="store", dest="privateKeyPath", help="Private key file path")
parser.add_argument("-p", "--port", action="store", dest="port", type=int, help="Port number override")
parser.add_argument("-w", "--websocket", action="store_true", dest="useWebsocket", default=False,
help="Use MQTT over WebSocket")
parser.add_argument("-id", "--clientId", action="store", dest="clientId", default="basicPubSub",
help="Targeted client id")
parser.add_argument("-t", "--topic", action="store", dest="topic", default="sdk/test/Python", help="Targeted topic")
parser.add_argument("-m", "--mode", action="store", dest="mode", default="both",
help="Operation modes: %s"%str(AllowedActions))
parser.add_argument("-M", "--message", action="store", dest="message", default="Hello World!",
help="Message to publish")
args = parser.parse_args()
host = args.host
rootCAPath = args.rootCAPath
certificatePath = args.certificatePath
privateKeyPath = args.privateKeyPath
port = args.port
useWebsocket = args.useWebsocket
clientId = args.clientId
topic = args.topic
if args.mode not in AllowedActions:
parser.error("Unknown --mode option %s. Must be one of %s" % (args.mode, str(AllowedActions)))
exit(2)
if args.useWebsocket and args.certificatePath and args.privateKeyPath:
parser.error("X.509 cert authentication and WebSocket are mutual exclusive. Please pick one.")
exit(2)
if not args.useWebsocket and (not args.certificatePath or not args.privateKeyPath):
parser.error("Missing credentials for authentication.")
exit(2)
# Port defaults
if args.useWebsocket and not args.port: # When no port override for WebSocket, default to 443
port = 443
if not args.useWebsocket and not args.port: # When no port override for non-WebSocket, default to 8883
port = 8883
# Configure logging
logger = logging.getLogger("AWSIoTPythonSDK.core")
logger.setLevel(logging.DEBUG)
streamHandler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
streamHandler.setFormatter(formatter)
logger.addHandler(streamHandler)
# Init AWSIoTMQTTClient
myAWSIoTMQTTClient = None
if useWebsocket:
myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId, useWebsocket=True)
myAWSIoTMQTTClient.configureEndpoint(host, port)
myAWSIoTMQTTClient.configureCredentials(rootCAPath)
else:
myAWSIoTMQTTClient = AWSIoTMQTTClient(clientId)
myAWSIoTMQTTClient.configureEndpoint(host, port)
myAWSIoTMQTTClient.configureCredentials(rootCAPath, privateKeyPath, certificatePath)
# AWSIoTMQTTClient connection configuration
myAWSIoTMQTTClient.configureAutoReconnectBackoffTime(1, 32, 20)
myAWSIoTMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing
myAWSIoTMQTTClient.configureDrainingFrequency(2) # Draining: 2 Hz
myAWSIoTMQTTClient.configureConnectDisconnectTimeout(10) # 10 sec
myAWSIoTMQTTClient.configureMQTTOperationTimeout(5) # 5 sec
# Connect and subscribe to AWS IoT
myAWSIoTMQTTClient.connect()
if args.mode == 'both' or args.mode == 'subscribe':
myAWSIoTMQTTClient.subscribe(topic, 1, customCallback)
time.sleep(2)
# Publish to the same topic in a loop forever
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
pinpir = 17
GPIO.setup(pinpir, GPIO.IN)
previous_state = 0
current_state = 0
while True:
if args.mode == 'both' or args.mode == 'publish':
current_state = GPIO.input(pinpir)
if current_state != previous_state:
message = {}
message['state'] = current_state
messageJson = json.dumps(message)
myAWSIoTMQTTClient.publish(topic, messageJson, 1)
if args.mode == 'publish':
print('Published topic %s: %s\\n' % (topic, messageJson))
previous_state = current_state

Next, hook up a PIR motion sensor to your embedded system and run the code with your endpoint, rootCA, certificate, and private key arguments. The code should start running seamlessly.

Next, go back to your AWS IoT portal, and click on the Act >> Rules section on the left navigation pane. Click “Create a rule”. Name your rule whatever you want, set the action “Send a message as an SNS push notification”, and click next. Create a new topic (and name it whatever you’d like), set the message format to “RAW”, and create a new IAM role. Click “Add Action”. Finally, scroll up and edit the SQL code to:

SELECT * FROM 'sdk/test/Python'

Finally, log in to the AWS SNS portal and create a new subscription. Click “Topic ARN” and it should appear instantly for you. Next, click the dropdown endpoint menu and select SMS. In the new box that should appear below, fill in your personal phone number.

For the final step, go back to your embedded system device and run basicPubSub.py. The result should be that you receive notifications whenever your PIR sensor detects new motion

Conclusion

Well there you have it, a super simple alarm system that costs 8 times less the initial infrastructure costs and infinitely less than the maintenance costs — because they’re are none! IoT is a flexible, powerful, and personalized exponential technology that will disrupt every industry in the future. The potential for the technology is limitless and there’s no telling what amazing technological advancements it will unlock for us. Thank you for reading my article! Claps and feedback would be appreciated.

--

--

Arnav Shah

14 y/o working on PCV13 distribution in low-income countries