Purple Robot may be configured to point to a JSON document that configures the system automatically. The URL of the document is accessible via the JSON Configuration URL setting in the application settings. This document describes the syntax & operation of this file.

The user_id HTTP GET Query Parameter

When the URL to the configuration file is set in the preferences, Purple Robot will inspect the URL for a user_id query parameter. If that parameter is missing, it will append a user_id query parameter set to the user identifier that maps specific instances of Purple Robot to different users. (The default identifier is the default system e-mail address.)

The HTTP endpoint serving the JSON configuration file has sole discretion whether to use the provided user_id parameter to generate user-specific configurations.

The JSON Configuration Document

The configuration document consists of a JSON dictionary/object in the following form:

{
  "user_id": "chris_test_id",
  "init_script": "PurpleRobot.playDefaultTone();",
  "features": [
    {
      "name": "Solar Information Feature",
      "feature": "PurpleRobot.loadLibrary('astro.js'); solarObjectForLocation(probe['LATITUDE'],probe['LONGITUDE']);",
      "formatter": "'Daylight: ' + result['sunrise_desc'] + ' to ' + result['sunset_desc'];",
      "sources": [
        "edu.northwestern.cbits.purple_robot_manager.probes.builtin.LocationProbe"
      ]
    }
  ],
  "triggers": 
  [
    {
      "type": "datetime",
      "name": "One-Time Test Date Trigger",
      "action": "PurpleRobot.loadLibrary('underscore'); PurpleRobot.showNativeDialog('JS Test Result', 'Using Underscore version ' + _.VERSION + '...', 'Ok', 'Cancel', 'PurpleRobot.launchUrl(\'http://www.yahoo.com\');', 'http://www.google.com')",
      "datetime_start": "20130218T145900",
      "datetime_end": "20130920T090100"
    },
    {
      "type": "probe",
      "name": "Orientation Probe Test",
      "frequency": 15000,
      "action": "PurpleRobot.showNativeDialog('Phone Orientation', 'Vertical', 'Ok', 'Cancel', null, null);",
      "test": "var delta = Math.abs(probeInfo.PITCH[0]); (delta > 75 && delta < 105);"
    }
  ]
}

Each key in the root dictionary are described in the sections below.

The user_id key

The user_id key may be used to override the user identifier (typically the default system e-mail address) with a custom identifier that may map on to study identifiers or other user-specific data. When the JSON configuration document is parsed this parameter is the first item to be set.

The probe_settings key

TODO: Document.

The features key

The features key points to an array of JSON dictionaries that define custom JavaScript features that are run alongside the default system probes. These features listen for probe data emitted by the probes named in the sources array.

Upon interception of data from a source probe, Purple Robot serializes the probe reading (consult the probe raw values for structure information) and passes the JavaScript object to the code defined in the feature key-value pair. This code runs and the return value of the last statement is returned as the feature’s value for the given probe reading.

The JavaScript defined in the formatter key-value pair functions similarly to that of the feature script, but instead of returning a new feature value, it generates a human-readable string summarizing the feature’s result.

The triggers key

The array of dictionaries in the triggers key-value pair define automatic actions that occur when a specified condition is met. Currently, Purple Robot supports two kinds of conditions: time-based events and probe-based events. Both triggers include a name parameter that provides a human-readable name for the trigger as well as an action parameter that contains JavaScript to be executed when the trigger fires. This JavaScript typically calls methods on the PurpleRobot singleton object to generate prompts, open applications, and so forth (reference).

datetime Triggers

Time-based triggers are indicated by the type parameter being set to datetime. These triggers support two required arguments that specify when to fire (datetime_start & datetime_end) and an optional datetime_repeat parameter that specifies a repeat pattern for the trigger. Both the date strings and the repeat pattern are specified using the formats defined in the iCalendar specification.

A common mistake to avoid is mistaking the datetime_start and datetime_end for the total duration of the repeating events. These parameters specify the start and end times of the first instance in the repeating sequence, and the number of repetitions is defined within the datetime_repeat parameter. For example, if you wanted to define a prompt that repeated daily at 5:00pm between Jan. 1, 2013 and Dec. 31, 2013, the proper way to specify these parameters are

{
  "datetime_start": "20130101T170000",
  "datetime_end": "20130101T170100",
  "datetime_repeat": "FREQ=DAILY;INTERVAL=1;UNTIL=20140101T000000"
}

not

{
  "datetime_start": "20130101T170000",
  "datetime_end": "20131231T170100",
  "datetime_repeat": "FREQ=DAILY;INTERVAL=1"
}

This second example just creates a single event that spans a single year. The trigger will fire once, then wait until the next year to fire.

A useful way to remember this subtlety is to picture how the event would look in your favorite calendar program. A time-based trigger fires once per event on the calendar.

If you do not want the trigger to fire at the beginning of the event, but instead sometime randomly within the event, you can include a Boolean datetime_random parameter that will fire the trigger at a random time within the event:

{
  "datetime_start": "20130101T170000",
  "datetime_end": "20130101T180000",
  "datetime_random": true
}

The trigger above will fire at some random time on Jan. 1, 2013 between 5:00 and 6:00pm.

probe Triggers

Probe-based triggers are similar to features in that they are executed when a system probe or feature generates a new value.

An example probe-based trigger:

{
  "type": "probe",
  "name": "Orientation Probe Test",
  "frequency": 15000,
  "action": "PurpleRobot.showNativeDialog('Phone Orientation', 'Vertical', 'Ok', 'Cancel', null, null);",
  "test": "var delta = Math.abs(probeInfo.PITCH[0]); (delta > 75 && delta < 105);"
}

When a new reading is available, its value is turned into a JavaScript object and passed to the code snippet in the test key-value pair. If the last statement of the test code returns a true value, the code contained in the action parameter is executed. The frequency parameter (specified in milliseconds) allows you to throttle the time between probe invocations. In the example above, the trigger will wait at least 15 seconds between testing & firing. This is useful to manage the local processor usage and other computational resources on the local device.