With each passing day, we are getting hooked on to an increasing number of small devices. Besides, the Internet drives our lives like never before. It is obvious, as well as natural, that the connectivity of these small devices with the Internet, ultimately, will lead towards their inter-connectivity; where not only data exchange but decision making will be a shared responsibility of these smart devices. That means the real value of Internet of Things (IoT) does not lie in just home automation, but rather in the data collection by these smart devices and analytics, further up the value chain.
In this article, we will explore the possibility of developing applications for IoT devices that capture data from low-cost sensors and communicate with real-time scalable services in Windows Azure – primarily using Open Source Technologies for devices and Managed Services in Azure.
Connected Devices vs People
In the last decade, we have seen multiple platforms (through the power of Internet) facilitate all facets of our communication – email, chat, meetups, networking or career development. People have more than one device that allows them to remain connected to the Internet to access platforms like Facebook, Twitter, WhatsApp, LinkedIn, Meetup, etc. With the current trend, soon the number of Internet connected devices (Internet-of-things, aka IoT) will outnumber the world population. While this increase in the number of Internet-connected devices will increase the network traffic and will force us to adopt IPv6, it will also open the door to new opportunities for developers, security analysts, business houses and governments.
This article is published from the DNC Magazine for .NET Developers and Architects. Download this magazine from here [PDF] or Subscribe to this magazine for FREE and download all previous and current editions
As developers and architects, it becomes essential for us to think of IoT from the aspects of scale of operation, autonomously connected devices, interoperability between them and seamless collection of data captured by these IoT devices into a centralized data store, that can be used for analytics. This makes the marryiage of IoT with the Cloud, perfect!
Internet of Things and Azure – The Way Ahead
There are several IoT boards available in the market and new ones are getting released every month. Whichever board we choose, the basic process of getting our board connected to the cloud remains the same. The 4 essential steps to have our sensors stream or send data to the cloud are:
1. Connect the device that we have: start with connecting sensors to our device and device to the Ethernet/Wireless network.
2. Utilize the Cloud Services: build services (Worker Roles, Web Roles, Jobs) that run in the cloud and help in persisting data in one of the data stores like SQL database, DocumentDB, MongoDB, Blobs, etc.
3. Combine data collected from devices: With service contracts ready in step 2, we need to ensure that our device consumes the service contracts and is able to push the sensor data to cloud services.
4. Generate new insights from data collected: From the network of IoT devices, the collected data can be used to feed Big Data platforms (like HDInsight) for the purpose of analytics.
Typical Tech Stack with Open Source
Choosing the right platform for IoT is an arduous task. The platform, while providing an ease of development, should be extensible to any other IoT board with little modification, should not compromise on the execution speed or security and should execute our code with low-energy factor. Some of the languages that meet the qualifying criteria for IoT platforms are - C, CPP and JavaScript. Choosing a language from these is a matter of personal preference. For this article, we will embrace the open-source technology stack and will explore JavaScript on IoT.
So our tech stack appears like the following:
Whether we use Raspberry Pi, Arduino or Intel Galileo board, the same tech stack can be used with the example illustrated in the sections to follow.
Editorial Note: For those who want to try this sample on RaspberryPi, please note that Pi cannot read analog input from FS Resistor. Additional analog to digital converter can be added to original circuit to make this project work. Please see http://acaird.github.io/computers/2015/01/07/raspberry-pi-fsr/ for more information (feedback provided by Shoban Kumar @shobankr).
Smart Garbage Bin using Azure, Node and JavaScript
One of the ideas that really fascinates me is the Smart Garbage Bin that some nations have adopted. Smart Garbage Bins tend to decrease the operational cost of monitoring the garbage bins by intelligent monitoring for waste and recyclables. There are different versions of Smart Bins available in market but our rationale (for this article) is -
We need to develop a smart bin that detects if the bin is full and should report to a centralized cloud service. Detection of level of garbage in the bin can be done either by calibrating the weight of garbage or the height of garbage in the bin.
And as mentioned earlier, we will follow the 4 step process to accomplish this.
Setting up the IoT board
To begin with, we need the following electronic components:
- IoT board – let’s take Intel Galileo Gen 2 running Yocto (Embedded Linux)
- Force sensitive resistor (FSR) 0.5” or 6” (depending upon surface area of bin)
- Resistor – 22K Ω
- LED Matrix 8x16 HT16K33
- Jumper cables
- Breadboard
The wiring of the Intel Galileo Gen 2 board with FSR sensor and LED matrix needs to be done as shown below:
This setup will then be placed at the bottom of the bin so that we can measure the force of the garbage on the bin.
Setting up the Azure Environment
With the tech stack mentioned earlier, we are aiming to have our IoT device code use Javascript/jQuery to send the sensor data to Azure Cloud Services. From an Azure perspective, we have the option to choose one of the multiple ways available to receive this data, for e.g. service bus queues/topics, event hubs, blobs, tables, etc. For this application, we will use Azure Service Bus Queues.
So as the next step, we need to create a queue on Azure Management Portal (or using PowerShell scripts) with name Q.FromSensorRealtimeValue
Once the queue has been created, we can navigate to the Configure tab and create shared access policy with the following settings:
- Name: DeviceSharedKey
- Permissions: Send
This will restrict the device to only publish messages to the queue.
Now we need a persistent store, like SQL Database, to store messages we receive on this queue. We need to create a new database using Azure Management Portal and create one table in this new database.
The script of the table is as shown here:
CREATE TABLE [dbo].[FSR](
[ID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
[MeasuredValueF] [numeric](7, 2) NOT NULL,
[DeviceName] [varchar](30) NOT NULL,
[RecordedAt] [datetime] NOT NULL,
[ReceivedAt] [datetime] NULL,
[MessageJSON] [ntext] NULL
)
GO
IoT – Cross-Platform, Open Source code
Javascript based platform NodeJS gives us the flexibility to write code regardless of any platform, providing us with over thousands of npm modules to do almost everything that we can do with managed code like C# and Java. So we can write and build our IoT code using NodeJS and then run it on any device / platform. For this application, we will require 4 npm modules to run with NodeJS – os, azure, galileo-io and johnny-five. If these modules are not installed on your IoT device, we can execute the following installation commands:
npm install os
npm install azure
npm install galileo-io
npm install johnny-five
Once the modules have been installed on our IoT device, we can paste the following code snippet in a file (say, smartbin.js)
var serviceBusConnectionString = "Endpoint=sb://iotcomm-ns.servicebus.windows.net/;SharedAccessKeyName=DeviceSharedKey;SharedAccessKey=1OD0KM8EjhNmrnlcSTwFfTBQ7xOs9yALpJSwVjP4sIw=";
var os = require("os");
var azure = require('azure');
var Galileo = require("galileo-io");
var five = require("johnny-five");
var serviceBusService = azure.createServiceBusService(serviceBusConnectionString);
console.log('Connected to Azure');
var board = new five.Board({
io: new Galileo()
});
board.on("ready", function () {
console.log("Connection Established with IoT device");
var fsr = new five.Sensor({
pin: "A0",
freq: 60000
});
var matrix = new five.Led.Matrix({
controller: "HT16K33",
addresses: [0x70],
dims: "8x16",
rotation: 2
});
var open = [
"0000000000000000", "0011110000111100",
"0100001001000010", "1001100110011001",
"1001100110011001", "0100001001000010",
"0011110000111100", "0000000000000000",
];
var closed = [
"0000000000000000", "0000000000000000",
"0000000000000000", "0000000000000000",
"0000000000000000", "0000000000000000",
"0000000000000000", "0000000000000000",
];
var THRESHOLD = 500;
fsr.scale([0, 1000]).on("data", function () {
if (this.value > THRESHOLD) {
var message = {
Hostname: os.hostname(),
SensorType: "FSR",
MeasuredValue: this.value,
RecordedAt: new Date()
};
matrix.draw(closed);
serviceBusService.sendQueueMessage("Q.FromSensorRealtimeValue", JSON.stringify(message), function (error) {
if (!error) {
console.log("FSR sent to Azure Queue");
}
else {
console.log("Error sending to Azure" + error);
}
}); //sendQueueMessage
}
else {
matrix.draw(open);
}
}); //fsr.on("data")
}); //board.on('ready')
To deploy this code on our IoT device, we can use FTP tools like FileZilla or use shared folders. Once we have telnet / putty to the device, we can run our IoT NodeJS code using
node smartbin.js
The code will connect to Azure using the connection string and will then initialize the Galileo board using Johnny-Five libraries.
Johnny-Five is Firmata protocol based open-source framework, that can be used to write programs on all Arduino models, Electric Imp, Beagle Bone, Intel Galileo & Edison, Linino One, Pinoccio, pcDuino3, Raspberry Pi, Spark Core, TI Launchpad and more with almost negligible code changes. The library exposes a board object which raises an event ‘ready’ once the board has been initialized.
Once the board is ready, at a frequency of every 1 minute (60000 millisecond), analog sensor value (i.e. force measured by FSR) on the pin A0 will be determined and the output will be scaled on a range of 0 to 1000.
When the force value goes beyond 500 (i.e. 50% of scaled value 0-1000), it will publish a message to Azure Queue and will dim off the display in LED matrix.
A sample message on the queue will appear:
{
"Hostname": "quark09877",
"SensorType": "FSR",
"MeasuredValue": 700,
"RecordedAt": "Wed Apr 29 2015 18:00:10 GMT+0000"
}
When we expand this solution to run on a network of IoT devices, we should ensure that the time-zones in the devices are either set to UTC and are synchronized, or the Azure Worker Role handles different time-zones.
Azure – Managed code to collect IoT data
To collect the data sent by IoT device, we need a Worker Role process that can pop the message out of the Service Bus Queue and save it in SQL database using Entity Framework. A typical Worker Role requires implementation of 3 methods – OnStart, Run and OnStop. Our Worker Role process will initiate the queue connection in OnStart method, subscribe to the Queue in Run method and should close the queue connection in OnStop method. Here’s the C# code for it:
public override void Run()
{
Trace.WriteLine("Starting processing of messages");
_queueClient.OnMessage((receivedMessage) => ProcessMessage(receivedMessage));
CompletedEvent.WaitOne();
}
private void ProcessMessage(BrokeredMessage receivedMessage)
{
try
{
DateTime receivedAt = DateTime.UtcNow;
Trace.WriteLine("Processing Service Bus message: " +
receivedMessage.SequenceNumber.ToString());
Stream stream = receivedMessage.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string messageBody = reader.ReadToEnd();
Trace.WriteLine("Message > " + messageBody);
var sensorMessage = JsonConvert.DeserializeObject<SensorMessage>(messageBody);
var sender = sensorMessage.Hostname.ToUpper();
if (sensorMessage.SensorType == SensorType.FSR)
{
using (var unitOfWork = new UnitOfWork())
{
decimal measuredValue = -1;
if (decimal.TryParse(sensorMessage.MeasuredValue, out measuredValue))
{
var fsr = new FSR();
fsr.MeasuredValue = measuredValue;
fsr.DeviceName = sensorMessage.Hostname;
fsr.ReceivedAt = receivedAt;
fsr.MessageJSON = messageBody;
fsr.RecordedAt = sensorMessage.RecordedAt;
unitOfWork.Add<FSR>(fsr);
}
}
}
receivedMessage.Complete();
}
catch (Exception ex)
{
Trace.TraceError(@"Error saving a FSR record due to exception: " + ex.ToString());
receivedMessage.Abandon();
}
}
The method ProcessMessage gets invoked when a sensor message is received in the queue. The BrokeredMessage is designed to support XML serialization, so we have to retrieve the message body as a Stream object and parse it to JSON format using Newtonsoft.Json Nuget package. Once we have an object of the sensor data, we can store it in a database (possibly, using Entity Framework or ADO.NET) for analytics purpose.
The code we just saw can be extended to receive data from any sensor attached to any IoT device as far as the device can connect to the Internet.
Beyond reporting measurement
When we are looking forward to building a production-ready IoT device, we would require more efforts in reducing the size of device and ensuring low-battery consumption. For projects like Smart Garbage Bin, we can use solar energy to power our device and we could reduce the frequency of checking the force from 1 minute to 15 minutes.
If we are aiming at creating a network of such IoT devices, we would require more services than just storing this data into database. We can explore several avenues of sending this data to tools like Azure SQL Data Warehouse, Azure Data Lake or Hadoop for trend analysis and then have actions taken based on patterns like peak load time or recycle duration.
With IoT and Cloud, the possibilities of increasing automation and building smarter homes, cities and nations appear to be seamless!
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Punit, a Microsoft .NET MVP and DZone MVB, is the author of 18 technical whitepapers published in DeveloperIQ and a book on C programming. He is an expert at Application Design & Development, Performance Optimization and defining Architecture for hybrid systems involving Microsoft, Open-Source and Messaging Platforms. He is founder of KonfDB platform and runs a blogging platform Codetails, organizes .NET sessions in Singapore, has spoken in various international forums. He maintains his blog at
www.ganshani.com