The SAFRActions.config file defines which events will trigger specified actions. You can also specify additional condition constraints before the action(s) will trigger. It also contains basic configuration information so that ARES can communicate with other SAFR components, such as the Event Archive.
{
environment : "string",
<optional,
- values: "LOCAL", "DEV", "INT2", "PROD", "Custom"
- if not specified assumed PROD >
eventServer : "string",
<optional,
- required in case of Custom environment
- only affects Custom environment>
replyServer : "string",
<optional,
- only affects Custom environment>
coviServer : "string",
<optional,
- only affects Custom environment>
reportServer : "string",
<optional,
- only affects Custom environment>
configServer : "string",
<optional, "https://cvos.int2.real.com" for
integration environment
"https:\/\/cvos.real.com" for
production environment
- if specified Config is retrieved from Cloud using
following address: <configServer>/obj/ares/<aresId> >
userId : "string", <optional>
userPwd : "string", <optional, encrypted or open text>
directory : "string", <required>
site : "string", <optional>
source : "string", <optional>
aresId : "string", <optional>
maxEventLatency: <long>, <optional, in milliseconds, default = 8000>
logActionResponses: <bool>, <optional, default = false>
rules: [
{
event : {
type: [ "string", ... , "string" ],
<optional, values=(person, tag, action, or recognizedObject), default = all>
personType: [ "string", ... , "string" ],
<optional, default = all, "" = no personType>
personTags: [
[ "string", ... , "string" ],
...
[ "string", ... , "string" ]
]
<optional, default = all>
tagType: [ "string", ... , "string" ]
<optional, values=(april), default = all, "" = no tagType>
tagId: [ "string", ... , "string" ],
<optional, values=(Ids of tagType) default = all, "" = no tagId>
actionType: [ "string", ... , "string" ],
<optional, values=(smileToActivate) default = all, "" = no actionType>
actionId: [ "string", ... , "string" ],
<optional, default = all, "" = no actionId>
directionId: [ "string", ... , "string" <"left", "right", "up", "down"> ],
<optional, default = all, "" = no directionId>
ended: <boolean>,
<optional, default = false>
name: [ "string", ... , "string" ],
<optional, default = all, "" = no name>
company: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
moniker: [ "string", ... , "string" ],
<optional, default = all, "" = no moniker>
personId: [ "string", ... , "string" ],
<optional, default = all, "" = no personId>
hasPersonId: <boolean>,
<optional, default = all>
hasFaceId: <boolean>,
<optional, default = all>
hasName: <boolean>,
<optional, default = all>
hasMoniker: <boolean>,
<optional, default = all>
hasRootEventId: <boolean>,
<optional, default = all>
gender: [ "string", ... , "string" ],
<optional, default = all>
age: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
],
smile: <boolean>,
<optional, default = all>
avgSentiment: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
],
liveness: {
<optional, default = all>
min: <float>,
max: <float>
},
livenessConfirmed: <boolean>,
<optional, default = all>
mask: <boolean>,
<optional, default = all>
similarityScore: {
<optional, default = all>
min: <float>,
max: <float>
},
occlusion: {
<optional, default = all>
min: <float>,
max: <float>
},
site: "string",
<optional if specified at the root>
source: "string",
<optional if specified at the root>
idClass: [ "string", ... , "string" ],
<optional, default = all, "" = no idClass>
directGazeDuration: {
<optional, default = all>
min: <long>,
max: <long>
}
objectType: [ "string", ... , "string" ]
<optional, default = all, "" = no objectType>
objectId: [ "string", ... , "string" ],
<optional, default = all, "" = no objectId>
accessClearance: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
accessClearanceLevel: {
<optional, default = all>
min: <long>,
max: <long>
}
accessCardId: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
accessFacilityId: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
accessCardFormat: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
groups: [
[ "string", ... , "string" ],
...
[ "string", ... , "string" ]
]
<optional, default = all>
srcUserId: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
statusType: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
feed: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
processor: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
mode: [ "string", ... , "string" ],
<optional, default = all, "" = no company>
longitude: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
latitude: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
altitude: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
srcHeading: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
srcHeadingPitch: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
srcOrientation: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
srcOrientationPitch: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
srcSpeed: [
<optional, default = all>
{
min: <float>,
max: <float>
},
...
]
}
triggers : [
{
triggerId : "string",
<optional>
daysOfWeek: ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],
<optional, default = all>
timesOfDay: [
<optional, default = all>
{
start: "11:00", <required>
end: "17:00" <required>
},
...
],
actions: [
<required - can be empty (no actions)>
"string",
...
],
reply: {
<optional, default = no reply>
"replyDelay": long,
<optional, in milliseconds, default = 0>
"message": "string",
<optional, default = no message>
"disposition": double,
<optional, range [-1 .. 1], default = 1>
"tags": [ "tag1", ... "tagN" ]
<optional, default = no tags>
},
conditionalReply: [
<optional, default = no conditional reply>
{
"actionResponse": [ integer, ..., integer ],
<required>
"replyDelay": long,
<optional, in milliseconds, default = 0>
"message": "string",
<optional, default = no message>
"disposition": double,
<optional, range [-1 .. 1], default = 1>
"tags": [ "tag1", ... "tagN" ]
<optional, default = no tags>
}
...
],
},
...
],
excludeDates : [
<optional, default = none>
"7/4",
"12/25",
"4/10/2017",
...
],
triggerFrequencyLimit : {
<optional, default = unlimited>
"minSeparationInterval" : long,
<optional, in milliseconds, default = 0>,
"spanRootPersonIds": bool,
<optional, default = false>
"spanSources" : bool,
<optional, default = false>
"spanSites" : bool
<optional, default = false>
}
}
...
],
noTriggerReply: {
<optional, default = no reply>
"replyDelay": long,
<optional, in milliseconds, default = 0>
"message": "string",
<optional, default = no message>
"disposition": double,
<optional, range [-1 .. 1], default = -1>
"tags": [ "tag1", ... "tagN" ]
<optional, default = no tags>
},
nFactorDef: [
{
"name": string,
<required>
"failOnMismatch": string,
<optional: "delayed"/"immediate"/"none", default = "delayed">
"maxDelay": <milliseconds>,
<optional, default = 60000 (1min)>
"factors": [
"<factor_name>|<factor_value>",
...
],
"actions": [
"<action_command>",
...
]
},
...
],
emailDef: [
{
"label": string,
<required>
"recipients": [ "recipient1", ... "recipientN" ],
<required, escape sequences can be used>
"subject": string,
<required, escape sequences can be used>
"cc": [ "cc1", ... "ccN" ],
<optional, escape sequences can be used>
"bcc": [ "bcc1", ... "bccN" ],
<optional, escape sequences can be used>
"message": string,
<optional, escape sequences can be used>
"attachments": [ "attachment1", ... "attachmentN" ],
<optional, escape sequences can be used
http://, https://, cvos:// url schemes are supported, not to indicated file type,
so attachment looks ok prepend | with a file name, for instance: cvos:://xyuz/best|bestimage.jpg>
},
...
],
smsDef: [
{
"label": string,
<required>
"recipients": [ "recipient1", ... "recipientN" ],
<required, escape sequences can be used, phone numbers using the the E.164 format required>
"maxPrice": string,
<optional>
"message": string,
<optional, escape sequences can be used>
},
...
],
}
For rules.events that allow arrays, the new event must contain all the specified array elements to match. For example, if a config file specified rules.events.personType as follows:
personType: [
"staff",
"admin",
"guest"
],
Then the new event's personType array would have to have all 3 specified personTypes for it to match the rule.
personTags: All elements in one of the sub-arrays need to exist in the event's personTags array to match the rule.
ended: Indicates if an event has completed. It defaults to false
for all events, but it's set to true
when an event completes.
disposition refers to how the reply should be perceived by the recipient:
When conditional reply is specified, non-conditional reply is used only as catch-all if none of the action response codes match.
When conditional reply is specified, execution of the FIRST action in trigger will occur in blocking manner to enable retrieval of the response code from that FIRST action.
When conditional reply is not specified, execution of all actions will occur in non-blocking manner.
A reply is generated as follows:
URL used to post the reply: <replyServer>/stream/reply.<Base64(event Id)>
#N - name
#F - first name (name prefix up to first white-space)
#U - surname (name postfix: staring after first white-space sequence to the end of name string)
#T - person type
#S - source
#I - site
#D - person id
#R - root person id
#E - person external id
#G - gender
#A - age (###)
#M - sentiment (#.##)
#L - smile (true/false)
#V - event type
#v - event id
#B - tag type
#C - action type
#b - tag id
#c - action id
#k - direction id
#s - event start time (milliseconds since epoch)
#r - event start date/time (local time)
#p - validation phone
#e - validation email
#H - home location
#t - personTags (comma separate list of personTags)
#O - company
#m - moniker
#<d>m - moniker substring (delimited by white-space)
indexed by single decimal digit 0-9 . E.g.: #0m or #3m
#l - similarityScore (#.####)
#a - idClass
#Z - directGazeDuration
#o - objectType
#d - objectId
#u - occlusion (#.##)
#i - liveness (#.##)
#n - livenessConfirmed (true/false)
#z - mask (true/false)
#X - access clearance
#x - access clearance level
#Q - access card id
#q - access facility id
#f - access card format
#g - groups (comma separate list of groups)
#j - source user id
#w - status type
#K - feed
#P - processor
#W - mode
#1 - longitude
#2 - latitude
#3 - altitude
#4 - source heading
#5 - source heading pitch
#6 - source orientation
#7 - source orientation pitch
#8 - source speed
#9 - source position time (milliseconds since epoch)
#0 - source position date/time (local time)
The \
character is used as an escape character. Thus, if you wanted the string "Welcome, Ms. #N!" to appear as a reply, you would need to have the following in your config file:
"reply" : {
"message" : "Welcome, Ms. \#N!"
},
When passing in simple arguments, you simply pass in the arguments with white space separating them from the script and from each other. For example:
"actions": [
"python ./scripts/write_result.py Jamie"
],
When a single argument contains whitespace, or when you want to use one of the #<letter> tokens listed above on a Windows machine, use escaped "" characters. For example:
"actions": [
"python ./scripts/write_result.py \"Jamie Rodriguez\""
],
or
"actions": [
"python .\\scripts\\write_result.py \"#N\""
],
Note the need to escape the path separator character \
in the Windows example above.
When you want to use one of the #<letter> tokens listed above on a Linux machine, use escaped '' characters. For example:
"actions": [
"python ./scripts/write_result.py \'#N\'"
],
nFactor actions are started via internal @nFactorStart actions within the standard trigger actions array:
{
triggerId : "string",
...
actions: [
"@nFactorStart <name>",
...
],
reply: {
...
},
conditionalReply: [
...
]
}
When the action starts, the following occurs:
Response codes for nFactorStart actions:
nFactorStart-ed actions are resolved via nFactorResolve commands. When all factors needed for the actions are resolved, actions are executed:
{
triggerId : "string",
...
actions: [
"@nFactorResolve <name> <factor_name>|<factor_value>",
...
],
reply: {
...
},
conditionalReply: [
...
]
}
At the time of resolving the following occurs:
Response codes for nFactorResolve actions:
@nFactorStartOrResolve combines starting and resolving into one action. It's usually used for generating pseudo events from monikers.
{
triggerId : "string",
...
actions: [
"@nFactorStartOrResolve <name> <factor_name>|<factor_value>",
...
],
reply: {
...
},
conditionalReply: [
...
]
}
@personEventFromMoniker action generates a pseudo person event from moniker created by combining all the resolved factor values (separated by space) in the order listed in factors array. The generated event is of type person which is populated with the meta-data of person with moniker matching the assembled moniker value.
{
nFactorDef : [ {
factors : [
"moniker|**",
"moniker|1**",
"moniker|2**",
"moniker|3**"
],
actions : [
"@personEventFromMoniker"
]
}
]
}
To send emails using actions, you must do the following:
Obtain an SMTP server account that you can use to send emails.
Configure SAFR so that it's ready to use your SMTP server account to send emails. You can do this from the Status page of the Web Console. On Windows and macOS machines, you can also do this via Tools -> Configure Email Server in SAFR Actions.
Configure the emailDef section of the SAFRActions.config, as described below. Note that your emailDef section can define multiple emails, each one being identified by the label
field.
emailDef: [
{
"label": string,
<required>
"recipients": [ "recipient1", ... "recipientN" ],
<required, escape sequences can be used>
"subject": string,
<required, escape sequences can be used>
"cc": [ "cc1", ... "ccN" ],
<optional, escape sequences can be used>
"bcc": [ "bcc1", ... "bccN" ],
<optional, escape sequences can be used>
"message": string,
<optional, escape sequences can be used>
"attachments": [ "attachment1", ... "attachmentN" ],
<optional, escape sequences can be used
http://, https://, cvos:// url schemes are supported>
},
]
In the actions
field of SAFRActions.config, enter a string with the following syntax: "@emailSend <label>", where <label> = the label of whichever email within your SAFRActions.config that you want to use.
To use Short Message Service (SMS) notifications within actions, you must do the following:
Obtain an AWS account which is configured for your region so it can send SMS messages.
Configure SAFR so that it's ready to use your AWS account to send SMS notifications. You can do this from the Status page of the Web Console. On Windows and macOS machines, you can also do this via Tools -> Configure SMS Sender in SAFR Actions.
Configure the smsDef section of the SAFRActions.config, as described below. Note that your smsDef section can define multiple SMS messages, each one being identified by the label
field.
smsDef: [
{
"label": string,
<required>
"recipients": [ "recipient1", ... "recipientN" ],
<required, escape sequences can be used, phone numbers using the the E.164 format required>
"maxPrice": string,
<optional>
"message": string,
<optional, escape sequences can be used>
},
]
AWS.SNS.SMS.MaxPrice
attribute here for more information about this field.In the actions
field of SAFRActions.config, enter a string with the following syntax: "@smsSend <label>", where <label> = the label of whichever SNS message within your SAFRActions.config that you want to use.