rule language for iot

109
Implementing a Rule Language for the Internet of Things Phil Windley Office of the CIO Brigham Young University

Upload: phil-windley

Post on 27-Jul-2015

284 views

Category:

Internet


0 download

TRANSCRIPT

Implementing a Rule Language for the Internet of Things

Phil Windley Office of the CIO

Brigham Young University

The great question (about power) is who should have it.

– John Locke

The Web (circa 1996)

ClientSpace

ServerSpace

Google FacebookiCloud

Web 2.0

ClientSpace

ServerSpace

Google FacebookiCloud

Web 2.0

ClientSpace

ServerSpace

Google FacebookiCloud

Web 2.0

So long as we are merely clients of servers, we cannot be independent

Internet of Things

Lorem Ipsum Dolor

But it’s bigger than that…

Everything will have an online representation.

But it’s not just about manufactured things...

What will its architecture be?

Trillion node networks

Imagine a mountain representing today’s

billion node network...

Lorem Ipsum Dolor

From Trillions by Maya Design

From Trillions by Maya Design

The Current IoT Model Won’t Scale

Me

Me

GE

Internet of My Things

Me

GE

• decentralized • heterarchical • interoperable

1. Distributed transaction processing and applications

2. Peer-to-peer messaging and sharing

3. Autonomous coordination and contracts between peers

picos

Picos are online computers• persistent—retain state based on past operations. • unique—identity that is immutable. • online—available on the Internet and respond to events and

queries. • concurrent—operate independently of one another and process

events and queries asynchronously. • event-driven—respond to events by changing state and sending

new events. • rule-based—behavior is expressed as rules that pattern-match

against incoming events.

http://joinfuse.com

Owner Pico

Fleet Pico

Vehicle Pico

Vehicle Pico

Vehicle Pico

Owner Pico

Fleet Pico

Vehicle Pico

Vehicle Pico

Vehicle Pico

Owner Pico

Phil's Pico

owner

Phil's Pico

owner

Lynne's Pico

owner

Phil's Pico Tom's Pico

owner

Lynne's Pico

owner

Phil's Pico Tom's Pico

owner

Lynne's Pico

owner

Phil's Pico Tom's Pico

owner

Lynne's Pico

owner

Phil's Pico Tom's Pico

owner

Lynne's Pico

ownerborrower

Domain-Specific Languages

devices standardsidentityAPIsprotocols

devices standardsidentityAPIsprotocols

architecture

devices standardsidentityAPIsprotocols

architecture

framework

devices standardsidentityAPIsprotocols

architecture

framework

notation

Events vs Requests

“this happened” vs

“do this”

Event System Properties• Events are autonomous

• Event-driven system are more loosely coupled

• Downstream (receiver) driven flow control

• Near real-time propagation

Web Application

Application Data

Browser

Web Application

Application Data

Browser

Vehicle's Pico

iCalendar

Web

Mobile

Rather than a model where a system presents an API for a collection of resources….

Rather than a model where a system presents an API for a collection of resources….Picos present a model wherein each pico presents it’s own, customizable API

CloudOS• Pico Lifecycle

• Subscriptions

• Ruleset management

• Notifications

• Files

KRL

Event-Condition-Actionrule check_subscriptions {

select when fuse subscription_check

pre {

vid = carvoyant:vehicle_id();

my_subs = carvoyant:getSubscription(vid);

should_have = required_subscription_list.length();

}

if(my_subs.length() < should_have) then

send_directive("not enough subscriptions")

fired {

log ">>>> vehicle #{vid} needs subscription check";

raise fuse event initial_carvoyant_subscriptions;

}

}

Event-Condition-Actionrule check_subscriptions {

select when fuse subscription_check

pre {

vid = carvoyant:vehicle_id();

my_subs = carvoyant:getSubscription(vid);

should_have = required_subscription_list.length();

}

if(my_subs.length() < should_have) then

send_directive("not enough subscriptions")

fired {

log ">>>> vehicle #{vid} needs subscription check";

raise fuse event initial_carvoyant_subscriptions;

}

}

Event-Condition-Actionrule check_subscriptions {

select when fuse subscription_check

pre {

vid = carvoyant:vehicle_id();

my_subs = carvoyant:getSubscription(vid);

should_have = required_subscription_list.length();

}

if(my_subs.length() < should_have) then

send_directive("not enough subscriptions")

fired {

log ">>>> vehicle #{vid} needs subscription check";

raise fuse event initial_carvoyant_subscriptions;

}

}

Event-Condition-Actionrule check_subscriptions {

select when fuse subscription_check

pre {

vid = carvoyant:vehicle_id();

my_subs = carvoyant:getSubscription(vid);

should_have = required_subscription_list.length();

}

if(my_subs.length() < should_have) then

send_directive("not enough subscriptions")

fired {

log ">>>> vehicle #{vid} needs subscription check";

raise fuse event initial_carvoyant_subscriptions;

}

}

Event-Condition-Actionrule check_subscriptions {

select when fuse subscription_check

pre {

vid = carvoyant:vehicle_id();

my_subs = carvoyant:getSubscription(vid);

should_have = required_subscription_list.length();

}

if(my_subs.length() < should_have) then

send_directive("not enough subscriptions")

fired {

log ">>>> vehicle #{vid} needs subscription check";

raise fuse event initial_carvoyant_subscriptions;

}

}

select when web pageview re#/support/(\d+)# setting(issue_number) before (phone inboundcall or email received subj.match(re#issue_number#) )

select when web pageview re#/support/(\d+)# setting(issue_number) before (phone inboundcall or email received subj.match(re#issue_number#) )

1

2

3

select when web pageview re#/support/(\d+)# setting(issue_number) before (phone inboundcall or email received subj.match(re#issue_number#) )

1

2

3

Persistent Variablesrule name_trip { select when fuse trip_name pre { tid = mkTid(event:attr("tripId")); tname = event:attr(“tripName”).defaultsTo(“”, “no trip name”); tcategory = event:attr(“tripCategory”).defaultsTo(“”, “no trip category”); trip = ent:trip_summaries{tid}.defaultsTo({}); start = reducePrecision(trip{"startWaypoint"}); end = reducePrecision(trip{"endWaypoint"}); } if(not trip{"startWaypoint"}.isnull() && not trip{"endWaypoint"}.isnull()) then send_directive("Named trip") with tripId = tid and start = start and end = end;

fired { set ent:trip_names{[end, start]} mkTripMeta(tname, tcategory); } }

Persistent Variablesrule name_trip { select when fuse trip_name pre { tid = mkTid(event:attr("tripId")); tname = event:attr(“tripName”).defaultsTo(“”, “no trip name”); tcategory = event:attr(“tripCategory”).defaultsTo(“”, “no trip category”); trip = ent:trip_summaries{tid}.defaultsTo({}); start = reducePrecision(trip{"startWaypoint"}); end = reducePrecision(trip{"endWaypoint"}); } if(not trip{"startWaypoint"}.isnull() && not trip{"endWaypoint"}.isnull()) then send_directive("Named trip") with tripId = tid and start = start and end = end;

fired { set ent:trip_names{[end, start]} mkTripMeta(tname, tcategory); } }

Persistent Variablesrule name_trip { select when fuse trip_name pre { tid = mkTid(event:attr("tripId")); tname = event:attr(“tripName”).defaultsTo(“”, “no trip name”); tcategory = event:attr(“tripCategory”).defaultsTo(“”, “no trip category”); trip = ent:trip_summaries{tid}.defaultsTo({}); start = reducePrecision(trip{"startWaypoint"}); end = reducePrecision(trip{"endWaypoint"}); } if(not trip{"startWaypoint"}.isnull() && not trip{"endWaypoint"}.isnull()) then send_directive("Named trip") with tripId = tid and start = start and end = end;

fired { set ent:trip_names{[end, start]} mkTripMeta(tname, tcategory); } }

persistent variables (cont)

ent:trips -> {“39.369,-111.456” : {“39.034,-110.915”: {“name” : “home/school”, “category” : “other”}}, “40.010,-111.456” : {“39.144,-112.324”: {“name” : “doctor’s office”, “category” : “medical”}}, … }

persistent variables (cont)

tripMeta = function(start, end) { ent:trip_names{[reducePrecision(end), reducePrecision(start)]} }

tripsByDate = function(start, end){

utc_start = common:convertToUTC(start); utc_end = common:convertToUTC(end); ent:trip_summaries.query([], { 'requires' : '$and', 'conditions' : [ { ‘search_key' : [ 'endWaypoint', 'timestamp'], 'operator' : '$gte', 'value' : utc_start }, { 'search_key' : [ 'endWaypoint', 'timestamp' ], 'operator' : '$lte', 'value' : utc_end } ]}, ‘return_values’) };

persistent variables (cont)

tripsByDate = function(start, end){

utc_start = common:convertToUTC(start); utc_end = common:convertToUTC(end); ent:trip_summaries.query([], { 'requires' : '$and', 'conditions' : [ { ‘search_key' : [ 'endWaypoint', 'timestamp'], 'operator' : '$gte', 'value' : utc_start }, { 'search_key' : [ 'endWaypoint', 'timestamp' ], 'operator' : '$lte', 'value' : utc_end } ]}, ‘return_values’) };

persistent variables (cont)

rulesets

pico engine (kre)

Pico container is implemented as

Apache module in Perl

We’ve got both kinds:C & Perl!

Open standards Open source

http://github.com/kre

Picos Support A Familiar Model

Kynetx Rules Engine

OtherData

Sources

WebServices

APIs

Rulesets PersistentData

APIs

engine

Picos Support A Familiar Model

Kynetx Rules Engine

OtherData

Sources

WebServices

APIs

Rulesets PersistentData

APIs

engine

Persistent Compute Object containers

Picos Support A Familiar Model

Kynetx Rules Engine

OtherData

Sources

WebServices

APIs

Rulesets PersistentData

APIs

engine

Persistent Compute Object containers

CloudOS

Confi

gura

tion

Man

agem

ent

Clou

dOS

Serv

ice

Notifi

catio

nSe

rvice

Pers

onal

Dat

a Se

rvice

UI S

uppo

rt

File

Soci

al

Soci

al Fuse

Libr

ary

Gua

rd

Tour

Libr

ary

libraries

Picos Support A Familiar Model

Kynetx Rules Engine

OtherData

Sources

WebServices

APIs

Rulesets PersistentData

APIs

engine

Persistent Compute Object containers

Fore

vr.u

s(c

onta

ct)

Tim

elin

e(s

ocia

l)

To D

o &

Rem

inde

rs

Vehi

cle

Man

ange

men

t

Hom

e M

anag

emen

t

Inte

ntca

stin

g

Fuse

Gua

rd

Tour

applicationsCloudOS

Confi

gura

tion

Man

agem

ent

Clou

dOS

Serv

ice

Notifi

catio

nSe

rvice

Pers

onal

Dat

a Se

rvice

UI S

uppo

rt

File

Soci

al

Soci

al Fuse

Libr

ary

Gua

rd

Tour

Libr

ary

libraries

Picos Are Decentralized & Networked

picopico

HostingSpace

PicoSpace

HostingCompany A

Hosting Company B

SelfHosted

pico

pico

pico

pico

picopico

pico

KRE KRE KRE PicoContainers

Apache as an Application Server

Modules are NOT CGI Programs

• Modules run inside the Apache process architecture

• Modules have access to and can replace all Apache services

• Uses the server API - not an embedded interpreter

• Access to every part of the HTTP request lifecycle

Apache Server Lifecycle

Apache HTTP Request Lifecycle

Apache Application Services• Configuration

• Process and thread management

• Security

• Logging

• Interprocess communication

• Request dispatching

Implementation• LOTS of libraries (~90)

• Any::Event • DateTime • Data::Diver • Cache::Memcached • WWW::Mechanize • Test::More

• Parser • Operators

• Good support for shards

• Documents are JSON

• Capped collections

• TTL indexes

wait

decodeevent

schedulerules

evalrules

assembleresponse

receiveevent explicit

event

directivedocument

scheduleobject

javaScript orJSON

eventobject

Pico Event Evaluation Cycle

event

directives

API interactions

external events

wait

decodeevent

schedulerules

evalrules

assembleresponse

receiveevent

explicitevent

directivedocument

scheduleobject

javaScript orJSON

requestenv

Pico Event Evaluation Cyclewith container actions

event

directives

API interactions

external events

establishcontext event

object

establish identityload rulesets (parse/optimize)

calculate RIDscalculate salience graph

Quickstart http://developer.kynetx.com

Lessons Learned• Understand language feng shui

• Parsing

• Don’t optimize too early

• Orthoganility

• Breadth first

• Languages evolve

• Leverage underlying language

• Build the language you want to use

• Use your language

• Picos are a decent abstraction

Implementing a Rule Language for the Internet of Things

Phil Windley [email protected]

www.windley.com @windley

windley