getStudyProtocol method

Future<SmartphoneStudyProtocol> getStudyProtocol(
  1. String studyDeploymentId
)
override

Get a SmartphoneStudyProtocol from the CARP backend.

Note that in the CARP backend, a study protocol is empbedded as a CustomProtocolTask and deployed as part of a so-called Participation for a user, with a specific studyDeploymentId.

Throws a CarpServiceException if not successful.

Implementation

Future<SmartphoneStudyProtocol> getStudyProtocol(
    String studyDeploymentId) async {
  assert(CarpService().isConfigured,
      "CARP Service has not been configured - call 'CarpService().configure()' first.");
  assert(CarpService().currentUser != null,
      "No user is authenticated - call 'CarpService().authenticate()' first.");
  info(
      'Retrieving study protocol from CARP web service - studyDeploymentId: $studyDeploymentId');

  if (!CarpDeploymentService().isConfigured)
    CarpDeploymentService().configureFrom(CarpService());

  DeploymentReference reference =
      CarpDeploymentService().deployment(studyDeploymentId);

  // get status
  StudyDeploymentStatus deploymentStatus = await reference.getStatus();
  info('Deployment status: $deploymentStatus');

  if (deploymentStatus.masterDeviceStatus?.device != null) {
    // register the remaining devices needed for deployment
    if (deploymentStatus.masterDeviceStatus
            ?.remainingDevicesToRegisterToObtainDeployment !=
        null) {
      for (String deviceRolename in deploymentStatus.masterDeviceStatus!
          .remainingDevicesToRegisterToObtainDeployment!) {
        info("Registring device: '$deviceRolename'");
        try {
          deploymentStatus =
              await reference.registerDevice(deviceRoleName: deviceRolename);
        } catch (error) {
          // we only print a warning - often an exception here arise when the device is already registrered
          warning("Error registring device '$deviceRolename'.\n$error");
        }
      }
    }

    // get the deployment
    MasterDeviceDeployment deployment = await reference.get();
    info('Deployment retrieved: $deployment');

    if (deployment.tasks.isNotEmpty) {
      // asume that this deployment only contains one custom task
      TaskDescriptor task = deployment.tasks[0];
      if (task is CustomProtocolTask) {
        // we expect to get a protocol of type [SmartphoneStudyProtocol]
        SmartphoneStudyProtocol protocol = SmartphoneStudyProtocol.fromJson(
            json.decode(task.studyProtocol) as Map<String, dynamic>);

        // mark this deployment as successful
        try {
          await reference.success();
        } catch (error) {
          // we only print a warning
          // see issue #50 - there is a bug in CARP
          warning(
              "Error marking deployment '$studyDeploymentId' as successful.\n$error");
        }
        info("Study protocol '$studyDeploymentId' successfully downloaded.");
        return protocol;
      } else {
        await reference.unRegisterDevice(
            deviceRoleName:
                deploymentStatus.masterDeviceStatus!.device.roleName);
        throw CarpServiceException(
            message:
                'The deployment does not contain a CustomProtocolTask - task: $task');
      }
    } else {
      await reference.unRegisterDevice(
          deviceRoleName:
              deploymentStatus.masterDeviceStatus!.device.roleName);
      throw CarpServiceException(
          message:
              'The deployment does not contain any tasks - deployment: $deployment');
    }
  } else {
    throw CarpServiceException(
        message:
            'There is not Master Device defined in this deployment: $deploymentStatus');
  }
}