Rule Language for IoT
-
Upload
phil-windley -
Category
Internet
-
view
284 -
download
0
Transcript of Rule Language for IoT
Implementing a Rule Language for the Internet of Things
Phil Windley Office of the CIO
Brigham Young University
1. Distributed transaction processing and applications
2. Peer-to-peer messaging and sharing
3. Autonomous coordination and contracts between peers
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.
Event System Properties• Events are autonomous
• Event-driven system are more loosely coupled
• Downstream (receiver) driven flow control
• Near real-time propagation
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
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)
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
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 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
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
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