Laurent Ellerbach, technical evangelist manager at Microsoft, presentation of the "Internet of (his garden) Things", explaining the technical architecture details and decisions.
Athens IoT meetup #7 - Create the Internet of your Things - Laurent Ellerbach (Microsoft)
1. Create The Internet
of Your Things
Laurent Ellerbach
laurelle@microsoft.com
Technical Evangelist Lead
Microsoft Central and Eastern Europe
http://blogs.msdn.com/laurelle
A developer introduction to Microsoft’s
approach to the Internet of Things
3. “”
What is the Internet of Things?
The network of physical
objects that contain
embedded technology to
communicate and interact
with their internal states or
the external environment.
Source: Gartner
4.
5.
6. Comprehensive IoT platform for developers
InsightsData AnalyticsCloud &
Infrastructure
Devices & Assets
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
Internet of Your Things
Development
7. IoT architecture simplified and key actors
Real time OS
Windows
Linux
No Operating Systems
Browser
Tablet, PC, Phone
Windows, Mac...
iOS, Android…
Cloud
Microsoft Azure, Amazon,
IBM, Google, etc, etc
8. Microsoft IoT
Comprehensive solutions from device to cloud
IoT Editions Power a Broad Range of Devices
20 years of history in embedded devices
One Windows platform for all devices
Enterprise-ready, Maker-friendly
Designed for today’s IoT environments
Free IoT Core edition!
Cloud-Based IoT Services & Solutions
Easy to provision, use and manage
Pay as you go, scale as you need
Global reach, hyper scale
End-to-end security & privacy
Windows, Mbed, Linux, iOS, Android, RTOS
support
Azure IoT
9. Microsoft Azure IoT services
Producers Connect Devices Storage Analytics Take Action
Event Hubs SQL Database
Machine
Learning
Azure Websites
Service Bus
Table/Blob
Storage
Stream
Analytics
Power BI
External Data
Sources
DocumentDB HDInsight
Notification
Hubs
External Data
Sources
Data Factory Mobile Services
BizTalk Services
{ }
10. Azure support any kind of devices, Windows,
Linux and more
Microsoft Azure
Certified for IoT:
http://www.azure.co
m/iotdev tests and
certifies IoT-
enabled platform,
device and
operating system
combinations
13. What I had in 1014 when I started
Few indoor/outdoor
temperature and humidity
Oregon Scientific sensors
Few ATmega328
(used in Arduino
boards)
Few Netduino using
.NET Microframework
Water arrivals in the
garden ☺ A great cloud
infrastructure, database,
website and more!
The best developer tools in
the world
14. Overall architecture of what I’ve build – v1 (Jun 2014)
433MHz
receiver
Spark.io
433MHz
emitter
ATmega328
sensors
SQL
Azure
Azure
Mobile
Services
HTTP REST
Azure Web
site (Web
App)
ASP.NET +
MVC +
Entity
Framework
+ jquery
Browser
sprinkler
Netduino running .NETMicroframework
HTTP
Gateway
22. Tools for Arduino development
+ • Visual Micro is free for
basic usage
• Great integration with
Visual Studio, support
projects type, template,
libraries
• Debugging thru serial and
USB
• Support bootloader flash
and more!
• Now working as well with
VS Code + Arduino
complement
29. RPI taking picture from greenhouse to Azure
Azure IoT Hub
• Device need to be
registered
• Node.js running on
RPI
• Azure IoT SDK
available on Github:
https://github.com/Az
ure/azure-iot-sdks
• C, C#, Java, node.js
• Azure IoT Hub can
receive data as well
from devices
• Manage devices key,
allow access…
Sending message
HTTPS
message
Sending
message
HTTPS
1. Node.js app
processing the
message
2. taking picture
3. Uploading into Azure
blob
4. Sending acknowledge
Can send as
well data
stora
ge
Event
hub…
SQL Azure
Blob storage
30. Inside the greenhouse ☺
https://portalvhdskb2vtjmyg3mg.blob.core.windows.net/webcam/picture
Code available on https://github.com/Ellerbach/nodejs-webcam-azure-iot
33. Some code
only main code, not complete
#define PIN_ANEMOMETER 3 // Digital 3
#define PIN_ALIMRF 4 //Digital 4
#define MSECS_CALC_WIND_SPEED 10 // 10 seconds for every wind speed
ulong nextCalcSpeed; // for interrupt management
byte OregonMessageBuffer[12]; // to store message before sending
void setup() {
pinMode(PIN_ANEMOMETER, INPUT);
// pull up interne
digitalWrite(PIN_ANEMOMETER, HIGH);
// interruption
attachInterrupt(0, countAnemometer, FALLING);
nextCalcSpeed = now() + MSECS_CALC_WIND_SPEED;
// other initialisation…
}
void loop() {
time = now();
// math and sending info happens only
// every 10 secondes, not bloking
if (time >= nextCalcSpeed) {
calcWindSpeed();
setWinMessage();
sendMessage();
nextCalcSpeed = time + MSECS_CALC_WIND_SPEED;
}
// Other treatments
}
// called at each interruption
// of anemometer
void countAnemometer() {
numRevsAnemometer++; }
float calcWindSpeed() {
// math in km/h
unsigned long speed = 6669;
speed = speed * numRevsAnemometer;
speed = speed / (MSECS_CALC_WIND_SPEED * 1000);
numRevsAnemometer = 0; // reset the interupt counter
myWind->addSpeed(speed); // store data in struct
return (speed); }
void setWinMessage() {
// create a message
byte ID[] = { 0x1A, 0x99 };
setType(OregonMessageBuffer, ID);
setChannel(OregonMessageBuffer, 0x20); // set channel
setId(OregonMessageBuffer, 0x12); // set ID
setBatteryLevel(OregonMessageBuffer, 1); // full battery
// fill buffer with speed direction, wind speed, average speed
setWind(OregonMessageBuffer, myWind->getInstantSpeed(), myWind->getAverageSpeed(),
myWind->getDirection());
byte numByteToSend = 10;
// create checksum
csWind(OregonMessageBuffer); }
void sendMessage() {
digitalWrite(PIN_ALIMRF, HIGH);
// wait 1sec the emitter is ready
// send 2 messages
delay(1000);
sendOregon(OregonMessageBuffer, numByteToSend);
SEND_LOW();
delayMicroseconds(TWOTIME * 8);
sendOregon(OregonMessageBuffer, numByteToSend);
SEND_LOW();
digitalWrite(PIN_ALIMRF, LOW); }
#define TX_PIN 5 // Digital 5
const unsigned long TIME = 512;
const unsigned long TWOTIME = TIME * 2;
// send an high/low signal
#define SEND_HIGH() digitalWrite(TX_PIN, HIGH)
#define SEND_LOW() digitalWrite(TX_PIN, LOW)
// send a bit 0
inline void sendZero(void) {
SEND_HIGH();
delayMicroseconds(TIME);
SEND_LOW();
delayMicroseconds(TWOTIME);
SEND_HIGH();
delayMicroseconds(TIME); }
// send a bit 1
inline void sendOne(void) {
SEND_LOW();
delayMicroseconds(TIME);
SEND_HIGH();
delayMicroseconds(TWOTIME);
SEND_LOW();
delayMicroseconds(TIME); }
// send 4 LBS bits
// same function for MBS
inline void sendQuarterLSB(const byte data) {
(bitRead(data, 0)) ? sendOne() : sendZero();
(bitRead(data, 1)) ? sendOne() : sendZero();
(bitRead(data, 2)) ? sendOne() : sendZero();
(bitRead(data, 3)) ? sendOne() : sendZero(); }
void sendOregon(byte *data, byte size) {
sendPreamble();
sendData(data, size);
sendPostamble(); }
// send all data
void sendData(byte *data, byte size) {
for (byte i = 0; i < size; ++i) {
sendQuarterLSB(data[i]);
sendQuarterMSB(data[i]); } }
34. What to do with the generated data?
101010100110001101010101110100110101010101001
101011101001110101010101101001101010101010100
35. Let insert a record in a table!
POST /tables/nomdelatable/ HTTP/1.1
X-ZUMO-APPLICATION: 123456789abcdef123456789abcdef12
Host: nomduservice.azure-mobile.net
Content-Length: 88
Connection: close
{"sensorID":22, "channel":5,
"instSpeed":12,"averSpeed":5,"direction":2,"batterylife
":90}
HTTP/1.1 201 Created
Cache-Control: no-cache
Content-Length: 133
Content-Type: application/json
Location: https://nomduservice.azure-
mobile.net/tables/weather//931CFDDE-AB7F-
4480-BA28-F1D5C611398B
Server: Microsoft-IIS/8.0
x-zumo-version:
Zumo.master.0.1.6.3803.Runtime
X-Powered-By: ASP.NET
Set-Cookie:
ARRAffinity=da4a9f7437a690e3c1a799d3a6c3ddf3e
e0cbb9f5a67008d3c919f0149f34ee3;Path=/;Domain
= nomduservice.azure-mobile.net
Date: Sun, 31 Aug 2014 15:40:12 GMT
Connection: close
{"sensorID":22,"channel":5,"instSpeed":12,"av
erSpeed":5,"direction":2,"batterylife":90,"id
":"931CFDDE-AB7F-4480-BA28-F1D5C611398B"}
Sent using POST on socket port 80
Received from the server
36. Arduino code to post in Azure Mobile Services
yes, it’s that simple!
TCPClient client;
byte AzureServer[] = { 12, 34, 56, 78 };
String writeJsonWind(struct wind wd) {
// Create a simple JSON;
String datastring = "{"sensorID":";
datastring += String(wd.ID);
datastring += ","channel":";
datastring += String(wd.channel);
datastring += ","instSpeed":";
datastring += String(wd.instantSpeed);
datastring += ","averSpeed":";
datastring += String(wd.averageSpeed);
datastring += ","direction":";
datastring += String(wd.direction);
datastring += ","batterylife":";
datastring += String(wd.bat);
datastring += "}";
return (datastring);
}
// Sending data is simple, create a JSON, and send it on port 80!
String dataString = writeJsonWind(myWind);
sendData(dataString);
void sendData(String thisData) {
// create a connection to port 80 on the server
// IP is your Mobile Services address
if (client.connect(AzureServer, 80))
{
//Serial.println("Connected to Azure Server");
// create the REST request using POST
// Nomdelatable is name of the table
client.print("POST /tables/nomdelatable/");
client.println(" HTTP/1.1");
// use the application key
client.println("X-ZUMO-APPLICATION:
123456789abcdef123456789abcdef12");
// host name is name of your Azure Mobile Service
client.println("Host: nomdumobileservice.azure-
mobile.net");
client.print("Content-Length: ");
client.println(thisData.length());
client.println("Connection: close");
client.println();
// and finally data!
client.println(thisData);
}
else { // in case of error, stop connection
client.stop();
} }
41. RPI taking picture from greenhouse to Azure
Azure IoT Hub
• Device need to be
registered
• Node.js running on
RPI
• Azure IoT SDK
available on Github:
https://github.com/Az
ure/azure-iot-sdks
• C, C#, Java, node.js
• Azure IoT Hub can
receive data as well
from devices
• Manage devices key,
allow access…
Sending message
HTTPS
message
Sending
message
HTTPS
1. Node.js app
processing the
message
2. taking picture
3. Uploading into Azure
blob
4. Sending acknowledge
Can send as
well data
stora
ge
Event
hub…
SQL Azure
Blob storage
42. Inside the greenhouse ☺
https://portalvhdskb2vtjmyg3mg.blob.core.windows.net/webcam/picture
Code available on https://github.com/Ellerbach/nodejs-webcam-azure-iot
44. What to do with the data?
101010100110001101010101110100110101010101001101110111101110010101000011010
101011101001110101010101101001101010101010100110110001010111101001110101010
49. • Intake millions of events per
second
• Easy processing on continuous
streams of data
• Correlate streaming with reference
data
• Guaranteed events delivery
• Elasticity of the cloud for scale up
or scale down
• Low startup costs
50. Using Stream Analytics
WITH mydata as (
SELECT
CAST(WindSpeed as bigint) as speed,
CAST(WindSpeedAverage as float) as average,
CAST(WindDirection as bigint) as direction,
CAST(SensorID as bigint) as sensorID,
CAST(Temperature as float) as temperature,
CAST(Humidity as float) as humidity,
CAST(Luminosity as bigint) as liminosite,
CAST(SoilHumidity as bigint) as soilhumid
FROM arrosageinput)
SELECT speed, average, direction, sensorID
INTO
arrosagewind
FROM mydata
SELECT temperature, humidity, liminosite,
soilhumid, sensorID
INTO
arrosagehum
FROM mydata
52. Why API in v2?
using System.Net;
using System.Net.Http;
using System.Web;
using System.Web.Http;
using Newtonsoft.Json;
using System.IO;
using System.Text;
namespace WeatherAPI.Controllers
{
public class WeatherController : ApiController
{
// GET api/weather
public ForecastData GetForecast(String location)
{
//Building parameter
String baseURL = "https://query.yahooapis.com/v1/public/yql";
String yqlQuery = "select * from weather.forecast where woeid in (select woeid from
geo.places(1) where text='" + location + "')";
String format = "json";
String requestURL = baseURL + "?q=" + HttpUtility.UrlEncode(yqlQuery) + "&format=" + format;
//Creating WebRequest and getting the response
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
//Response stream to string
String responseString;
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
//Deserialize response to object
ForecastData forecastData = JsonConvert.DeserializeObject<ForecastData>(responseString);
return forecastData;
}
}
}
xhr.open("GET", "https://microsoft-
apiappccd711277be14956b169a7c59837294a.azurewebsi
tes.net:443/api/Recommandation", true);
53. What to do with the analytics?
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
58. The bot architecture: example with email
Raspberry PI running
Linux and node.js
Azure IoT Hub
Message
(picture)
SQL Azure
Blob storage
Web App, Bot framework
Bot providers
68. The sprinkler architecture
Netduino
http
1 Page to manage programming
1 to manage sprinkler opening
and closing
Simple browser as a client
2 Pages to manage calendar and
programming
Timer to launch psrinkler and automated mode
• Used in production for all summer
• Fully REST API based
• Can be accessed by apps, simple key
security
• Fully customizable with settings in SD card
71. HTTP Get server code
http://blogs.msdn.com/laur
elle
http://netmfwebserver.code
plex.com/
private void StartServer() {
using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
{ //set a receive Timeout to avoid too long connection
server.ReceiveTimeout= this.Timeout;
server.Bind(new IPEndPoint(IPAddress.Any, this.Port));
server.Listen(int.MaxValue); while (!cancel)
{ try { using (Socket connection= server.Accept())
{ if (connection.Poll(-1, SelectMode.SelectRead))
{ // Create buffer and receive raw bytes.
byte[] bytes = new byte[connection.Available];
int count = connection.Receive(bytes);
Debug.Print("Request received from " + connection.RemoteEndPoint.ToString() + " at " +
DateTime.Now.ToString("dd MMM yyyy HH:mm:ss"));
//stup some time for send timeout as 10s. //necessary to avoid any problem when multiple requests are done the
same time.
connection.SendTimeout= this.Timeout; ;
// Convert to string, will include HTTP headers.
string rawData = new string(Encoding.UTF8.GetChars(bytes));
string mURI;
// Remove GET + Space
// pull out uri and remove the first /
if (rawData.Length > 5)
{ int uriStart = rawData.IndexOf(' ') + 2;
mURI = rawData.Substring(uriStart, rawData.IndexOf(' ', uriStart) - uriStart);
} else mURI = "";
// return a simple header
string header = "HTTP/1.1 200 OKrnContent-Type:text/html; charset=utf-
8rnConnection: closernrn";
connection.Send(Encoding.UTF8.GetBytes(header), header.Length,SocketFlags.None);
if (CommandReceived != null)
CommandReceived(this, new WebServerEventArgs(connection,mURI)); } } } catch
(Exception e) { //this may be due to a bad IP address Debug.Print(e.Message); } } } }
72. Code to consume Azure Mobile Services
custom API
// http_Client is very simple http client
// IntegratedSocket is a class making easy socket usage
// All is really very simple
HTTP_Client myClient = new HTTP_Client(new
IntegratedSocket("nomduservice.azure-mobile.net", 80));
String myRequest = "GET http://nomduservice.azure-
mobile.net/api/nomAPI";
// nomduservice and nomAPI are names of service and of API
myRequest += " HTTP/1.1rn";
myRequest += "Accept: application/jsonrn";
// the key to use is the application key
myRequest += "X-ZUMO-APPLICATION:
123456789abcdefghij123456789abcdrn";
myRequest += "Host: nomduservice.azure-mobile.netrn";
myRequest += "Connection: Closern";
myRequest += "rn";
HTTP_Client.HTTP_Response response = myClient._DoRequest(myRequest);
if (response.ResponseCode == 200) {
// search for the resturned value
}
HTTP/1.1 200 OKrnCache-Control: no-
cachernContent-Length: 18rnContent-Type:
application/json; charset=utf-8rnServer:
Microsoft-IIS/8.0rnx-zumo-version:
Zumo.master.0.1.6.3711.RuntimernX-Powered-By:
ASP.NETrnSet-Cookie:
ARRAffinity=09482d5b42db702a74aa7bd65eb9fb93fe0f432
10a649f6bd3c17386ab00447d;Path=/;Domain=arrosage.az
ure-mobile.netrnDate: Sat, 16 Aug 2014 17:09:52
GMTrnConnection:
closernrn[{"soilhumid":38}]
78. Azure is a market leader in compliance coverage
USGov
HIPAA/
HITECH Act
Moderate
JAB P-ATO FIPS 140-2
FERPA
DoD DISA
SRG Level 2 ITARCJIS
GxP
21 CFR Part 11
IRS1075Section
508 VPAT
ISO 27001
SOC 1
Type 2ISO 27018
CSA STAR
Self-Assessment
Regional
Singapore
MTCS
UK
G-Cloud
Australia
IRAP/CCSL
FISC
Japan
China
MLPS
New
Zealand
GCIO
China
GB 18030
EU
Model Clauses
ENISA
IAF
Argentina
PDPA
Japan CS
MarkGold
SP 800-171
China
TRUCS
Spain
ENS
PCI DSS
Level 1 CDSA
Shared
Assessments
MPAA
Japan My
Number Act
FACT
UK
High
JAB P-ATO
GLBA
DoD DISA
SRG Level 4
MARS-E FFIEC
ISO 27017
SOC 2
Type 2
SOC 3
India
MeitY
Canada
Privacy
Laws
Privacy
Shield
ISO 22301
GermanyIT
Grundschutz
workbook
Spain
DPA
CSA STAR
Certification
CSA STAR
Attestation
IndustryGlobal
79. Only Microsoft delivers across the board
Do they
have the
experience?
Can they
scale?
Are they
open?
Will they
accelerate
time to
market?
Are they
complete?
88. Comprehensive IoT platform for developers
InsightsData AnalyticsCloud &
Infrastructure
Devices & Assets
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
1010101001100011010101011101001101010101010011011101111011100101010000110101010111010011010
1010111010011101010101011010011010101010101001101100010101111010011101010101011011110100111
Internet of Your Things
Development