56
Rapid IoT Prototyping with Canopy http://canopy.link @CanopyIoT Presented by Greg Prisament ([email protected]), founder of Canopy. 2014 SFIoT UnConference (8/16/2014)

Canopy unconference preso

Embed Size (px)

DESCRIPTION

Canopy - Open source IoT software platform. Presented at the 2014 SFIoT Unconference (http://sfiot.org/unconference).

Citation preview

Page 1: Canopy unconference preso

Rapid IoT Prototyping

with Canopy

http://canopy.link @CanopyIoT

Presented by Greg Prisament ([email protected]),

founder of Canopy.

2014 SFIoT UnConference (8/16/2014)

Page 2: Canopy unconference preso

An end-to-end IoT software platform.

Page 3: Canopy unconference preso

Selling Points

100% open source.

Designed for commercial use.Designed for commercial use.

Developer-friendly.

Page 4: Canopy unconference preso

Creating a cloud-

managed product today

is expensive and

difficult…

Page 5: Canopy unconference preso

Creating a cloud-

managed product today

is expensive and

difficult…

Complex software systems are involved.

Most platforms are proprietary and

expensive to license.

Page 6: Canopy unconference preso

… but it doesn’t need to be that way.

What if IoT software were free,

readily-available, and easy-to-use?

Page 7: Canopy unconference preso

Canopy makes it simple to develop

commercially-viable smart products.

WeSolve the common

system engineering

YouFocus on what your

business does best.system engineering

challenges with IoT.

Sensor data storage.

Communication protocols.

REST APIs & client libraries.

Authorization.

Security.

business does best.

Market-specific hardware.

Customer engagement.

Services and solutions.

Vertical applications.

Branding.

Page 8: Canopy unconference preso

Key FeaturesKey Features

Page 9: Canopy unconference preso

Enable Custom Experiences

Demonstration only. This prototype is not endorsed by anyone.

Page 10: Canopy unconference preso

Enable Custom Experiences

Demonstration only. This prototype is not endorsed by anyone.

Canopy provides APIs

& client libraries so

you can build sexy

custom apps for your

product.

Page 11: Canopy unconference preso

Low-latency control from anywhere.

Seriously. Any similarity to an actual product is purely coincidental.

Page 12: Canopy unconference preso

Low-latency control from anywhere.

Seriously. Any similarity to an actual product is purely coincidental.

Page 13: Canopy unconference preso

Low-latency control from anywhere.

Seriously. Any similarity to an actual product is purely coincidental.

Page 14: Canopy unconference preso

Low-latency control from anywhere.

Seriously. Any similarity to an actual product is purely coincidental.

Sub-100ms response time!

Page 15: Canopy unconference preso

Low-latency control from anywhere.

HTTP POSTWebsocket

Home-spun

message-passing

system – “pigeon”

Callback triggered in

firmware code.

Page 16: Canopy unconference preso

Sensor Monitoring

Dyson? Never heard of them.

Page 17: Canopy unconference preso

Sensor MonitoringStored in cassandra

cluster.LOD-based

downsampling

for performance.

Historic

data sent in

response.

Pruning for

space.

Sensor sample read in

firmware.

Sent over

websocket

HTTP GET

Page 18: Canopy unconference preso

Social

Activity

Maybe you should stop reading the fine print and pay attention to the presentation.

Google Docs-

like sharing and

permissions.

30s ago

MissPiggy set fan to off.

1m ago

Kermit set fan to max.

2m ago

MissPiggy set fan to off.

3m ago

Kermit set fan to max.

4m ago

Page 19: Canopy unconference preso

Our Emphasis

Powered Appliances

We assume moderately powerful HW:

• ARM-based SoC

• Internet access over WiFi, ETH0, 3G, or 4G LTE

• Linux-based OS• Linux-based OS

• Websockets & SSL

Enable Key Activities

Monitor Control Share

Page 20: Canopy unconference preso

Developing

forfor

Canopy

Page 21: Canopy unconference preso

App

Protocol

Machine

Protocol

Databases

IoT software components

Firmware Server-side

software

Application(s)

ProtocolProtocol

Page 22: Canopy unconference preso

Canopy

REST API

Canopy

Websocket

Protocol

Canopy has all that

Canopy

Embedded

Development Kit

Canopy

Cloud Service

Application

(Using Canopy

Client Libraries)

REST APIProtocol

Page 23: Canopy unconference preso

App

Protocol

Machine

Protocol

Databases

Here,

Just make your changes

here,

here,

here, and here.

Adding a feature (without Canopy)

Firmware Server-side

software

Application(s)

ProtocolProtocol

here,

Page 24: Canopy unconference preso

Canopy

REST API

Canopy

Websocket

Protocol

Make

change

here

See it

here.

Adding a feature with Canopy

Canopy

Cloud Service

Application

(Using Canopy

Client Libraries)

REST APIProtocol

Canopy

Embedded

Development Kit

Page 25: Canopy unconference preso

1) Describe your device in SDDL.

2) Generate embedded Code.

The Process

3) Run it.

4) Customize it.

Page 26: Canopy unconference preso

// // // // fan.sddlfan.sddlfan.sddlfan.sddl{{{{

""""class class class class canopy.example.smartfancanopy.example.smartfancanopy.example.smartfancanopy.example.smartfan" : {" : {" : {" : {""""control speedcontrol speedcontrol speedcontrol speed" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "int8int8int8int8“,“,“,“,""""minminminmin----valuevaluevaluevalue" : 0," : 0," : 0," : 0,""""maxmaxmaxmax----valuevaluevaluevalue" : 4" : 4" : 4" : 4

},},},},

Smart Device Description Language

""""sensorsensorsensorsensor temperaturetemperaturetemperaturetemperature" : {" : {" : {" : {""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""unitsunitsunitsunits" : "" : "" : "" : "degrees_cdegrees_cdegrees_cdegrees_c””””

},},},},""""sensorsensorsensorsensor humidityhumidityhumidityhumidity" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""uiuiuiui----numericnumericnumericnumeric----displaydisplaydisplaydisplay----hinthinthinthint" : "" : "" : "" : "percentagepercentagepercentagepercentage””””

}}}}}}}}

}}}}

Page 27: Canopy unconference preso

A class is a collection

of sensors and

controls.

// // // // fan.sddlfan.sddlfan.sddlfan.sddl{{{{

""""class class class class canopy.example.smartfancanopy.example.smartfancanopy.example.smartfancanopy.example.smartfan" : {" : {" : {" : {""""control speedcontrol speedcontrol speedcontrol speed" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "int8int8int8int8“,“,“,“,""""minminminmin----valuevaluevaluevalue" : 0," : 0," : 0," : 0,""""maxmaxmaxmax----valuevaluevaluevalue" : 4" : 4" : 4" : 4

},},},},

Smart Device Description Language

controls.""""sensorsensorsensorsensor temperaturetemperaturetemperaturetemperature" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""unitsunitsunitsunits" : "" : "" : "" : "degrees_cdegrees_cdegrees_cdegrees_c””””

},},},},""""sensorsensorsensorsensor humidityhumidityhumidityhumidity" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""uiuiuiui----numericnumericnumericnumeric----displaydisplaydisplaydisplay----hinthinthinthint" : "" : "" : "" : "percentagepercentagepercentagepercentage””””

}}}}}}}}

}}}}

Page 28: Canopy unconference preso

A control is a property

that can be remotely

// // // // fan.sddlfan.sddlfan.sddlfan.sddl{{{{

""""class class class class canopy.example.smartfancanopy.example.smartfancanopy.example.smartfancanopy.example.smartfan" : {" : {" : {" : {""""control speedcontrol speedcontrol speedcontrol speed" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "int8int8int8int8“,“,“,“,""""minminminmin----valuevaluevaluevalue" : 0," : 0," : 0," : 0,""""maxmaxmaxmax----valuevaluevaluevalue" : 4" : 4" : 4" : 4

},},},},

Smart Device Description Language

that can be remotely

changed by the user.

""""sensorsensorsensorsensor temperaturetemperaturetemperaturetemperature" : {" : {" : {" : {""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""unitsunitsunitsunits" : "" : "" : "" : "degrees_cdegrees_cdegrees_cdegrees_c””””

},},},},""""sensorsensorsensorsensor humidityhumidityhumidityhumidity" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""uiuiuiui----numericnumericnumericnumeric----displaydisplaydisplaydisplay----hinthinthinthint" : "" : "" : "" : "percentagepercentagepercentagepercentage””””

}}}}}}}}

}}}}

Page 29: Canopy unconference preso

A sensor is a property

that is sampled

periodically and can

be monitored

remotely by the user.

// // // // fan.sddlfan.sddlfan.sddlfan.sddl{{{{

""""class class class class canopy.example.smartfancanopy.example.smartfancanopy.example.smartfancanopy.example.smartfan" : {" : {" : {" : {""""control speedcontrol speedcontrol speedcontrol speed" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "int8int8int8int8“,“,“,“,""""minminminmin----valuevaluevaluevalue" : 0," : 0," : 0," : 0,""""maxmaxmaxmax----valuevaluevaluevalue" : 4" : 4" : 4" : 4

},},},},

Smart Device Description Language

""""sensorsensorsensorsensor temperaturetemperaturetemperaturetemperature" : {" : {" : {" : {""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""unitsunitsunitsunits" : "" : "" : "" : "degrees_cdegrees_cdegrees_cdegrees_c””””

},},},},""""sensorsensorsensorsensor humidityhumidityhumidityhumidity" : {" : {" : {" : {

""""datatypedatatypedatatypedatatype" : "" : "" : "" : "float32float32float32float32“,“,“,“,""""uiuiuiui----numericnumericnumericnumeric----displaydisplaydisplaydisplay----hinthinthinthint" : "" : "" : "" : "percentagepercentagepercentagepercentage””””

}}}}}}}}

}}}}

Page 30: Canopy unconference preso

fan.sddl canotool gen fan.sddl

fan.h

fan.c

makefile

Generate Embedded Code

Register your device w/ the server: sudo canotool provision

Compile and run: make run

Page 31: Canopy unconference preso

fan.sddl canotool gen fan.sddl

fan.h

fan.c

makefile

Generate Embedded CodeContains boilerplate code.

Contains stubs.

Register your device w/ the server: sudo canotool provision

Compile and run: make run

Page 32: Canopy unconference preso

Login to http://canopy.link to see the device.

Page 33: Canopy unconference preso

Login to http://canopy.link to see the device.

A control panel is

automatically

generated based

on the SDDL.

Page 34: Canopy unconference preso

The controls don’t

Login to http://canopy.link to see the device.

No sensor data The controls don’t

do anything yet.

No sensor data

is reported

Page 35: Canopy unconference preso

fan.c - Stubs#include <#include <#include <#include <canopy.hcanopy.hcanopy.hcanopy.h>>>>

static static static static voidvoidvoidvoid on_change_speedon_change_speedon_change_speedon_change_speed((((CanopyContextCanopyContextCanopyContextCanopyContext canopy, canopy, canopy, canopy, int8_tint8_tint8_tint8_t value)value)value)value){{{{

// your code here// your code here// your code here// your code herereturn return return return falsefalsefalsefalse;;;;

}}}}

static static static static boolboolboolbool on_report_requestedon_report_requestedon_report_requestedon_report_requested((((CanopyContextCanopyContextCanopyContextCanopyContext canopy)canopy)canopy)canopy){{{{

CanopyReportCanopyReportCanopyReportCanopyReport report = report = report = report = canopy_begin_reportcanopy_begin_reportcanopy_begin_reportcanopy_begin_report(canopy);(canopy);(canopy);(canopy);

// // // // Your code here:Your code here:Your code here:Your code here:// canopy_report_float32(report, “temperature", 0.0);// canopy_report_float32(report, “temperature", 0.0);// canopy_report_float32(report, “temperature", 0.0);// canopy_report_float32(report, “temperature", 0.0);// canopy_report_float32(report, “humidity", 0.0);// canopy_report_float32(report, “humidity", 0.0);// canopy_report_float32(report, “humidity", 0.0);// canopy_report_float32(report, “humidity", 0.0);

canopy_send_reportcanopy_send_reportcanopy_send_reportcanopy_send_report(report(report(report(report););););

return return return return truetruetruetrue;;;;}}}}

sssstatic tatic tatic tatic boolboolboolbool on_canopy_initon_canopy_initon_canopy_initon_canopy_init((((CanopyContextCanopyContextCanopyContextCanopyContext canopy)canopy)canopy)canopy){{{{

// your code here// your code here// your code here// your code here}}}}

............

Page 36: Canopy unconference preso

fan.c – Example control code#include <#include <#include <#include <canopy.hcanopy.hcanopy.hcanopy.h>>>>

#define FAN_SLOW_PIN 18#define FAN_SLOW_PIN 18#define FAN_SLOW_PIN 18#define FAN_SLOW_PIN 18#define FAN_MED_PIN 19#define FAN_MED_PIN 19#define FAN_MED_PIN 19#define FAN_MED_PIN 19#define FAN_HIGH_PIN 20#define FAN_HIGH_PIN 20#define FAN_HIGH_PIN 20#define FAN_HIGH_PIN 20

static static static static voidvoidvoidvoid on_change_speedon_change_speedon_change_speedon_change_speed((((CanopyContextCanopyContextCanopyContextCanopyContext canopy, int8_t value)canopy, int8_t value)canopy, int8_t value)canopy, int8_t value){{{{

set_gpioset_gpioset_gpioset_gpio(FAN_SLOW_PIN, (value == (FAN_SLOW_PIN, (value == (FAN_SLOW_PIN, (value == (FAN_SLOW_PIN, (value == 1111));));));));set_gpioset_gpioset_gpioset_gpio(FAN_MED_PIN, (value == (FAN_MED_PIN, (value == (FAN_MED_PIN, (value == (FAN_MED_PIN, (value == 2222));));));));set_gpioset_gpioset_gpioset_gpio(FAN_HIGH_PIN, (value == (FAN_HIGH_PIN, (value == (FAN_HIGH_PIN, (value == (FAN_HIGH_PIN, (value == 3333));));));));return return return return truetruetruetrue;;;;return return return return truetruetruetrue;;;;

}}}}

............

static static static static boolboolboolbool on_canopy_initon_canopy_initon_canopy_initon_canopy_init((((CanopyContextCanopyContextCanopyContextCanopyContext canopy)canopy)canopy)canopy){{{{

init_gpioinit_gpioinit_gpioinit_gpio(FAN_SLOW_PIN, (FAN_SLOW_PIN, (FAN_SLOW_PIN, (FAN_SLOW_PIN, “out”“out”“out”“out”, , , , 0000););););init_gpioinit_gpioinit_gpioinit_gpio(FAN_MED_PIN, (FAN_MED_PIN, (FAN_MED_PIN, (FAN_MED_PIN, “out”“out”“out”“out”, , , , 0000););););init_gpioinit_gpioinit_gpioinit_gpio(FAN_HIGH_PIN, (FAN_HIGH_PIN, (FAN_HIGH_PIN, (FAN_HIGH_PIN, “out”“out”“out”“out”, , , , 0000););););return return return return truetruetruetrue;;;;

}}}}............

Page 37: Canopy unconference preso

fan.c – Example sensor code............#include “#include “#include “#include “pi_dht_read.hpi_dht_read.hpi_dht_read.hpi_dht_read.h””””

#define DHT_SENSOR_PIN 6#define DHT_SENSOR_PIN 6#define DHT_SENSOR_PIN 6#define DHT_SENSOR_PIN 6

............

static static static static boolboolboolbool on_report_requestedon_report_requestedon_report_requestedon_report_requested((((CanopyContextCanopyContextCanopyContextCanopyContext canopycanopycanopycanopy)))){{{{

CanopyReportCanopyReportCanopyReportCanopyReport report = report = report = report = canopy_begin_reportcanopy_begin_reportcanopy_begin_reportcanopy_begin_report(canopy);(canopy);(canopy);(canopy);intintintint result;result;result;result;floatfloatfloatfloat t, h;t, h;t, h;t, h;floatfloatfloatfloat t, h;t, h;t, h;t, h;

result = result = result = result = pi_dht_readpi_dht_readpi_dht_readpi_dht_read(DHT22, SENSOR_PIN, &h, &t);(DHT22, SENSOR_PIN, &h, &t);(DHT22, SENSOR_PIN, &h, &t);(DHT22, SENSOR_PIN, &h, &t);if (result != DHT_SUCCESS)if (result != DHT_SUCCESS)if (result != DHT_SUCCESS)if (result != DHT_SUCCESS)

return return return return falsefalsefalsefalse;;;;

canopy_report_float32(report, canopy_report_float32(report, canopy_report_float32(report, canopy_report_float32(report, “temperature"“temperature"“temperature"“temperature", t);, t);, t);, t);canopy_report_float32(report, canopy_report_float32(report, canopy_report_float32(report, canopy_report_float32(report, “humidity"“humidity"“humidity"“humidity", h);, h);, h);, h);canopy_send_reportcanopy_send_reportcanopy_send_reportcanopy_send_report(report(report(report(report););););

return return return return truetruetruetrue;;;;}}}}

............

Page 38: Canopy unconference preso

Now the controls and sensors work!

Page 39: Canopy unconference preso

Now the controls and sensors work!

Page 40: Canopy unconference preso

Now the controls and sensors work!

We just made a cloud-

managed product in 15

minutes!

Page 41: Canopy unconference preso

Building Custom Apps

I’m back baby!

Page 42: Canopy unconference preso

https://canopy.link/device/<UUID>

Or, using alias:

REST endpoints created for each device

https://canopy.link/gregp/SmartFan

Page 43: Canopy unconference preso

https://canopy.link/device/<UUID>

Or, using alias:

REST endpoints created for each device

https://canopy.link/gregp/SmartFan

Authentication?

Currently, cookies & BASIC AUTH

over are supported.

OAuth2.0 support is coming soon.

Page 44: Canopy unconference preso

POST /device/<UUID>{

“speed” : 3}

REST: Control Device

}

Page 45: Canopy unconference preso

POST /device/<UUID>{

“speed” : 3}

REST: Control Device

}

Remember that we

had “control speed” in

our fan.sddl file.

Page 46: Canopy unconference preso

GET /device/<UUID>/humidity

200 OK{

“samples” : [{“t” : “2014-08-08T15:47:31”,“v” : 0.34194

}, {

REST: Get historic sensor data

}, {“t” : “2014-08-08T15:48:31”,“v” : 0.34022

}, {“t” : “2014-08-08T15:49:31”,“v” : 0.33998

}, {“t” : “2014-08-08T15:50:32”,“v” : 0.33715

}]}

Page 47: Canopy unconference preso

GET /device/<UUID>/humidity

200 OK{

“samples” : [{“t” : “2014-08-08T15:47:31”,“v” : 0.34194

}, {

Remember that we

had “sensor humidity”

in our fan.sddl file.

REST: Get historic sensor data

}, {“t” : “2014-08-08T15:48:31”,“v” : 0.34022

}, {“t” : “2014-08-08T15:49:31”,“v” : 0.33998

}, {“t” : “2014-08-08T15:50:32”,“v” : 0.33715

}]}

Page 48: Canopy unconference preso

var fan = canopy.devices[uuid];

fan.properties.speed.setTargetValue(3, {onSuccess: function() {

Javascript: Control device

onSuccess: function() {alert(“Fan speed set to MAX”);

}})

Page 49: Canopy unconference preso

var fan = canopy.devices[uuid];

var hum = fan.properties.humidity.value();

Javascript: Get current sensor value

Page 50: Canopy unconference preso

var fan = canopy.devices[uuid];

fan.properties.humidity.fetchHistoricData({onSuccess: function(data) {

Javascript: Get historic sensor data

for (var i = 0; i < data.length; i++) {console.log(data[i].t);console.log(data[i].v);

} }

});

Page 51: Canopy unconference preso

var fan = canopy.devices[uuid];

fan.share({user: “[email protected]

Javascript: Sharing a device

});

Page 52: Canopy unconference preso

API & client library documentation at http://canopy.link

Page 53: Canopy unconference preso

Project Status

Page 54: Canopy unconference preso

Roadmap

Alpha Aug 31, 2014End-to-end proof-of-concept.

Completed drafts of all specifications.

Beta Nov 31, 2014Security.Security.

Scalability.

Completeness.

v1.0 Feb 28, 2015Incorporate Beta feedback.

Testing.

Robustness.

Page 55: Canopy unconference preso

Project Status

Get Involved!Learn more

http://canopy.link

Connect with me

[email protected]

Follow Canopy on Twitter

@CanopyIoT

Contributor

Sponsor

Partner

Team member

Advocate

Investor

Page 56: Canopy unconference preso

Conclusion

• 100% open source.

• SDDL simplifies IoT product

development.

Learn more

http://canopy.link

Connect with me

[email protected]

Follow Canopy on Twitter

@CanopyIoT

development.

• Developer-friendly REST API and client

libraries enable “branded” applications.

• We will work with you to integrate

Canopy into your device. Looking for

partners for “pilot”.