SlideShare a Scribd company logo
Programming IoT Gateways
in JavaScript with macchina.io
Günter Obiltschnig
Applied Informatics Software Engineering GmbH
guenter@appinf.com
@obiltschnig, @macchina_io
About Me
hard-core C++ developer (20+ years), who also likes JavaScript
“full stack++”, embedded, hardware to web frontend + cloud
POCO C++ Libraries (2004)
Applied Informatics GmbH (2006)
my-devices.net (2010)
AIS Radar for iOS (2011)
macchina.io (2013)
m .ioacchina
A modular open source toolkit for building embedded IoT
applications that connect sensors, devices and cloud services.
IoT Gateway
devices.netCloud Services
AirVantage, Bluemix,
Tinamous, Xively, etc.
HTTP(S)
MQTT
Remote Access
my-devices.net
device apps
local“business logic”
web services
web visualization
database
discoverability
Mobile/Web
Clients
Devices/Sensor Networks
CoAP, IEEE 802.15.4,
Modbus, USB,
Bluetooth,
RS-232
Programming IoT Gateways in JavaScript with macchina.io
> open source (Apache 2.0 License)
> built in C++ for best performance and efficiency 

(JavaScript for parts of web interface)
> modular and extensible
> mature, proven codebase: 

POCO C++ Libraries, Google V8, Eclipse Paho, SQLite

AngularJS, jQuery, OpenLayers, Ace (text editor),

+ Applied Informatics OSP and Remoting frameworks
> C++-to-JavaScript bridge
> Raspberry Pi, Beaglebone, Edison, RED, MangOH, etc.
> prototype on Linux or OS X host, easily deploy to device
> web interface with JavaScript editor
Sensors & Devices Protocols Cloud Services
Temperature, Ambient Light, 

Humidity, Air Pressure, etc.
HTTP AirVantage
I/O, Trigger, Rotary Encoder MQTT Bluemix
Accelerometer CoAP* Twitter
GNSS/GPS WebEvent Twilio (SMS)
Barcode Reader, RFID* WebTunnel my-devices.net
XBee (ZigBee, IEEE 802.15.4) XBee API any with HTTP/REST APIs
Serial Port Modbus*, CANopen*
* planned
Pro Users and Device Manufacturers
> add device specific APIs
> make devices programmable in JavaScript for partners or end users
> device specific app store (sell additional software features)
> additional frameworks (UPnP, Remoting SOAP and JSON-RPC)
> customizable web user interface
> improved user authentication and authorization
> signed bundles
> pro support
Demo
Inside macchina.io
Programming IoT Gateways in JavaScript with macchina.io
POCO C++ Libraries
> Started 2004
> ~300.000 LOC
> 1000+ classes
> on GitHub since 2012 

1000+ stars

400+ forks

30-50 clones/day
> ~100 contributors
> Boost License
> http://pocoproject.org
POSIX, WIN32, other (RT)OS API
Foundation
C++ and C Standard LibrariesApplication
Zip
Net
Crypto
Data
SQLite
ODBC
MySQL
NetSSL
Util
Tools, Utilities and
additional Libraries
XML JSON
V8
> Google’s JavaScript Engine
> Used by Chrome/Chromium and node.js
> C++ library, (reasonably) easy to integrate and to extend
> Compiles JavaScript to native code (x86, ARM, MIPS)
> Great performance
> BSD License
Remoting
> Similar to .NET Remoting or Java RMI, but for C++
> Code generator parses annotated C++ header files and generates code

(serialization/deserialization, method dispatching, helpers)
> Supports different transports (binary TCP, SOAP, JSON-RPC)
> Used for automatic C++-to-JavaScript bridging
> Will also be used to implement sandbox mechanism
Open Service Platform (OSP)
> Inspired by OSGi, but for C++ (also JavaScript, Python, etc.)
> Dynamic module system based on bundles

(Zip files with metadata, 

shared libs, other files)
> Dependency and 

lifecycle management
> Services and service registry
> Web Server
POCO Core Libraries
(Foundation,XML,Util,Net)
Operating
System
API
Std.C/C++
Libraries
Service
Registry
Portable Runtime
Environment
Life
C
ycle
M
anagem
ent
Bundle
M
anagem
ent
Standard
Services
Bundles
install,resolve,start,stop
and uninstall bundles
provide services to other
bundles and find services
provided by other bundles
manage bundle versions
and dependencies
web server,
web- and console-
based management,
user authentication
and authorization,
preferences,etc.
application-specific
functionality and services
Combining POCO C++ Libraries and V8
> JavaScript is single-threaded and garbage-collected
> POCO is multithreaded (specifically web server)
> Make C++ object available to JavaScript

easy for static objects, just provide Wrapper
> Allow JavaScript code to create C++ objects

easy if you don’t care about memory/resource leaks
> Register a callback function called by GC when object is deleted

allows you to properly delete underlying c++ object
> However, V8 does not do callbacks when script ends

wrapped C++ objects won’t be deleted, leaks resulting
> Need to track every C++ object a script creates and clean up afterwards :-(
Automatic JavaScript
Wrappers for C++ Objects
// Sensor.h
//@ remote
class Sensor: public Device
{
public:
Poco::BasicEvent<const double> valueChanged;
virtual double value() const = 0;
virtual bool ready() const = 0;
};
Sensor.h
RemoteGen
lots of generated source files
RemoteGen.xml
Service
<<generatedFrom>>
IService
ServiceProxy
Service
RemoteObject
The interface class has
all @remote methods
from the service class.
Service
Skeleton
<<invokes>>
<<generated>>
<<generated>><<generated>>
<<generated>>
Service
ServerHelper
<<generated>>
Registers
Skeleton, RemoteObject
and EventDispatcher (if
needed) with the Object
Request Broker.
Service
ProxyFactory
<<creates>>
<<generated>>
Service
ClientHelper
<<generated>>
Registers ProxyFactory
with the Object Request
Broker.
<<registers>><<registers>>
<<registers>>
Service
EventSubscriber
<<generated>>
Service
EventDispatcher
<<generated>>
<<registers>>
var tempSensor = ...;
tempSensor.on(‘valueChanged', function(ev) {
var temp = ev.data;
// ...
});
if (tempSensor.ready())
{
var temp = tempSensor.value();
// ...
}
JavaScript Samples
// sensors.js (search sensors by physical quantity)
var sensors = {};
var illuminanceRefs = serviceRegistry.find(
'io.macchina.physicalQuantity == "illuminance"');
if (illuminanceRefs.length > 0)
{
sensors.illuminance = illuminanceRefs[0].instance();
}
var temperatureRefs = serviceRegistry.find(
'io.macchina.physicalQuantity == "temperature"');
if (temperatureRefs.length > 0)
{
sensors.temperature = temperatureRefs[0].instance();
}
var humidityRefs = serviceRegistry.find(
'io.macchina.physicalQuantity == "humidity"');
if (humidityRefs.length > 0)
{
sensors.humidity = humidityRefs[0].instance();
}
module.exports = sensors;
// sensors.js (search sensors by ID)
var sensors = {};
var illuminanceRef = serviceRegistry.findByName(
'io.macchina.xbee.sensor.illuminance#0013A20040A4D7F7');
if (illuminanceRef)
{
sensors.illuminance = illuminanceRef.instance();
}
var temperatureRef = serviceRegistry.findByName(
'io.macchina.xbee.sensor.temperature#0013A20040A4D7F7');
if (temperatureRef)
{
sensors.temperature = temperatureRef.instance();
}
var humidityRef = serviceRegistry.findByName(
'io.macchina.xbee.sensor.humidity#0013A20040A4D7F7');
if (humidityRef)
{
sensors.humidity = humidityRef.instance();
}
module.exports = sensors;
// database.js
var database = {};
database.path = bundle.persistentDirectory + "logger.db";
database.session = new DBSession('SQLite', database.path);
database.logIntervalSeconds = application.config.getInt(
"datalogger.intervalSeconds", 30);
database.keepDataSeconds = application.config.getInt(
"datalogger.keepDataSeconds", 3600);
module.exports = database;
// logger.js
var sensors = require('sensors.js');
var db = require('database.js');
db.session.execute('PRAGMA journal_mode=WAL');
db.session.execute('CREATE TABLE IF NOT EXISTS datalog ( 
timestamp INTEGER, 
illuminance FLOAT, 
temperature FLOAT, 
humidity FLOAT 
)');
setInterval(
function()
{
db.session.execute('INSERT INTO datalog VALUES (?, ?, ?, ?)',
DateTime().epoch,
sensors.illuminance.value(),
sensors.temperature.value(),
sensors.humidity.value());
},
db.logIntervalSeconds*1000);
// logger.js (continued)
setInterval(
function()
{
var cutoffTime = DateTime().epoch - db.keepDataSeconds;
db.session.execute('DELETE FROM datalog WHERE timestamp < ?',
cutoffTime);
},
db.keepDataSeconds*1000);
// history.jss
var db = require(‘../database.js');
var validItems = ['temperature', 'humidity', 'illuminance'];
var data = [];
db.session.pageSize = form.maxItems ? parseInt(form.maxItems) : 20;
var item = form.item;
if (validItems.indexOf(item) > -1)
{
var recordSet = db.session.execute(
'SELECT timestamp, ' + item + ' FROM datalog ORDER BY timestamp DESC');
// history.jss (continued)
for (var row = 0; row < recordSet.rowCount; row++)
{
var time = recordSet.getValue('timestamp');
var value = recordSet.getValue(item);
var date = LocalDateTime('1970-01-01');
date.addSeconds(time);
data[recordSet.rowCount - row - 1] =
{
timestamp: date.format('%H:%M:%S'),
value: value
};
recordSet.moveNext();
}
recordSet.close();
}
response.contentType = 'application/json';
response.write(JSON.stringify(data));
response.send();
// MQTT to AirVantage
var sensors = require('sensors.js');
var mqttClientRefs = serviceRegistry.find(
'io.macchina.mqtt.serverURI == "tcp://na.airvantage.net:1883"');
if (mqttClientRefs.length > 0)
{
logger.information("MQTT Client found!");
var mqttClient = mqttClientRefs[0].instance();
setInterval(function() {
var epoch = "" + 1000*DateTime().epoch; // seconds to milliseconds
var payload = {};
payload[epoch] = {
"sensors.temperature": sensors.temperature.value(),
"sensors.humidity": sensors.humidity.value()
"sensors.illuminance": sensors.illuminance.value()
};
mqttClient.publish('JA347400060803/messages/json', 

JSON.stringify(payload), 0);
}, 10000);
}
// Send SMS via Twilio
function sendSMS(to, message)
{
var accountSID = application.config.getString("twilio.accountSID");
var authToken = application.config.getString("twilio.authToken");
var from = application.config.getString(“twilio.from");
var twilioHttpRequest = new HTTPRequest(
"POST",
"https://api.twilio.com/2010-04-01/Accounts/"
+ accountSID
+ "/SMS/Messages"
);
twilioHttpRequest.authenticate(accountSID, authToken);
twilioHttpRequest.contentType = "application/x-www-form-urlencoded";
twilioHttpRequest.content =
"From=" + encodeURIComponent(from) +
"&To=" + encodeURIComponent(to) +
"&Body=" + encodeURIComponent(message);
twilioHttpRequest.send(function(result) {
logger.information("Twilio SMS Response: ",
result.response.status,
result.response.content);
});
}
var sensors = require('sensors.js');
var enableSMS = true;
sensors.illuminance.on('valueChanged', function(ev) {
logger.notice("valueChanged: " + ev.data);
if (ev.data < 10)
{
logger.warning("Lights out!");
if (enableSMS)
{
sendSMS("+436765166737", "Lights out!");
enableSMS = false;
}
}
else if (ev.data > 50)
{
enableSMS = true;
}
});
Q&A
guenter@appinf.com | @obiltschnig | obiltschnig.com
macchina.io | my-devices.net | pocoproject.org | www.appinf.com

More Related Content

PDF
Programming IoT Gateways with macchina.io
PDF
Browser-based Secure Remote Access for the Internet of Things
PDF
POCO C++ Libraries Intro and Overview
PDF
Mastering the IoT With JavaScript and C++ - Günter Obiltschnig
PPTX
Cnam azure 2014 mobile services
DOCX
Laporan multi client
PPTX
201410 2 fiware-orion-contextbroker
KEY
Whats new in iOS5
Programming IoT Gateways with macchina.io
Browser-based Secure Remote Access for the Internet of Things
POCO C++ Libraries Intro and Overview
Mastering the IoT With JavaScript and C++ - Günter Obiltschnig
Cnam azure 2014 mobile services
Laporan multi client
201410 2 fiware-orion-contextbroker
Whats new in iOS5

What's hot (18)

PDF
Arduino、Web 到 IoT
PDF
Do you know what your drupal is doing? Observe it!
PPTX
C#을 이용한 task 병렬화와 비동기 패턴
PPTX
Jafka guide
PDF
Ice mini guide
PDF
NoSQL and JavaScript: a love story
PDF
Security and performance designs for client-server communications
PDF
FwDays 2021: Metarhia Technology Stack for Node.js
PDF
Http4s, Doobie and Circe: The Functional Web Stack
PPTX
Python database interfaces
PPTX
Taking advantage of the Amazon Web Services (AWS) Family
ODP
Networking and Data Access with Eqela
KEY
What is the ServiceStack?
PPTX
The zen of async: Best practices for best performance
PDF
Source Code for Dpilot
PDF
Dpilot Source Code With ScreenShots
PDF
Node.js in production
PPTX
Java Persistence Frameworks for MongoDB
Arduino、Web 到 IoT
Do you know what your drupal is doing? Observe it!
C#을 이용한 task 병렬화와 비동기 패턴
Jafka guide
Ice mini guide
NoSQL and JavaScript: a love story
Security and performance designs for client-server communications
FwDays 2021: Metarhia Technology Stack for Node.js
Http4s, Doobie and Circe: The Functional Web Stack
Python database interfaces
Taking advantage of the Amazon Web Services (AWS) Family
Networking and Data Access with Eqela
What is the ServiceStack?
The zen of async: Best practices for best performance
Source Code for Dpilot
Dpilot Source Code With ScreenShots
Node.js in production
Java Persistence Frameworks for MongoDB
Ad

Viewers also liked (20)

PDF
Welcome
PDF
ApacheCon NA11 - Apache Celix, Universal OSGi?
PDF
The tools & technologies behind Resin.io
PDF
IoTcloud-cybersecurity-securityofthings
PDF
Lab IoT 2016
PDF
Introduction to AllJoyn
PDF
Building Open Source IoT Cloud
PPTX
Internet of Things (IoT) reference architecture using Azure -MIC - Lahore
PDF
Real World IoT Architectures and Projects with Eclipse IoT
PPTX
Introduction to Internet of Things Hardware
PPT
Building IoT with Arduino Day One
PDF
Native OSGi, Modular Software Development in a Native World - Alexander Broek...
PDF
Hands on with lightweight m2m and Eclipse Leshan
PDF
IoT Architecture - Are Traditional Architectures Good Enough or do we Need Ne...
PDF
IoT Solutions for Smart Energy Smart Grid and Smart Utility Applications
PPT
PPT
MySQL Atchitecture and Concepts
PDF
Open IoT Cloud Architecture, Web of Things, Shenzhen, China.
PPT
MySql slides (ppt)
PDF
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
Welcome
ApacheCon NA11 - Apache Celix, Universal OSGi?
The tools & technologies behind Resin.io
IoTcloud-cybersecurity-securityofthings
Lab IoT 2016
Introduction to AllJoyn
Building Open Source IoT Cloud
Internet of Things (IoT) reference architecture using Azure -MIC - Lahore
Real World IoT Architectures and Projects with Eclipse IoT
Introduction to Internet of Things Hardware
Building IoT with Arduino Day One
Native OSGi, Modular Software Development in a Native World - Alexander Broek...
Hands on with lightweight m2m and Eclipse Leshan
IoT Architecture - Are Traditional Architectures Good Enough or do we Need Ne...
IoT Solutions for Smart Energy Smart Grid and Smart Utility Applications
MySQL Atchitecture and Concepts
Open IoT Cloud Architecture, Web of Things, Shenzhen, China.
MySql slides (ppt)
IoT Open Source Integration Comparison (Kura, Node-RED, Flogo, Apache Nifi, S...
Ad

Similar to Programming IoT Gateways in JavaScript with macchina.io (20)

PPTX
StrongLoop Overview
PDF
Easing offline web application development with GWT
PDF
soft-shake.ch - Hands on Node.js
PPT
Play!ng with scala
PPTX
[NDC 2019] Enterprise-Grade Serverless
PPTX
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
PPTX
Building a chat app with windows azure mobile
PPT
Shindig in 2 hours
PPT
Pushing the Boundaries of Sencha and HTML5′s WebRTC
PDF
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
PPTX
Developing your first application using FIWARE
PPT
Windows Azure and a little SQL Data Services
PPTX
Real World Lessons on the Pain Points of Node.JS Application
PDF
using Mithril.js + postgREST to build and consume API's
PPTX
Meteor Meet-up San Diego December 2014
PDF
5.node js
PDF
NodeJS for Beginner
KEY
CouchDB on Android
PDF
Nanoservices and Microservices with Java
PDF
Intro to Retrofit 2 and RxJava2
StrongLoop Overview
Easing offline web application development with GWT
soft-shake.ch - Hands on Node.js
Play!ng with scala
[NDC 2019] Enterprise-Grade Serverless
[NDC 2019] Functions 2.0: Enterprise-Grade Serverless
Building a chat app with windows azure mobile
Shindig in 2 hours
Pushing the Boundaries of Sencha and HTML5′s WebRTC
Boost Development With Java EE7 On EAP7 (Demitris Andreadis)
Developing your first application using FIWARE
Windows Azure and a little SQL Data Services
Real World Lessons on the Pain Points of Node.JS Application
using Mithril.js + postgREST to build and consume API's
Meteor Meet-up San Diego December 2014
5.node js
NodeJS for Beginner
CouchDB on Android
Nanoservices and Microservices with Java
Intro to Retrofit 2 and RxJava2

Recently uploaded (20)

PPTX
INTERNET------BASICS-------UPDATED PPT PRESENTATION
PPT
Design_with_Watersergyerge45hrbgre4top (1).ppt
PPTX
Funds Management Learning Material for Beg
PDF
Decoding a Decade: 10 Years of Applied CTI Discipline
PDF
Triggering QUIC, presented by Geoff Huston at IETF 123
PDF
💰 𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓 💰
PPT
tcp ip networks nd ip layering assotred slides
PDF
Paper PDF World Game (s) Great Redesign.pdf
PPTX
Introduction about ICD -10 and ICD11 on 5.8.25.pptx
PPTX
CHE NAA, , b,mn,mblblblbljb jb jlb ,j , ,C PPT.pptx
PPTX
522797556-Unit-2-Temperature-measurement-1-1.pptx
PPTX
presentation_pfe-universite-molay-seltan.pptx
PPTX
artificial intelligence overview of it and more
PPTX
QR Codes Qr codecodecodecodecocodedecodecode
PDF
An introduction to the IFRS (ISSB) Stndards.pdf
PDF
Testing WebRTC applications at scale.pdf
PPTX
Slides PPTX World Game (s) Eco Economic Epochs.pptx
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PPTX
Introduction to Information and Communication Technology
PPTX
SAP Ariba Sourcing PPT for learning material
INTERNET------BASICS-------UPDATED PPT PRESENTATION
Design_with_Watersergyerge45hrbgre4top (1).ppt
Funds Management Learning Material for Beg
Decoding a Decade: 10 Years of Applied CTI Discipline
Triggering QUIC, presented by Geoff Huston at IETF 123
💰 𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓 💰
tcp ip networks nd ip layering assotred slides
Paper PDF World Game (s) Great Redesign.pdf
Introduction about ICD -10 and ICD11 on 5.8.25.pptx
CHE NAA, , b,mn,mblblblbljb jb jlb ,j , ,C PPT.pptx
522797556-Unit-2-Temperature-measurement-1-1.pptx
presentation_pfe-universite-molay-seltan.pptx
artificial intelligence overview of it and more
QR Codes Qr codecodecodecodecocodedecodecode
An introduction to the IFRS (ISSB) Stndards.pdf
Testing WebRTC applications at scale.pdf
Slides PPTX World Game (s) Eco Economic Epochs.pptx
Tenda Login Guide: Access Your Router in 5 Easy Steps
Introduction to Information and Communication Technology
SAP Ariba Sourcing PPT for learning material

Programming IoT Gateways in JavaScript with macchina.io

  • 1. Programming IoT Gateways in JavaScript with macchina.io Günter Obiltschnig Applied Informatics Software Engineering GmbH guenter@appinf.com @obiltschnig, @macchina_io
  • 2. About Me hard-core C++ developer (20+ years), who also likes JavaScript “full stack++”, embedded, hardware to web frontend + cloud POCO C++ Libraries (2004) Applied Informatics GmbH (2006) my-devices.net (2010) AIS Radar for iOS (2011) macchina.io (2013)
  • 3. m .ioacchina A modular open source toolkit for building embedded IoT applications that connect sensors, devices and cloud services.
  • 4. IoT Gateway devices.netCloud Services AirVantage, Bluemix, Tinamous, Xively, etc. HTTP(S) MQTT Remote Access my-devices.net device apps local“business logic” web services web visualization database discoverability Mobile/Web Clients Devices/Sensor Networks CoAP, IEEE 802.15.4, Modbus, USB, Bluetooth, RS-232
  • 6. > open source (Apache 2.0 License) > built in C++ for best performance and efficiency 
 (JavaScript for parts of web interface) > modular and extensible > mature, proven codebase: 
 POCO C++ Libraries, Google V8, Eclipse Paho, SQLite
 AngularJS, jQuery, OpenLayers, Ace (text editor),
 + Applied Informatics OSP and Remoting frameworks > C++-to-JavaScript bridge > Raspberry Pi, Beaglebone, Edison, RED, MangOH, etc. > prototype on Linux or OS X host, easily deploy to device > web interface with JavaScript editor
  • 7. Sensors & Devices Protocols Cloud Services Temperature, Ambient Light, 
 Humidity, Air Pressure, etc. HTTP AirVantage I/O, Trigger, Rotary Encoder MQTT Bluemix Accelerometer CoAP* Twitter GNSS/GPS WebEvent Twilio (SMS) Barcode Reader, RFID* WebTunnel my-devices.net XBee (ZigBee, IEEE 802.15.4) XBee API any with HTTP/REST APIs Serial Port Modbus*, CANopen* * planned
  • 8. Pro Users and Device Manufacturers > add device specific APIs > make devices programmable in JavaScript for partners or end users > device specific app store (sell additional software features) > additional frameworks (UPnP, Remoting SOAP and JSON-RPC) > customizable web user interface > improved user authentication and authorization > signed bundles > pro support
  • 12. POCO C++ Libraries > Started 2004 > ~300.000 LOC > 1000+ classes > on GitHub since 2012 
 1000+ stars
 400+ forks
 30-50 clones/day > ~100 contributors > Boost License > http://pocoproject.org POSIX, WIN32, other (RT)OS API Foundation C++ and C Standard LibrariesApplication Zip Net Crypto Data SQLite ODBC MySQL NetSSL Util Tools, Utilities and additional Libraries XML JSON
  • 13. V8 > Google’s JavaScript Engine > Used by Chrome/Chromium and node.js > C++ library, (reasonably) easy to integrate and to extend > Compiles JavaScript to native code (x86, ARM, MIPS) > Great performance > BSD License
  • 14. Remoting > Similar to .NET Remoting or Java RMI, but for C++ > Code generator parses annotated C++ header files and generates code
 (serialization/deserialization, method dispatching, helpers) > Supports different transports (binary TCP, SOAP, JSON-RPC) > Used for automatic C++-to-JavaScript bridging > Will also be used to implement sandbox mechanism
  • 15. Open Service Platform (OSP) > Inspired by OSGi, but for C++ (also JavaScript, Python, etc.) > Dynamic module system based on bundles
 (Zip files with metadata, 
 shared libs, other files) > Dependency and 
 lifecycle management > Services and service registry > Web Server POCO Core Libraries (Foundation,XML,Util,Net) Operating System API Std.C/C++ Libraries Service Registry Portable Runtime Environment Life C ycle M anagem ent Bundle M anagem ent Standard Services Bundles install,resolve,start,stop and uninstall bundles provide services to other bundles and find services provided by other bundles manage bundle versions and dependencies web server, web- and console- based management, user authentication and authorization, preferences,etc. application-specific functionality and services
  • 16. Combining POCO C++ Libraries and V8 > JavaScript is single-threaded and garbage-collected > POCO is multithreaded (specifically web server) > Make C++ object available to JavaScript
 easy for static objects, just provide Wrapper > Allow JavaScript code to create C++ objects
 easy if you don’t care about memory/resource leaks > Register a callback function called by GC when object is deleted
 allows you to properly delete underlying c++ object > However, V8 does not do callbacks when script ends
 wrapped C++ objects won’t be deleted, leaks resulting > Need to track every C++ object a script creates and clean up afterwards :-(
  • 18. // Sensor.h //@ remote class Sensor: public Device { public: Poco::BasicEvent<const double> valueChanged; virtual double value() const = 0; virtual bool ready() const = 0; };
  • 19. Sensor.h RemoteGen lots of generated source files RemoteGen.xml
  • 20. Service <<generatedFrom>> IService ServiceProxy Service RemoteObject The interface class has all @remote methods from the service class. Service Skeleton <<invokes>> <<generated>> <<generated>><<generated>> <<generated>> Service ServerHelper <<generated>> Registers Skeleton, RemoteObject and EventDispatcher (if needed) with the Object Request Broker. Service ProxyFactory <<creates>> <<generated>> Service ClientHelper <<generated>> Registers ProxyFactory with the Object Request Broker. <<registers>><<registers>> <<registers>> Service EventSubscriber <<generated>> Service EventDispatcher <<generated>> <<registers>>
  • 21. var tempSensor = ...; tempSensor.on(‘valueChanged', function(ev) { var temp = ev.data; // ... }); if (tempSensor.ready()) { var temp = tempSensor.value(); // ... }
  • 23. // sensors.js (search sensors by physical quantity) var sensors = {}; var illuminanceRefs = serviceRegistry.find( 'io.macchina.physicalQuantity == "illuminance"'); if (illuminanceRefs.length > 0) { sensors.illuminance = illuminanceRefs[0].instance(); } var temperatureRefs = serviceRegistry.find( 'io.macchina.physicalQuantity == "temperature"'); if (temperatureRefs.length > 0) { sensors.temperature = temperatureRefs[0].instance(); } var humidityRefs = serviceRegistry.find( 'io.macchina.physicalQuantity == "humidity"'); if (humidityRefs.length > 0) { sensors.humidity = humidityRefs[0].instance(); } module.exports = sensors;
  • 24. // sensors.js (search sensors by ID) var sensors = {}; var illuminanceRef = serviceRegistry.findByName( 'io.macchina.xbee.sensor.illuminance#0013A20040A4D7F7'); if (illuminanceRef) { sensors.illuminance = illuminanceRef.instance(); } var temperatureRef = serviceRegistry.findByName( 'io.macchina.xbee.sensor.temperature#0013A20040A4D7F7'); if (temperatureRef) { sensors.temperature = temperatureRef.instance(); } var humidityRef = serviceRegistry.findByName( 'io.macchina.xbee.sensor.humidity#0013A20040A4D7F7'); if (humidityRef) { sensors.humidity = humidityRef.instance(); } module.exports = sensors;
  • 25. // database.js var database = {}; database.path = bundle.persistentDirectory + "logger.db"; database.session = new DBSession('SQLite', database.path); database.logIntervalSeconds = application.config.getInt( "datalogger.intervalSeconds", 30); database.keepDataSeconds = application.config.getInt( "datalogger.keepDataSeconds", 3600); module.exports = database;
  • 26. // logger.js var sensors = require('sensors.js'); var db = require('database.js'); db.session.execute('PRAGMA journal_mode=WAL'); db.session.execute('CREATE TABLE IF NOT EXISTS datalog ( timestamp INTEGER, illuminance FLOAT, temperature FLOAT, humidity FLOAT )'); setInterval( function() { db.session.execute('INSERT INTO datalog VALUES (?, ?, ?, ?)', DateTime().epoch, sensors.illuminance.value(), sensors.temperature.value(), sensors.humidity.value()); }, db.logIntervalSeconds*1000);
  • 27. // logger.js (continued) setInterval( function() { var cutoffTime = DateTime().epoch - db.keepDataSeconds; db.session.execute('DELETE FROM datalog WHERE timestamp < ?', cutoffTime); }, db.keepDataSeconds*1000);
  • 28. // history.jss var db = require(‘../database.js'); var validItems = ['temperature', 'humidity', 'illuminance']; var data = []; db.session.pageSize = form.maxItems ? parseInt(form.maxItems) : 20; var item = form.item; if (validItems.indexOf(item) > -1) { var recordSet = db.session.execute( 'SELECT timestamp, ' + item + ' FROM datalog ORDER BY timestamp DESC');
  • 29. // history.jss (continued) for (var row = 0; row < recordSet.rowCount; row++) { var time = recordSet.getValue('timestamp'); var value = recordSet.getValue(item); var date = LocalDateTime('1970-01-01'); date.addSeconds(time); data[recordSet.rowCount - row - 1] = { timestamp: date.format('%H:%M:%S'), value: value }; recordSet.moveNext(); } recordSet.close(); } response.contentType = 'application/json'; response.write(JSON.stringify(data)); response.send();
  • 30. // MQTT to AirVantage var sensors = require('sensors.js'); var mqttClientRefs = serviceRegistry.find( 'io.macchina.mqtt.serverURI == "tcp://na.airvantage.net:1883"'); if (mqttClientRefs.length > 0) { logger.information("MQTT Client found!"); var mqttClient = mqttClientRefs[0].instance(); setInterval(function() { var epoch = "" + 1000*DateTime().epoch; // seconds to milliseconds var payload = {}; payload[epoch] = { "sensors.temperature": sensors.temperature.value(), "sensors.humidity": sensors.humidity.value() "sensors.illuminance": sensors.illuminance.value() }; mqttClient.publish('JA347400060803/messages/json', 
 JSON.stringify(payload), 0); }, 10000); }
  • 31. // Send SMS via Twilio function sendSMS(to, message) { var accountSID = application.config.getString("twilio.accountSID"); var authToken = application.config.getString("twilio.authToken"); var from = application.config.getString(“twilio.from"); var twilioHttpRequest = new HTTPRequest( "POST", "https://api.twilio.com/2010-04-01/Accounts/" + accountSID + "/SMS/Messages" ); twilioHttpRequest.authenticate(accountSID, authToken); twilioHttpRequest.contentType = "application/x-www-form-urlencoded"; twilioHttpRequest.content = "From=" + encodeURIComponent(from) + "&To=" + encodeURIComponent(to) + "&Body=" + encodeURIComponent(message); twilioHttpRequest.send(function(result) { logger.information("Twilio SMS Response: ", result.response.status, result.response.content); }); }
  • 32. var sensors = require('sensors.js'); var enableSMS = true; sensors.illuminance.on('valueChanged', function(ev) { logger.notice("valueChanged: " + ev.data); if (ev.data < 10) { logger.warning("Lights out!"); if (enableSMS) { sendSMS("+436765166737", "Lights out!"); enableSMS = false; } } else if (ev.data > 50) { enableSMS = true; } });
  • 33. Q&A
  • 34. guenter@appinf.com | @obiltschnig | obiltschnig.com macchina.io | my-devices.net | pocoproject.org | www.appinf.com