Date post: | 15-Jul-2015 |
Category: |
Technology |
Upload: | kevin-swiber |
View: | 246 times |
Download: | 1 times |
Using JavaScript to Put the Internet in IoT
@kevinswiber
Open source platform for the Internet of Things
http://zettajs.org
Internet of Things
Ubiquitous Computing
Like control systems
Sensor Actuator
Controller
Environment
The Internet
but on the Internet
More than 50B connected devices by 2020
99 Problems
Technology
Coordination
Analysis
Experience
Decisions
Protocols HTTP/1.1 WebSockets SPDY Future: HTTP/2
Crossing Network Boundaries
Access Interaction Streaming
Why Node? Evented, async Open Source Cross-platform Because you know JavaScript!
Nuts & Bolts
Reaching the Edge
DevicesDevicesDevices
Zetta
Zetta
DevicesDevicesDevices
Zetta
ClientsClientsClients
ClientsClientsClients Private Network
Data Center
Internet
Desired Architectural Properties
Decoupling of implementations
Independent evolution
Scale
Load balancing
Centralize complexity, distribute simplicity
Reduce latency
Support event streams
Architectural Constraints Client-server, stateless, cacheable, layered
system, uniform interface, etc.
Wait, isnt that REST?
The hypest of all media!
http://sirenspec.org
What about event streams?
How streams are done over HTTP today
WebHooks
Chunked Transfer-Encoding
HTTP Pipelining
Long Polling
Server Sent Events
XXXXX
Just upgrade
Zetta Process
Zetta Components
Scouts Drivers
Apps
create
observe
Model drivers as finite state machines
LED.prototype.init = function(config) { config .type('led') .state('off') .when('off', { allow: ['turn-on'] }) .when('on', { allow: ['turn-off'] }) .map('turn-on', this.turnOn) .map('turn-off', this.turnOff); };
Transitions are represented as affordances in the API.
"actions": [ { "name": "turn-on", "method": "POST", "href": ..., "fields": [ { "name": "action", "type": "hidden", "value": "turn-on" } ] } ]
We need to consume an object stream.
links: [ { title: pulse, rel: [http://rels.zettajs.io/object-stream], href: ws://... } ]
We need to consume an object stream.
wscat -c ws://... connected (press CTRL+C to quit) < {"topic":"heartbeat/1/pulse","timestamp":1411757412119,"data":61} < {"topic":"heartbeat/1/pulse","timestamp":1411757412620,"data":65} < {"topic":"heartbeat/1/pulse","timestamp":1411757413121,"data":69} < {"topic":"heartbeat/1/pulse","timestamp":1411757413622,"data":71} < {"topic":"heartbeat/1/pulse","timestamp":1411757414124,"data":66} < {"topic":"heartbeat/1/pulse","timestamp":1411757414626,"data":64} < {"topic":"heartbeat/1/pulse","timestamp":1411757415128,"data":68} < {"topic":"heartbeat/1/pulse","timestamp":1411757415629,"data":63} < {"topic":"heartbeat/1/pulse","timestamp":1411757416130,"data":65} < {"topic":"heartbeat/1/pulse","timestamp":1411757416631,"data":63}
Monitor resource events before taking action.
links: [ { title: logs, rel: [ monitor, http://rels.zettajs.io/object-stream ], href: ws://... } ]
Monitor resource events before taking action.
wscat -c ws://... connected (press CTRL+C to quit) < {"topic":"led/2/logs","timestamp":1411809676901,"transition":"turn-on","input":[],"properties":{"id":"2","type":"led","name":null,"state":"on"}} < {"topic":"led/2/logs","timestamp":1411809677548,"transition":"turn-off","input":[],"properties":{"id":"2","type":"led","name":null,"state":"off"}} < {"topic":"led/2/logs","timestamp":1411809678483,"transition":"turn-on","input":[],"properties":{"id":"2","type":"led","name":null,"state":"on"}} < {"topic":"led/2/logs","timestamp":1411809679126,"transition":"turn-off","input":[],"properties":{"id":"2","type":"led","name":null,"state":"off"}}
We also need binary.
links: [ { rel: [http://rels.zettajs.io/binary-stream], href: ws://..., type: video/mpeg, } ]
We also need binary.
wscat -c ws://... connected (press CTRL+C to quit) Q`rCEDDIp=`"3ss79:Yk}{` 5e\`>9%J[K89\z^> 8X Gp;WqXF h1{%O;7
We also need binary.
wscat -c ws://... connected (press CTRL+C to quit)
Reactive Clientsvar siren = require('siren'); !siren() .load('http://zetta-cloud-2.herokuapp.com') .link('http://rels.zettajs.io/peer', 'Detroit') .entity(function(e) { return e.properties.type === 'sound'; }) .link('http://rels.zettajs.io/object-stream', 'level') .monitor() .subscribe(console.log);
Reactive Clientsvar zrx = require('zrx'); !zrx() .load('http://zetta-cloud-2.herokuapp.com') .server('Detroit') .device(function(d) { return d.type === 'sound'; }) .stream('level') .subscribe(console.log);
It works!
Going Forward
Solve the producer-consumer problem.
Reactive Stream Control Protocol
Consumer controlled streams
Runs over WebSockets
Multiplex streams
URI scheme definition
Will be supported on HTTP/2 + WebSockets.
What can you do with streams?
Monitoring values over time
Distributed data processing
Event sourcing
Batches
// TODO:
Extract reactive hypermedia framework from Zetta internals.
Produce a clean specification and documentation.
Experiment with multiple languages/platform implementations.
Hit me up! [email protected]
https://twitter.com/kevinswiber
https://linkedin.com/in/kevinswiber
https://github.com/kevinswiber