Upload
gregulator
View
232
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Canopy - Open source IoT software platform. Presented at the 2014 SFIoT Unconference (http://sfiot.org/unconference).
Citation preview
Rapid IoT Prototyping
with Canopy
http://canopy.link @CanopyIoT
Presented by Greg Prisament ([email protected]),
founder of Canopy.
2014 SFIoT UnConference (8/16/2014)
An end-to-end IoT software platform.
Selling Points
100% open source.
Designed for commercial use.Designed for commercial use.
Developer-friendly.
Creating a cloud-
managed product today
is expensive and
difficult…
Creating a cloud-
managed product today
is expensive and
difficult…
Complex software systems are involved.
Most platforms are proprietary and
expensive to license.
… but it doesn’t need to be that way.
What if IoT software were free,
readily-available, and easy-to-use?
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.
Key FeaturesKey Features
Enable Custom Experiences
Demonstration only. This prototype is not endorsed by anyone.
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.
Low-latency control from anywhere.
Seriously. Any similarity to an actual product is purely coincidental.
Low-latency control from anywhere.
Seriously. Any similarity to an actual product is purely coincidental.
Low-latency control from anywhere.
Seriously. Any similarity to an actual product is purely coincidental.
Low-latency control from anywhere.
Seriously. Any similarity to an actual product is purely coincidental.
Sub-100ms response time!
Low-latency control from anywhere.
HTTP POSTWebsocket
Home-spun
message-passing
system – “pigeon”
Callback triggered in
firmware code.
Sensor Monitoring
Dyson? Never heard of them.
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
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
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
Developing
forfor
Canopy
App
Protocol
Machine
Protocol
Databases
IoT software components
Firmware Server-side
software
Application(s)
ProtocolProtocol
Canopy
REST API
Canopy
Websocket
Protocol
Canopy has all that
Canopy
Embedded
Development Kit
Canopy
Cloud Service
Application
(Using Canopy
Client Libraries)
REST APIProtocol
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,
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
1) Describe your device in SDDL.
2) Generate embedded Code.
The Process
3) Run it.
4) Customize it.
// // // // 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””””
}}}}}}}}
}}}}
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””””
}}}}}}}}
}}}}
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””””
}}}}}}}}
}}}}
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””””
}}}}}}}}
}}}}
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
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
Login to http://canopy.link to see the device.
Login to http://canopy.link to see the device.
A control panel is
automatically
generated based
on the SDDL.
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
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}}}}
............
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;;;;
}}}}............
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;;;;}}}}
............
Now the controls and sensors work!
Now the controls and sensors work!
Now the controls and sensors work!
We just made a cloud-
managed product in 15
minutes!
Building Custom Apps
I’m back baby!
https://canopy.link/device/<UUID>
Or, using alias:
REST endpoints created for each device
https://canopy.link/gregp/SmartFan
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.
POST /device/<UUID>{
“speed” : 3}
REST: Control Device
}
POST /device/<UUID>{
“speed” : 3}
REST: Control Device
}
Remember that we
had “control speed” in
our fan.sddl file.
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
}]}
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
}]}
var fan = canopy.devices[uuid];
fan.properties.speed.setTargetValue(3, {onSuccess: function() {
Javascript: Control device
onSuccess: function() {alert(“Fan speed set to MAX”);
}})
var fan = canopy.devices[uuid];
var hum = fan.properties.humidity.value();
Javascript: Get current sensor value
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);
} }
});
var fan = canopy.devices[uuid];
fan.share({user: “[email protected]”
Javascript: Sharing a device
});
API & client library documentation at http://canopy.link
Project Status
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.
Project Status
Get Involved!Learn more
http://canopy.link
Connect with me
Follow Canopy on Twitter
@CanopyIoT
Contributor
Sponsor
Partner
Team member
Advocate
Investor
Conclusion
• 100% open source.
• SDDL simplifies IoT product
development.
Learn more
http://canopy.link
Connect with me
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”.