-
Notifications
You must be signed in to change notification settings - Fork 81
Activities
An activity is a binding between an event and a task.
Both the event and task are often groups of actors. For events, groups are boolean composed (e.g., "if THIS or THAT"), whilst for tasks, groups are temporally composed (e.g., "UP then DOWN").
NOTE THAT TEMPORAL EVALUATION IS NOT YET IMPLEMENTED
In addition, each task has an optional guard to disable its performance. For example, an activity might perform a task to turn all lights to full during an alarm condition; however, the lights in a nursery might have a guard telling them not to perform during solar night.
An activity consists of:
-
A fixed activityID that is assigned by the steward during activity creation, and is used by any subsequent API call referencing that activity.
-
A fixed activityUID that is assigned by the client during activity creation, and is used to ensure atomicity of activity creation.
-
An activityName and activityComments that is assigned by the client during activity creation. Unlike the activityID and activityUID, these are meant to be meaningful to people.
-
An eventType (either 'event' or 'group') and eventID that is assigned by the client during activity creation.
-
A taskType (either 'task' or 'group') and taskID that is assigned by the client during activity creation.
-
A sortOrder to provide an optional hint to programs when sorting activities for display.
Let's say we want to turn on a lightbulb at solar sunrise. Logically, this is an activity:
-
binding an event:
-
actor: place/1
-
observes: solar
-
parameter: sunrise
-
-
to a task: where
-
actor: device/1
-
performs: on
-
parameter: { color: { model: rgb, rgb: { r: 255, g: 255, b: 255 } }, brightness: 100 }
-
Things like 'place/1' and 'device/1' are called actors -- their job is to observe events or perform tasks. The possible events that can be observed, or tasks that can be performed, depend on the type of actor. The Device Taxonomy defines these possibilities along with how the parameters are interpreted.
In this case, hopefully, the light is not close to someone sleeping, as they may not appreciate a light going white at full brightness!
Of course, real-world activities tend to be more complex in the sense that we might want multiple lights to go on at once. So, the steward supports groups (discussed later on).
A key concept in the steward is that when a thing observes an event, then another thing performs an task. Events and tasks either refer to a single actor (e.g., a particular device), or may refer to a group of actors combined by either boolean (event) or temporal (task) logic.
An event consists of:
-
A fixed eventID that is assigned by the steward during event creation, and is used by any subsequent API call referencing that event.
-
A fixed eventUID that is assigned by the client during event creation, and is used to ensure atomicity of event creation.
-
An eventName and eventComments that is assigned by the client during event creation, Unlike the eventID and eventUID, these are meant t be meaningful to people.
-
An actorType (either 'device', 'place', or 'group') and actorID that is assigned by the client during event creation.
-
An observe verb and parameter value specific to the actor that is assigned by the client during event creation.
-
A sortOrder to provide an optional hint to programs when sorting events for display.
If the observe verb is the value '.condition', then the associated actor may NOT refer to a group, and the parameter value is an expression that is evaluated against the info property of the actor (termed the actor's state information). For example,
{ operator : "any-of"
, operand1 : ".solar"
, operand2": ["morning", "daylight", "evening"]
}
says to look at the actor's 'info.solar' property, and if the value is equal to any of the strings in the list, then this evaluates to true.
The parameter consists of three parts:
-
operator: one of "equals", "not-equals", "less-than", "less-than-or-equals", "greater-than", "greater-than-or-equals", "any-of", "none-of", "present", "not" "and", "or"
-
operand1: either a number, a string beginning with "." (referring to a state variable), or a literal string.
-
operand2: as operand1, but optional, depending on the operator
Typically conditional events are long-lived and are grouped with some other event that is observed to trigger an activity. For example, the condition above refers to daylight hours. It is likely that this is used with something an observed event (e.g., a motion sensor detecting motion) to perform a particular task. Alternatively, this might be used as a task guard so to limit the performance of a particular task to daylight hours.
An task consists of:
-
A fixed taskID that is assigned by the steward during task creation, and is used by any subsequent API call referencing that task.
-
A fixed taskUID that is assigned by the client during task creation, and is used to ensure atomicity of task creation.
-
An taskName and taskComments that is assigned by the client during task creation, Unlike the taskID and taskUID, these are meant t be meaningful to people.
-
An actorType (either 'device', 'place', or 'group') and actorID that is assigned by the client during task creation.
-
A perform verb and parameter value specific to the actor that is assigned by the client during task creation.
-
A guard, if present, identifies a conditional event that must be true in order for the task to be performed.
-
A sortOrder to provide an optional hint to programs when sorting tasks for display.
An group consists of:
-
A fixed groupID that is assigned by the steward during group creation, and is used by any subsequent API call referencing that group.
-
A fixed groupUID that is assigned by the client during group creation, and is used to ensure atomicity of group creation.
-
A fixed parentID that refers to the superior entry for the group.
-
An groupName and groupComments that is assigned by the client during group creation, Unlike the groupID and groupUID, these are meant t be meaningful to people.
-
An groupType (either 'device', 'event', or 'task') and actorID that is assigned by the client during group creation.
-
A groupOperator used by a superior to relate its immediate children: and (0), or (1), or not (2).
-
A sortOrder to provide an optional hint to programs when sorting groups for display.
Events are managed by authorized clients using the
/manage/api/v1/event/
path prefix, e.g.,
{ path : '/api/v1/event/list'
, requestID : '1'
, options : { depth: all }
}
To create a event, an authorized client sends:
{ path : '/api/v1/event/create/UUID'
, requestID : 'X'
, name : 'NAME'
, actor : 'TYPE/ID'
, observe : 'EVENT'
, parameter : 'PARAMS'
, comments : 'COMMENTS'
}
where UUID corresponds to an unpredictable string generated by the client, X is any non-empty string, NAME is a user-friendly name for this instance, TYPE/ID identifies the actor that observes the event, TASK identifies the particular event, PARAMS provides the parameters, and COMMENTS (if present) are textual, e.g.,
{ path : '/api/v1/event/create/0123456789abcdef'
, requestID : '1'
, name : 'hello sunrise'
, actor : 'place/1'
, observe : 'solar'
, parameter : 'sunrise'
}
To list the properties of a single event, an authorized client sends:
{ path : '/api/v1/event/list/ID'
, requestID : 'X'
, options : { depth: DEPTH }
}
where ID corresponds to the eventID of the event to be deleted, X is any non-empty string, and DEPTH is either 'flat', 'tree', or 'all'
If the ID is omitted, then all events are listed, e.g., to find out anything about everything, an authorized client sends:
{ path : '/api/v1/event/list'
, requestID : '2'
, options : { depth: 'all' }
}
To define a event, an authorized client sends:
{ path : '/api/v1/event/delete/ID'
, requestID : 'X'
}
where ID corresponds to the eventID of the event to be deleted, and X is any non-empty string, e.g.,
{ path : '/api/v1/event/delete/6'
, requestID : '3'
}
Tasks are managed by authorized clients using the
/manage/api/v1/task/
path prefix, e.g.,
{ path : '/api/v1/task/list'
, requestID : '1'
, options : { depth: all }
}
To create a task, an authorized client sends:
{ path : '/api/v1/task/create/UUID'
, requestID : 'X'
, name : 'NAME'
, actor : 'TYPE/ID'
, perform : 'TASK'
, parameter : 'PARAMS'
, guard : 'event/ID'
, comments : 'COMMENTS'
}
where UUID corresponds to an unpredictable string generated by the client, X is any non-empty string, NAME is a user-friendly name for this instance, TYPE/ID identifies the actor that performs the task, TASK identifies the particular task, PARAMS provides the parameters, event/ID (if present) the guard event associated with this task, and COMMENTS (if present) are textual, e.g.,
{ path : '/api/v1/task/create/0123456789abcdef'
, requestID : '1'
, name : 'wakeup light'
, actor : 'device/1'
, perform : 'on'
, parameter : '{"color":{"model":"rgb","rgb":{"r":255,"g":255,"b": 255}},"brightness":100 }'
}
To list the properties of a single task, an authorized client sends:
{ path : '/api/v1/task/list/ID'
, requestID : 'X'
, options : { depth: DEPTH }
}
where ID corresponds to the taskID of the task to be deleted, X is any non-empty string, and DEPTH is either 'flat', 'tree', or 'all'
If the ID is omitted, then all tasks are listed, e.g., to find out anything about everything, an authorized client sends:
{ path : '/api/v1/task/list'
, requestID : '2'
, options : { depth: 'all' }
}
To perform a task, an authorized client sends:
{ path : '/api/v1/task/perform/ID'
, requestID : 'X'
}
where ID corresponds to the taskID of the task to be performed, X is any non-empty string, e.g.,
{ path : '/api/v1/task/perform/7'
, requestID : '3'
}
To define a task, an authorized client sends:
{ path : '/api/v1/task/delete/ID'
, requestID : 'X'
}
where ID corresponds to the taskID of the task to be deleted, and X is any non-empty string, e.g.,
{ path : '/api/v1/task/delete/7'
, requestID : '4'
}
Activities are managed by authorized clients using the
/manage/api/v1/activity/
path prefix, e.g.,
{ path : '/api/v1/activity/list'
, requestID : '1'
, options : { depth: all }
}
To create a activity, an authorized client sends:
{ path : '/api/v1/activity/create/UUID'
, requestID : 'X'
, name : 'NAME'
, armed : BOOLEAN
, event : 'EVENT/ID'
, task : 'TASK/ID'
, comments : 'COMMENTS'
}
where UUID corresponds to an unpredictable string generated by the client, X is any non-empty string, NAME is a user-friendly name for this instance, ARMED indicates whether this activity should be evaluated, EVENT/ID identifies the event, TASK/ID identifies the task, and COMMENTS (if present) are textual, e.g.,
{ path : '/api/v1/activity/create/0123456789abcdef'
, requestID : '1'
, armed : true
, event : 'event/6'
, task : 'task/7'
}
To list the properties of a single activity, an authorized client sends:
{ path : '/api/v1/activity/list/ID'
, requestID : 'X'
, options : { depth: DEPTH }
}
where ID corresponds to the activityID of the activity to be deleted, X is any non-empty string, and DEPTH is either 'flat', 'tree', or 'all'
If the ID is omitted, then all activities are listed, e.g., to find out anything about everything, an authorized client sends:
{ path : '/api/v1/activity/list'
, requestID : '2'
, options : { depth: 'all' }
}
To modify a activity, an authorized client sends:
{ path : '/api/v1/activity/modify/ID'
, requestID : 'X'
...
}
where ID corresponds to the activityID of the activity to be modified, X is any non-empty string, e.g.,
{ path : '/api/v1/activity/modify/8'
, requestID : '3'
, armed : false
}
Any or all of the name, armed, event, task, and comments fields may be provided.
To perform a activity, an authorized client sends:
{ path : '/api/v1/activity/perform/ID'
, requestID : 'X'
}
where ID corresponds to the activityID of the activity to be performed, X is any non-empty string, e.g.,
{ path : '/api/v1/activity/perform/8'
, requestID : '3'
}
To define a activity, an authorized client sends:
{ path : '/api/v1/activity/delete/ID'
, requestID : 'X'
}
where ID corresponds to the activityID of the activity to be deleted, and X is any non-empty string, e.g.,
{ path : '/api/v1/activity/delete/8'
, requestID : '4'
}
Groups are managed by authorized clients using the
/manage/api/v1/group/
path prefix, e.g.,
{ path : '/api/v1/group/list'
, requestID : '1'
, options : { depth: all }
}
To create a group, an authorized client sends:
{ path : '/api/v1/group/create/UUID'
, requestID : 'X'
, parentID : 'Y'
, name : 'NAME'
, type : 'device' (default) | 'event' | 'task'
, operator : 'and' (default) | 'or' | 'not'
, members : [ 'TYPE/ID, ... ]
, comments : 'COMMENTS'
}
where UUID corresponds to an unpredictable string generated by the client, X is any non-empty string, Y (if present) refers to an existing group to be the superior, NAME is a user-friendly name for this instance, each TASK/ID identifies the actors associated with this group, and COMMENTS (if present) are textual, e.g.,
{ path : '/api/v1/group/create/0123456789abcdef'
, requestID : '1'
, members : [ 'device/1', 'device/2' ]
}
To list the properties of a single group, an authorized client sends:
{ path : '/api/v1/group/list/ID'
, requestID : 'X'
, options : { depth: DEPTH }
}
where ID corresponds to the groupID of the group to be deleted, X is any non-empty string, and DEPTH is either 'flat', 'tree', or 'all'
If the ID is omitted, then all groups are listed, e.g., to find out anything about everything, an authorized client sends:
{ path : '/api/v1/group/list'
, requestID : '2'
, options : { depth: 'all' }
}
To modify a group, an authorized client sends:
{ path : '/api/v1/group/modify/ID'
, requestID : 'X'
...
}
where ID corresponds to the groupID of the group having tasks to be modified, X is any non-empty string, e.g.,
{ path : '/api/v1/group/perform/9'
, requestID : '3'
}
To perform the tasks associated with a group, an authorized client sends:
{ path : '/api/v1/group/perform/ID'
, requestID : 'X'
...
}
where ID corresponds to the groupID of the group having tasks to be performed, X is any non-empty string, e.g.,
{ path : '/api/v1/group/perform/9'
, requestID : '3'
, members : []
}
Any or all of the parentID, name, type, operator, members, and comments fields may be provided.
To define a group, an authorized client sends:
{ path : '/api/v1/group/delete/ID'
, requestID : 'X'
}
where ID corresponds to the groupID of the group to be deleted, and X is any non-empty string, e.g.,
{ path : '/api/v1/group/delete/9'
, requestID : '4'
}