edit

EMA Scheduler

Config file name and location: mCerebrum/org.md2k.ema_scheduler/config.json

EMA scheduler configuration structure:

[
  EMA_EMI_OBJECT_1,
  EMA_EMI_OBJECT_2,
  ...
]

EMA/EMI Object

The EMA/EMI object defines what, when, and under which conditions an event will be sent to the participant.

  • id: unique object identifier string
  • type: must be one of the following
    • EMA for ecological momentary assessment
    • EMI for ecological momentary intervention
  • trigger_type: Must be one of the following:
    • RANDOM: A randomly generated assessment time subject to the criteria of the block definition
    • SELF_REPORT: Participant has generated a self-reported response
    • EVENT: Generated by a processing sensor data and computing specific events such as high stress or a smoking puff
  • name: Description that is provided to a participant through mCerebrum's interface
  • enabled: true or false to enable or disable this object
  • application: Defines where the EMA/EMI is located and which application utilized to execute it
    • id: unique EMA identifier
    • name: string that is displayed to the user describing an EMA
    • file_name: file name of a JSON document located in this folder for a specific EMA
    • package_name: Application reference which handles the specified file_name
    • timeout: Time in milliseconds after which an EMA is considered abandoned
  • blocks: A list of block object each designating:
  • scheduler_rules: List of schedule objects each designating:
  • notifications: A list of notification objects, each of which include:
  • incentive_rules: A list of incentive objects to apply

Partial Example

{
  "id": "RANDOM_EMA",
  "type": "EMA",
  "trigger_type": "RANDOM",
  "name": "Random Experience Sampling",
  "enable": true,
  "application": {
    "id": "random_experience_sampling",
    "name": "Random Experience Sampling",
    "file_name": "random_experience_sampling.json",
    "package_name": "org.md2k.ema",
    "timeout": 600000
  },
  "blocks": [SEE_BELOW],
  "scheduler_rules": [SEE_BELOW],
  "notifications": [SEE_BELOW],
  "incentive_rules": [SEE_BELOW]
}

Block object

A block object defines a time window within event can occur and provides a way to limit the total number of EMA/EMI events. These are the fields that must be specified:

  • total: Total number of times this object should be shown to a participant
  • base: A reference from which to start the offsets: base
  • start_offset: Offset time in milliseconds from the value defined in base
  • end_offset: Offset time in milliseconds from the value defined in base

Block Example

{
  "total": 1,
  "base": "DAY_START",
  "start_offset": 14400000,
  "end_offset": 28800000
}

Block List Example

"blocks": [
  {
    "total": 1,
    "base": "DAY_START",
    "start_offset": 0,
    "end_offset": 14400000
  },
  {
    "total": 1,
    "base": "DAY_START",
    "start_offset": 14400000,
    "end_offset": 28800000
  },
  {
    "total": 1,
    "base": "DAY_START",
    "start_offset": 28800000,
    "end_offset": 43200000
  }
]

Scheduler object

TODO: This section is incomplete. Missing EMI-specific configurations. Discuss with Monowar

A scheduler object designates the rules for delivering the specified EMA/EMI to a participant and contains the following parameters:

  • type: Must choose one
    • RANDOM: Randomly deliver the EMA/EMI within the current block
    • IMMEDIATE: Immediately deliver the EMA/EMI
  • start_time: Currently must be BLOCK_START but will be more flexible in a future release
  • end_time: Currently must be BLOCK_END but will be more flexible in a future release
  • divide: Divisor in which to segment the remaining time for random EMA/EMI delivery
  • conditions: A list from a a set of conditions, all which are required to be met for a notification to be delivered

Scheduler Example

This example configures a RANDOM ...

{
  "type": "RANDOM",
  "start_time": "BLOCK_START",
  "end_time": "BLOCK_END",
  "divide": 2,
  "conditions": [
    "PRIVACY",
    "VALID_BLOCK_RANDOM_EMA",
    "RANDOM_EMA_60",
    "SMOKING_EMA_10",
    "EMI_10",
    "DATA_QUALITY_5",
    "NOT_DRIVING_5",
    "PHONE_BATTERY_10"
  ]
}

Scheduler List Example

"scheduler_rules": [
  {
    "type": "RANDOM",
    "start_time": "BLOCK_START",
    "end_time": "BLOCK_END",
    "divide": 2,
    "conditions": [
      "PRIVACY",
      "VALID_BLOCK_RANDOM_EMA",
      "RANDOM_EMA_60",
      "SMOKING_EMA_10",
      "EMI_10",
      "DATA_QUALITY_5",
      "NOT_DRIVING_5",
      "PHONE_BATTERY_10"
    ]
  },
  {
    "type": "RANDOM",
    "start_time": "LAST_SCHEDULE",
    "end_time": "BLOCK_END",
    "divide": 2,
    "conditions": [
      "PRIVACY",
      "VALID_BLOCK_RANDOM_EMA",
      "RANDOM_EMA_60",
      "SMOKING_EMA_10",
      "EMI_10",
      "DATA_QUALITY_5",
      "NOT_DRIVING_5",
      "PHONE_BATTERY_10"
    ]
  },
  {
    "type": "IMMEDIATE",
    "conditions": [
      "PRIVACY",
      "VALID_BLOCK_RANDOM_EMA",
      "RANDOM_EMA_60",
      "SMOKING_EMA_10",
      "EMI_10"
    ]
  }
]

Notification object

The notification objects define what types of alerts can be sent to the participant and their duration(s).

There are two fields that must be specified:

  • time: Milliseconds after the object generation time when to deliver the specified notification(s)
  • types: A list of notification types

Notification Example

In this example, 2 minutes (120000 milliseconds) after the EMA/EMI was triggered, it sends the MICROSOFT_BAND_VIBRATE_3 and PHONE_VIBRATE_3 notifications to the Notification Manager for delivery to the participant.

{
  "time": 120000,
  "types": [
    "MICROSOFT_BAND_VIBRATE_3",
    "PHONE_VIBRATE_3"
  ]
}

Notification List Example

"notifications": [
  {
    "time": 0,
    "types": [
      "MICROSOFT_BAND_VIBRATE_3",
      "MICROSOFT_BAND_MESSAGE_EMA",
      "PHONE_VIBRATE_3",
      "PHONE_MESSAGE_DELAY_EMA",
      "PHONE_SCREEN"
    ]
  },
  {
    "time": 120000,
    "types": [
      "MICROSOFT_BAND_VIBRATE_3",
      "PHONE_VIBRATE_3"
    ]
  },
  {
    "time": 240000,
    "types": [
      "MICROSOFT_BAND_VIBRATE_3",
      "PHONE_VIBRATE_3"
    ]
  }
]

Incentive object

Incentives allow the system to be configuration for micro-payments based on the participant meeting a set of conditions or rules. The following must be specified:

  • incentive: Payment in dollars
  • messages: List of strings to be shown to the participant
  • conditions: A set of conditions that must be met to receive this incentive.

Incentive Example

{
  "incentive": 0.75,
  "messages": [
    "Thank you. You will be paid $0.75 for taking the survey within 5 minutes and wearing the sensors for more than 60% of the time since day started.",
    "You will be paid $0.75",
    "Total Earning: $"
  ],
  "conditions": [
    "DATA_QUALITY_DAY_START",
    "EMA_ANSWER_5"
  ]
}

Incentive List Example

"incentive_rules": [
  {
    "incentive": 0.75,
    "messages": [
      "Thank you. You will be paid $0.75 for taking the survey within 5 minutes and wearing the sensors for more than 60% of the time since day started.",
      "You will be paid $0.75",
      "Total Earning: $"
    ],
    "conditions": [
      "DATA_QUALITY_DAY_START",
      "EMA_ANSWER_5"
    ]
  },
  {
    "incentive": 0.5,
    "messages": [
      "Thank you. You will be paid $0.50 for taking the survey and wearing the sensors for more than 60% of the time since day started. But you missed $0.25 bonus for not answering the survey within 5 minutes.",
      "You will be paid $0.50",
      "Total Earning: $"
    ],
    "conditions": [
      "DATA_QUALITY_DAY_START"
    ]
  },
  {
    "incentive": 0,
    "messages": [
      "Thank you. Unfortunately, you will be paid $0.00 because you have not worn sensors for at least 60% of the time since day started.",
      "You will be paid $0.50",
      "Total Earning: $"
    ],
    "conditions": []
  }
]

Complete Example

[
  {
    "id": "RANDOM_EMA",
    "type": "EMA",
    "trigger_type": "RANDOM",
    "name": "Random Experience Sampling",
    "enable": true,
    "application": {
      "id": "random_experience_sampling",
      "name": "Random Experience Sampling",
      "file_name": "random_experience_sampling.json",
      "package_name": "org.md2k.ema",
      "timeout": 600000
    },
    "blocks": [
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 0,
        "end_offset": 14400000
      },
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 14400000,
        "end_offset": 28800000
      },
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 28800000,
        "end_offset": 43200000
      }
    ],
    "scheduler_rules": [
      {
        "type": "RANDOM",
        "start_time": "BLOCK_START",
        "end_time": "BLOCK_END",
        "divide": 2,
        "conditions": [
          "PRIVACY",
          "VALID_BLOCK_RANDOM_EMA",
          "RANDOM_EMA_60",
          "SMOKING_EMA_10",
          "EMI_10",
          "DATA_QUALITY_5",
          "NOT_DRIVING_5",
          "PHONE_BATTERY_10"
        ]
      },
      {
        "type": "RANDOM",
        "start_time": "LAST_SCHEDULE",
        "end_time": "BLOCK_END",
        "divide": 2,
        "conditions": [
          "PRIVACY",
          "VALID_BLOCK_RANDOM_EMA",
          "RANDOM_EMA_60",
          "SMOKING_EMA_10",
          "EMI_10",
          "DATA_QUALITY_5",
          "NOT_DRIVING_5",
          "PHONE_BATTERY_10"
        ]
      },
      {
        "type": "IMMEDIATE",
        "conditions": [
          "PRIVACY",
          "VALID_BLOCK_RANDOM_EMA",
          "RANDOM_EMA_60",
          "SMOKING_EMA_10",
          "EMI_10"
        ]
      }
    ],
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_EMA",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_DELAY_EMA",
          "PHONE_SCREEN"
        ]
      },
      {
        "time": 120000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      },
      {
        "time": 240000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      }
    ],
    "incentive_rules": [
      {
        "incentive": 0.75,
        "messages": [
          "Thank you. You will be paid $0.75 for taking the survey within 5 minutes and wearing the sensors for more than 60% of the time since day started.",
          "You will be paid $0.75",
          "Total Earning: $"
        ],
        "conditions": [
          "DATA_QUALITY_DAY_START",
          "EMA_ANSWER_5"
        ]
      },
      {
        "incentive": 0.5,
        "messages": [
          "Thank you. You will be paid $0.50 for taking the survey and wearing the sensors for more than 60% of the time since day started. But you missed $0.25 bonus for not answering the survey within 5 minutes.",
          "You will be paid $0.50",
          "Total Earning: $"
        ],
        "conditions": [
          "DATA_QUALITY_DAY_START"
        ]
      },
      {
        "incentive": 0,
        "messages": [
          "Thank you. Unfortunately, you will be paid $0.00 because you have not worn sensors for at least 60% of the time since day started.",
          "You will be paid $0.50",
          "Total Earning: $"
        ],
        "conditions": []
      }
    ]
  },
  {
    "id": "SMOKING_EMA",
    "type": "EMA",
    "trigger_type": "SELF_REPORT",
    "name": "Event Contingent EMA",
    "enable": true,
    "application": {
      "id": "event_contingent_recording",
      "name": "Event Contingent Recording",
      "package_name": "org.md2k.ema",
      "file_name": "event_contingent_recording.json",
      "timeout": 600000
    },
    "blocks": [
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 0,
        "end_offset": 14400000
      },
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 14400000,
        "end_offset": 28800000
      },
      {
        "total": 1,
        "base": "DAY_START",
        "start_offset": 28800000,
        "end_offset": 43200000
      }
    ],
    "scheduler_rules": [
      {
        "type": "IMMEDIATE",
        "data_source": {
          "type": "EVENT"
        },
        "parameters": [
          "SMOKING"
        ],
        "conditions": [
          "PRIVACY",
          "VALID_BLOCK_SMOKING_EMA",
          "RANDOM_EMA_10",
          "SMOKING_EMA_30",
          "EMI_10",
          "DATA_QUALITY_5",
          "NOT_DRIVING_5",
          "PHONE_BATTERY_10"
        ]
      }
    ],
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_EMA",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_DELAY_EMA",
          "PHONE_SCREEN"
        ]
      },
      {
        "time": 120000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      },
      {
        "time": 240000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      }
    ],
    "incentive_rules": [
      {
        "incentive": 0.75,
        "messages": [
          "Thank you. You will be paid $0.75 for taking the survey within 5 minutes and wearing the sensors for more than 60% of the time since day started.",
          "You will be paid $0.75",
          "Total Earning: $"
        ],
        "conditions": [
          "DATA_QUALITY_DAY_START",
          "EMA_ANSWER_5"
        ]
      },
      {
        "incentive": 0.5,
        "messages": [
          "Thank you. You will be paid $0.50 for taking the survey and wearing the sensors for more than 60% of the time since day started. But you missed $0.25 bonus for not answering the survey within 5 minutes.",
          "You will be paid $0.50",
          "Total Earning: $"
        ],
        "conditions": [
          "DATA_QUALITY_DAY_START"
        ]
      },
      {
        "incentive": 0,
        "messages": [
          "Thank you. Unfortunately, you will be paid $0.00 because you have not worn sensors for at least 60% of the time since day started.",
          "You will be paid $0.50",
          "Total Earning: $"
        ],
        "conditions": []
      }
    ]
  },
  {
    "id": "END_OF_DAY_EMA",
    "type": "EMA",
    "trigger_type": "SELF_REPORT",
    "name": "End of day EMA",
    "enable": true,
    "application": {
      "id": "end_of_day_recording",
      "name": "End of Day Recording",
      "package_name": "org.md2k.ema",
      "file_name": "end_of_day_recording.json",
      "timeout": 600000
    },
    "scheduler_rules": [
      {
        "type": "IMMEDIATE",
        "data_source": {
          "type": "DAY_END"
        }
      }
    ],
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_EMA",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_DELAY_EMA_15_30_60_120",
          "PHONE_SCREEN"
        ]
      },
      {
        "time": 120000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      },
      {
        "time": 240000,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "PHONE_VIBRATE_3"
        ]
      }
    ],
    "incentive_rules": [
      {
        "incentive": 1,
        "messages": [
          "Thank you. You will be paid $1.00 for taking the End of Day survey.",
          "You will be paid $1.00",
          "Total Earning: $"
        ],
        "conditions": []
      }
    ]
  },
  {
    "id": "EMI",
    "type": "EMI",
    "trigger_type": "EVENT",
    "name": "Intervention",
    "enable": true,
    "scheduler_rules": [
      {
        "type": "IMMEDIATE",
        "data_source": {
          "type": "ORG_MD2K_CSTRESS_STRESS_EPISODE_CLASSIFICATION"
        },
        "parameters": [
          "0",
          "2"
        ],
        "conditions": [
          "PRIVACY",
          "RANDOM_EMA_10",
          "SMOKING_EMA_10",
          "EMI_60",
          "DATA_QUALITY_5",
          "NOT_DRIVING_5",
          "PHONE_BATTERY_10"
        ]
      }
    ],
    "incentive_rules": [
      {
        "incentive": 1,
        "conditions": []
      }
    ]
  },
  {
    "id": "MOODSURFING",
    "type": "EMI",
    "name": "MoodSurfing",
    "trigger_type": "EVENT",
    "enable": false,
    "application": {
      "id": "moodsurfing",
      "name": "MoodSurfing",
      "package_name": "org.md2k.moodsurfing",
      "timeout": 600000
    },
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_MOODSURFING",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_MOODSURFING"
        ]
      }
    ]
  },
  {
    "id": "THOUGHT_SHAKEUP",
    "type": "EMI",
    "name": "Thought Shakeup",
    "trigger_type": "EVENT",
    "enable": false,
    "application": {
      "id": "thought_shakeup",
      "name": "Thought Shakeup",
      "package_name": "org.md2k.thoughtshakeup",
      "timeout": 600000
    },
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_THOUGHTSHAKEUP",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_THOUGHTSHAKEUP"
        ]
      }
    ]
  },
  {
    "id": "HEADSPACE",
    "type": "EMI",
    "name": "HeadSpace",
    "trigger_type": "EVENT",
    "enable": false,
    "application": {
      "id": "head_space",
      "name": "HeadSpace",
      "package_name": "com.getsomeheadspace.android",
      "timeout": 1000
    },
    "notifications": [
      {
        "time": 0,
        "types": [
          "MICROSOFT_BAND_VIBRATE_3",
          "MICROSOFT_BAND_MESSAGE_HEADSPACE",
          "PHONE_VIBRATE_3",
          "PHONE_MESSAGE_HEADSPACE"
        ]
      }
    ]
  }
]