From 2524257330e93d27605f42f25e33cde1187590fa Mon Sep 17 00:00:00 2001 From: bardram Date: Wed, 29 May 2024 13:53:41 +0200 Subject: [PATCH 1/4] fix of #369 --- .../lib/carp_services/carp_base_service.dart | 4 +- .../lib/carp_services/carp_service.dart | 15 ++--- .../lib/carp_services/carp_tasks.dart | 6 +- .../lib/carp_services/file_reference.dart | 6 +- .../lib/carp_services/http_retry.dart | 62 +++++++++++++------ 5 files changed, 59 insertions(+), 34 deletions(-) diff --git a/backends/carp_webservices/lib/carp_services/carp_base_service.dart b/backends/carp_webservices/lib/carp_services/carp_base_service.dart index 9b27d320..7c15599a 100644 --- a/backends/carp_webservices/lib/carp_services/carp_base_service.dart +++ b/backends/carp_webservices/lib/carp_services/carp_base_service.dart @@ -95,8 +95,8 @@ abstract class CarpBaseService { // debug( // 'RESPONSE: $httpStatusCode\n${toJsonString(json.decode(responseBody))}'); - // check if this is a json list or an empty string - // if so turn it into a valid json map + // Check if this is a json list or an empty string + // If so turn it into a valid json map if (responseBody.startsWith('[')) responseBody = '{"items":$responseBody}'; if (responseBody.isEmpty) responseBody = '{}'; diff --git a/backends/carp_webservices/lib/carp_services/carp_service.dart b/backends/carp_webservices/lib/carp_services/carp_service.dart index b76bdf10..7eacfd3a 100644 --- a/backends/carp_webservices/lib/carp_services/carp_service.dart +++ b/backends/carp_webservices/lib/carp_services/carp_service.dart @@ -7,10 +7,10 @@ part of 'carp_services.dart'; -/// Provide access to a CARP web service endpoint. +/// Provide access to a CARP Web Services (CAWS) endpoints. /// /// The (current) assumption is that each Flutter app (using this library) will -/// only connect to one CARP web service backend. +/// only connect to one CARP web services backend. /// Therefore a [CarpService] is a singleton and can be used like: /// /// ```dart @@ -65,10 +65,11 @@ class CarpService extends CarpBaseService { Future createConsentDocument( Map document) async { // POST the document to the CARP web service - http.Response response = await http.post( - Uri.parse(Uri.encodeFull(consentDocumentEndpointUri)), - headers: headers, - body: json.encode(document)); + http.Response response = await httpr.post( + consentDocumentEndpointUri, + headers: headers, + body: json.encode(document), + ); int httpStatusCode = response.statusCode; Map responseJson = @@ -161,7 +162,7 @@ class CarpService extends CarpBaseService { int httpStatusCode = response.statusCode; switch (httpStatusCode) { - case 200: + case HttpStatus.ok: { List list = json.decode(response.body) as List; List fileList = []; diff --git a/backends/carp_webservices/lib/carp_services/carp_tasks.dart b/backends/carp_webservices/lib/carp_services/carp_tasks.dart index 19fc8cbc..c5d07a59 100644 --- a/backends/carp_webservices/lib/carp_services/carp_tasks.dart +++ b/backends/carp_webservices/lib/carp_services/carp_tasks.dart @@ -88,8 +88,8 @@ class FileUploadTask extends CarpServiceTask { switch (httpStatusCode) { // CARP web service returns "201 Created" when a file is created on the server. - case 200: - case 201: + case HttpStatus.ok: + case HttpStatus.created: { // save the id generated from the server reference.id = map["id"] as int; @@ -152,7 +152,7 @@ class FileDownloadTask extends CarpServiceTask { final int httpStatusCode = response.statusCode; switch (httpStatusCode) { - case 200: + case HttpStatus.ok: { _state = TaskStateType.success; file.writeAsBytes(response.bodyBytes); diff --git a/backends/carp_webservices/lib/carp_services/file_reference.dart b/backends/carp_webservices/lib/carp_services/file_reference.dart index d302a079..99a8dce5 100644 --- a/backends/carp_webservices/lib/carp_services/file_reference.dart +++ b/backends/carp_webservices/lib/carp_services/file_reference.dart @@ -58,7 +58,7 @@ class FileStorageReference extends CarpReference { print(response.body); switch (httpStatusCode) { - case 200: + case HttpStatus.ok: { return CarpFileResponse._(map); } @@ -84,8 +84,8 @@ class FileStorageReference extends CarpReference { int httpStatusCode = response.statusCode; switch (httpStatusCode) { - case 200: - case 204: + case HttpStatus.ok: + case HttpStatus.noContent: { return httpStatusCode; } diff --git a/backends/carp_webservices/lib/carp_services/http_retry.dart b/backends/carp_webservices/lib/carp_services/http_retry.dart index 5c5fa78a..a167b584 100644 --- a/backends/carp_webservices/lib/carp_services/http_retry.dart +++ b/backends/carp_webservices/lib/carp_services/http_retry.dart @@ -101,19 +101,21 @@ class HTTPRetry { } /// Sends an HTTP GET request with the given [headers] to the given [url]. - Future get(String url, {Map? headers}) async => - await retry( - () => client - .get( - Uri.parse(Uri.encodeFull(url)), - headers: headers, - ) - .timeout(const Duration(seconds: 20)), - delayFactor: const Duration(seconds: 5), - maxAttempts: 15, - retryIf: (e) => e is SocketException || e is TimeoutException, - onRetry: (e) => print('${e.runtimeType} - Retrying to GET $url'), - ); + Future get(String url, {Map? headers}) async { + final response = await retry( + () => client + .get( + Uri.parse(Uri.encodeFull(url)), + headers: headers, + ) + .timeout(const Duration(seconds: 20)), + delayFactor: const Duration(seconds: 5), + maxAttempts: 15, + retryIf: (e) => e is SocketException || e is TimeoutException, + onRetry: (e) => print('${e.runtimeType} - Retrying to GET $url'), + ); + return clean(response); + } /// Sends an HTTP POST request with the given [headers] and [body] to the given [url]. Future post( @@ -123,7 +125,7 @@ class HTTPRetry { Encoding? encoding, }) async { // calling the http POST method using the retry approach - final http.Response response = await retry( + final response = await retry( () => client .post( Uri.parse(Uri.encodeFull(url)), @@ -137,7 +139,8 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to POST $url'), ); - return response; + + return clean(response); } /// Sends an HTTP PUT request with the given [headers] and [body] to the given [url]. @@ -148,7 +151,7 @@ class HTTPRetry { Encoding? encoding, }) async { // calling the http PUT method using the retry approach - final http.Response response = await retry( + final response = await retry( () => client .put( Uri.parse(Uri.encodeFull(url)), @@ -162,7 +165,7 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to PUT $url'), ); - return response; + return clean(response); } /// Sends an HTTP DELETE request with the given [headers] to the given [url]. @@ -171,7 +174,7 @@ class HTTPRetry { Map? headers, }) async { // calling the http DELETE method using the retry approach - final http.Response response = await retry( + final response = await retry( () => client .delete( Uri.parse(Uri.encodeFull(url)), @@ -183,6 +186,27 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to DELETE $url'), ); - return response; + return clean(response); } + + /// Check if we get an Nginx reverse proxy error in HTML format, and if so + /// convert it to a JSON error message. + /// + /// See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/369 + http.Response clean(http.Response response) => + response.body.startsWith('') + ? http.Response( + '{' + '"statusCode": 502,' + '"message": "502 Bad Gateway.",' + '"path": "POST ${response.request?.url}"' + '}', + response.statusCode, + headers: response.headers, + isRedirect: response.isRedirect, + persistentConnection: response.persistentConnection, + reasonPhrase: response.reasonPhrase, + request: response.request, + ) + : response; } From 1d3e4f4050a209e0fa3abdb5622bab9b1114a994 Mon Sep 17 00:00:00 2001 From: bardram Date: Thu, 30 May 2024 08:36:19 +0200 Subject: [PATCH 2/4] fix of #392 --- .../lib/carp_auth/carp_auth_service.dart | 1 + .../lib/carp_services/http_retry.dart | 39 +++++++++++++++++++ .../test/carp_properties.dart | 4 +- .../test/credentials_template.dart | 2 + 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/backends/carp_webservices/lib/carp_auth/carp_auth_service.dart b/backends/carp_webservices/lib/carp_auth/carp_auth_service.dart index 6893186f..352178bd 100644 --- a/backends/carp_webservices/lib/carp_auth/carp_auth_service.dart +++ b/backends/carp_webservices/lib/carp_auth/carp_auth_service.dart @@ -8,6 +8,7 @@ class CarpAuthService extends CarpAuthBaseService { /// Before this instance can be used, it must be configured using the /// [configure] method. factory CarpAuthService() => _instance; + CarpAuthService.instance() : this._(); /// Is a user authenticated? diff --git a/backends/carp_webservices/lib/carp_services/http_retry.dart b/backends/carp_webservices/lib/carp_services/http_retry.dart index a167b584..c79fe745 100644 --- a/backends/carp_webservices/lib/carp_services/http_retry.dart +++ b/backends/carp_webservices/lib/carp_services/http_retry.dart @@ -114,6 +114,16 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to GET $url'), ); + + // Check if we are accessing a newly created resource and refresh token once + // if we get a 403 forbidden response. + // + // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + return get(url, headers: headers); + } + return clean(response); } @@ -140,6 +150,15 @@ class HTTPRetry { onRetry: (e) => print('${e.runtimeType} - Retrying to POST $url'), ); + // Check if we are accessing a newly created resource and refresh token once + // if we get a 403 forbidden response. + // + // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + return post(url, headers: headers, body: body, encoding: encoding); + } + return clean(response); } @@ -165,6 +184,16 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to PUT $url'), ); + + // Check if we are accessing a newly created resource and refresh token once + // if we get a 403 forbidden response. + // + // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + return put(url, headers: headers, body: body, encoding: encoding); + } + return clean(response); } @@ -186,6 +215,16 @@ class HTTPRetry { retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) => print('${e.runtimeType} - Retrying to DELETE $url'), ); + + // Check if we are accessing a newly created resource and refresh token once + // if we get a 403 forbidden response. + // + // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + return put(url, headers: headers); + } + return clean(response); } diff --git a/backends/carp_webservices/test/carp_properties.dart b/backends/carp_webservices/test/carp_properties.dart index d5bfcaab..b786d619 100644 --- a/backends/carp_webservices/test/carp_properties.dart +++ b/backends/carp_webservices/test/carp_properties.dart @@ -11,7 +11,7 @@ class CarpProperties { Uri get uri => Uri( scheme: 'https', - host: 'dev.carp.dk', + host: cawsUri, ); CarpAuthProperties get authProperties => CarpAuthProperties( @@ -27,7 +27,7 @@ class CarpProperties { ); CarpApp get app => CarpApp( - name: "CAWS @ DigitalOcean [DEV]", + name: "CAWS @ $cawsUri", uri: uri, studyDeploymentId: testDeploymentId, studyId: testStudyId, diff --git a/backends/carp_webservices/test/credentials_template.dart b/backends/carp_webservices/test/credentials_template.dart index 497c34a1..fa953b15 100644 --- a/backends/carp_webservices/test/credentials_template.dart +++ b/backends/carp_webservices/test/credentials_template.dart @@ -11,6 +11,8 @@ // HOWEVER, remember to add the file to .gitignore in order not to commit // the authentication details. +const String cawsUri = 'dev.carp.dk'; + // Username + password for the user doing the testing const String username = 'a_username'; const String password = 'the_password'; From ce0ed328b5a24810e1871fd3e46dd5a46e2e11ce Mon Sep 17 00:00:00 2001 From: bardram Date: Thu, 30 May 2024 22:06:46 +0200 Subject: [PATCH 3/4] refactor and optimization based on testing - update to unit tests too --- .../carp_webservices/analysis_options.yaml | 3 +- .../cache/upload/batch-0.json | 10 +- .../cache/upload/batch-1.json | 10 +- .../example/analysis_options.yaml | 28 - .../carp_webservices/example/lib/main.dart | 9 +- .../lib/carp_services/carp_base_service.dart | 96 +- .../lib/carp_services/carp_service.dart | 27 +- .../lib/carp_services/carp_tasks.dart | 5 - .../carp_services/collection_reference.dart | 30 +- .../carp_services/data_point_reference.dart | 25 +- .../lib/carp_services/document_reference.dart | 41 +- .../lib/carp_services/file_reference.dart | 8 +- .../lib/carp_services/http_retry.dart | 185 +- .../test/carp_data_stream_service_test.dart | 23 +- .../test/carp_service_test.dart | 199 +- .../carp_webservices/test/json/batch_2.json | 2972 +++++++++++++++-- 16 files changed, 3003 insertions(+), 668 deletions(-) delete mode 100644 backends/carp_webservices/example/analysis_options.yaml diff --git a/backends/carp_webservices/analysis_options.yaml b/backends/carp_webservices/analysis_options.yaml index c9eb4528..47925a79 100644 --- a/backends/carp_webservices/analysis_options.yaml +++ b/backends/carp_webservices/analysis_options.yaml @@ -15,4 +15,5 @@ linter: cancel_subscriptions: true constant_identifier_names: false depend_on_referenced_packages: true - avoid_print: false + avoid_print: true + diff --git a/backends/carp_webservices/cache/upload/batch-0.json b/backends/carp_webservices/cache/upload/batch-0.json index 7ce40c68..a0ffd3f6 100644 --- a/backends/carp_webservices/cache/upload/batch-0.json +++ b/backends/carp_webservices/cache/upload/batch-0.json @@ -1,7 +1,7 @@ [ { "carp_header": { - "start_time": "2024-04-21T16:15:54.710227Z", + "start_time": "2024-05-30T13:18:31.845318Z", "data_format": { "namespace": "dk.cachet.carp", "name": "ambientlight" @@ -17,7 +17,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710234Z", + "start_time": "2024-05-30T13:18:31.845325Z", "data_format": { "namespace": "dk.cachet.carp", "name": "ambientlight" @@ -33,7 +33,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710242Z", + "start_time": "2024-05-30T13:18:31.845331Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" @@ -48,7 +48,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710245Z", + "start_time": "2024-05-30T13:18:31.845333Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" @@ -63,7 +63,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710247Z", + "start_time": "2024-05-30T13:18:31.845335Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" diff --git a/backends/carp_webservices/cache/upload/batch-1.json b/backends/carp_webservices/cache/upload/batch-1.json index 7ce40c68..a0ffd3f6 100644 --- a/backends/carp_webservices/cache/upload/batch-1.json +++ b/backends/carp_webservices/cache/upload/batch-1.json @@ -1,7 +1,7 @@ [ { "carp_header": { - "start_time": "2024-04-21T16:15:54.710227Z", + "start_time": "2024-05-30T13:18:31.845318Z", "data_format": { "namespace": "dk.cachet.carp", "name": "ambientlight" @@ -17,7 +17,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710234Z", + "start_time": "2024-05-30T13:18:31.845325Z", "data_format": { "namespace": "dk.cachet.carp", "name": "ambientlight" @@ -33,7 +33,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710242Z", + "start_time": "2024-05-30T13:18:31.845331Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" @@ -48,7 +48,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710245Z", + "start_time": "2024-05-30T13:18:31.845333Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" @@ -63,7 +63,7 @@ }, { "carp_header": { - "start_time": "2024-04-21T16:15:54.710247Z", + "start_time": "2024-05-30T13:18:31.845335Z", "data_format": { "namespace": "dk.cachet.carp", "name": "deviceinformation" diff --git a/backends/carp_webservices/example/analysis_options.yaml b/backends/carp_webservices/example/analysis_options.yaml deleted file mode 100644 index 0d290213..00000000 --- a/backends/carp_webservices/example/analysis_options.yaml +++ /dev/null @@ -1,28 +0,0 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. -include: package:flutter_lints/flutter.yaml - -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at https://dart.dev/lints. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/backends/carp_webservices/example/lib/main.dart b/backends/carp_webservices/example/lib/main.dart index 3a0327e7..3adcb8a9 100644 --- a/backends/carp_webservices/example/lib/main.dart +++ b/backends/carp_webservices/example/lib/main.dart @@ -132,13 +132,16 @@ class AppBLoC { void dispose() async {} Future getStudyInvitation( - BuildContext context) async { + BuildContext context, + ) async { // configure a participant service based on the carp service already configured CarpParticipationService().configureFrom(CarpService()); _invitation = await CarpParticipationService().getStudyInvitation(context); - print('CARP Study Invitation: $_invitation'); + debugPrint('CARP Study Invitation: $_invitation'); + // check that the app has been updated to reflect the study id and deployment id - print('Study ID: ${app.studyId}, Deployment ID: ${app.studyDeploymentId}'); + debugPrint( + 'Study ID: ${app.studyId}, Deployment ID: ${app.studyDeploymentId}'); return _invitation; } } diff --git a/backends/carp_webservices/lib/carp_services/carp_base_service.dart b/backends/carp_webservices/lib/carp_services/carp_base_service.dart index 7c15599a..bb01cc4f 100644 --- a/backends/carp_webservices/lib/carp_services/carp_base_service.dart +++ b/backends/carp_webservices/lib/carp_services/carp_base_service.dart @@ -86,9 +86,12 @@ abstract class CarpBaseService { final String body = toJsonString(request.toJson()); _endpointName = endpointName ?? rpcEndpointName; - debug('REQUEST: $rpcEndpointUri\n$body'); - http.Response response = await httpr.post(Uri.encodeFull(rpcEndpointUri), - headers: headers, body: body); + debug('REQUEST: POST $rpcEndpointUri\n$body'); + http.Response response = await httpr.post( + Uri.encodeFull(rpcEndpointUri), + headers: headers, + body: body, + ); int httpStatusCode = response.statusCode; String responseBody = response.body; debug('RESPONSE: $httpStatusCode\n$responseBody'); @@ -115,4 +118,91 @@ abstract class CarpBaseService { path: responseJson["path"].toString(), ); } + + /// Sends an HTTP GET request to the given [url] for this CAWS service. + Future _get(String url) async { + debug('REQUEST: GET $url'); + + var response = await httpr.get(url, headers: headers); + + debug('RESPONSE: ${response.statusCode}\n${response.body}'); + + // If we get a 403 forbidden response try to refresh token and retry once. + // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + response = await httpr.get(url, headers: headers); + } + + return _clean(response); + } + + /// Sends an HTTP POST request with [body] to the given [url] for this CAWS service. + Future _post(String url, {Object? body}) async { + debug('REQUEST: POST $url\n$body'); + + var response = await httpr.post(url, headers: headers, body: body); + + debug('RESPONSE: ${response.statusCode}\n${response.body}'); + + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + response = await httpr.post(url, headers: headers, body: body); + } + + return _clean(response); + } + + /// Sends an HTTP PUT request with [body] to the given [url] for this CAWS service. + Future _put(String url, {Object? body}) async { + debug('REQUEST: PUT $url\n$body'); + + var response = await httpr.put(url, headers: headers, body: body); + + debug('RESPONSE: ${response.statusCode}\n${response.body}'); + + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + response = await httpr.put(url, headers: headers, body: body); + } + + return _clean(response); + } + + /// Sends an HTTP DELETE request to the given [url] for this CAWS service. + Future _delete(String url) async { + debug('REQUEST: DELETE $url'); + + var response = await httpr.delete(url, headers: headers); + + debug('RESPONSE: ${response.statusCode}\n${response.body}'); + + if (response.statusCode == HttpStatus.forbidden) { + await CarpAuthService().refresh(); + response = await httpr.delete(url, headers: headers); + } + + return _clean(response); + } + + /// Check if we get an Nginx reverse proxy error in HTML format, and if so + /// convert it to a JSON error message. + /// + /// See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/369 + http.Response _clean(http.Response response) => + response.body.startsWith('') + ? http.Response( + '{' + '"statusCode": 502,' + '"message": "502 Bad Gateway.",' + '"path": "POST ${response.request?.url}"' + '}', + response.statusCode, + headers: response.headers, + isRedirect: response.isRedirect, + persistentConnection: response.persistentConnection, + reasonPhrase: response.reasonPhrase, + request: response.request, + ) + : response; } diff --git a/backends/carp_webservices/lib/carp_services/carp_service.dart b/backends/carp_webservices/lib/carp_services/carp_service.dart index 7eacfd3a..50918d6d 100644 --- a/backends/carp_webservices/lib/carp_services/carp_service.dart +++ b/backends/carp_webservices/lib/carp_services/carp_service.dart @@ -35,23 +35,6 @@ class CarpService extends CarpBaseService { @override CarpApp get app => nonNullAble(_app); - /// The headers for any authenticated HTTP REST call to this [CarpService]. - @override - Map get headers { - if (CarpAuthService().currentUser.token == null) { - throw CarpServiceException( - message: - "OAuth token is null. Call 'CarpAuthService().authenticate()' first."); - } - - return { - "Content-Type": "application/json", - "Authorization": - "bearer ${CarpAuthService().currentUser.token!.accessToken}", - "cache-control": "no-cache" - }; - } - // -------------------------------------------------------------------------- // CONSENT DOCUMENT // -------------------------------------------------------------------------- @@ -64,10 +47,11 @@ class CarpService extends CarpBaseService { /// Returns the created [ConsentDocument] if the document is uploaded correctly. Future createConsentDocument( Map document) async { + debug('REQUEST: POST $consentDocumentEndpointUri'); + // POST the document to the CARP web service - http.Response response = await httpr.post( + http.Response response = await _post( consentDocumentEndpointUri, - headers: headers, body: json.encode(document), ); @@ -93,8 +77,9 @@ class CarpService extends CarpBaseService { String url = "$consentDocumentEndpointUri/$id"; // GET the consent document from the CARP web service - http.Response response = - await httpr.get(Uri.encodeFull(url), headers: headers); + http.Response response = await _get(Uri.encodeFull(url)); + + debug('RESPONSE: ${response.statusCode}\n${response.body}'); int httpStatusCode = response.statusCode; Map responseJson = diff --git a/backends/carp_webservices/lib/carp_services/carp_tasks.dart b/backends/carp_webservices/lib/carp_services/carp_tasks.dart index c5d07a59..3760ab81 100644 --- a/backends/carp_webservices/lib/carp_services/carp_tasks.dart +++ b/backends/carp_webservices/lib/carp_services/carp_tasks.dart @@ -75,14 +75,9 @@ class FileUploadTask extends CarpServiceTask { request.files.add(ClonableMultipartFile.fromFileSync(file.path)); - print('files # : ${request.files.length}'); - httpr.send(request).then((http.StreamedResponse response) { response.stream.toStringStream().first.then((body) { final int httpStatusCode = response.statusCode; - print("httpStatusCode: $httpStatusCode"); - print("response:\n$response"); - print("body:\n$body"); final Map map = json.decode(body) as Map; diff --git a/backends/carp_webservices/lib/carp_services/collection_reference.dart b/backends/carp_webservices/lib/carp_services/collection_reference.dart index 69bed181..f0153fb1 100644 --- a/backends/carp_webservices/lib/carp_services/collection_reference.dart +++ b/backends/carp_webservices/lib/carp_services/collection_reference.dart @@ -48,12 +48,12 @@ class CollectionReference extends CarpReference { /// Returns the path of this collection (relative to the root of the web service). String get path => _path; - /// The full CARP web service path to this collection. - String get carpPath => + /// The full CARP Web Service (CAWS) path to this collection. + String get cawsPath => '/api/studies/${service.app!.studyId}/collections/$path'; /// The full URI for the collection endpoint for this [CollectionReference]. - String get collectionUri => "${service.app!.uri.toString()}$carpPath"; + String get collectionUri => "${service.app!.uri.toString()}$cawsPath"; /// The full URI for the collection endpoint for this [CollectionReference] by its unique [id]. String get collectionUriByID => @@ -63,16 +63,9 @@ class CollectionReference extends CarpReference { /// /// If no collection exists on the server (yet), this local CollectionReference is returned. Future get() async { - final restHeaders = headers; - - debug('REQUEST: GET $collectionUri\n'); - - final response = - await httpr.get(Uri.encodeFull(collectionUri), headers: restHeaders); + final response = await service._get(collectionUri); int httpStatusCode = response.statusCode; - debug('RESPONSE: $httpStatusCode\n${response.body}\n'); - Map responseJson = json.decode(response.body) as Map; if (httpStatusCode == HttpStatus.ok) { @@ -91,10 +84,7 @@ class CollectionReference extends CarpReference { /// Get the documents in this collection. Future> get documents async { - final restHeaders = headers; - - final response = - await httpr.get(Uri.encodeFull(collectionUri), headers: restHeaders); + final response = await service._get(collectionUri); int httpStatusCode = response.statusCode; final responseJson = json.decode(response.body) as Map; @@ -107,7 +97,6 @@ class CollectionReference extends CarpReference { documents.add(DocumentSnapshot._('$path/$key', documentJson)); } } - return documents; } @@ -150,8 +139,10 @@ class CollectionReference extends CarpReference { /// Rename this collection. Future rename(String newName) async { // PUT the new name of this collection to the CARP web service - final response = await httpr.put(Uri.encodeFull(collectionUriByID), - headers: headers, body: '{"name":"$newName"}'); + final response = await service._put( + collectionUriByID, + body: '{"name":"$newName"}', + ); int httpStatusCode = response.statusCode; Map responseJson = json.decode(response.body) as Map; @@ -172,8 +163,7 @@ class CollectionReference extends CarpReference { /// Deletes the collection referred to by this [CollectionReference]. Future delete() async { - final response = - await httpr.delete(Uri.encodeFull(collectionUriByID), headers: headers); + final response = await service._delete(collectionUriByID); int httpStatusCode = response.statusCode; if (httpStatusCode == HttpStatus.ok) { diff --git a/backends/carp_webservices/lib/carp_services/data_point_reference.dart b/backends/carp_webservices/lib/carp_services/data_point_reference.dart index 5a08ce86..c4281fa8 100644 --- a/backends/carp_webservices/lib/carp_services/data_point_reference.dart +++ b/backends/carp_webservices/lib/carp_services/data_point_reference.dart @@ -25,11 +25,8 @@ class DataPointReference extends CarpReference { /// /// Returns the server-generated ID for this data point. Future post(DataPoint data) async { - final String url = dataEndpointUri; - - // POST the data point to the CARP web service - http.Response response = await httpr.post(Uri.encodeFull(url), - headers: headers, body: json.encode(data)); + final response = + await service._post(dataEndpointUri, body: json.encode(data)); int httpStatusCode = response.statusCode; Map responseJson = @@ -80,7 +77,7 @@ class DataPointReference extends CarpReference { /// Batch upload a list of [DataPoint]s. /// - /// Returns when successful. Throws an [CarpServiceException] if not. + /// Returns when successful. Throws a [CarpServiceException] if not. Future batch(List batch) async { if (batch.isEmpty) return; @@ -96,7 +93,7 @@ class DataPointReference extends CarpReference { /// The [file] can be created using a [FileDataManager] in `carp_mobile_sensing`. /// Note that the file should be raw JSON, and hence _not_ zipped. /// - /// Returns when successful. Throws an [CarpServiceException] if not. + /// Returns when successful. Throws a [CarpServiceException] if not. Future upload(File file) async { final String url = "$dataEndpointUri/batch"; @@ -130,11 +127,8 @@ class DataPointReference extends CarpReference { /// Get a [DataPoint] based on its [id] from the CARP backend. Future get(int id) async { - String url = "$dataEndpointUri/$id"; - - // GET the data point from the CARP web service - http.Response response = - await httpr.get(Uri.encodeFull(url), headers: headers); + final url = "$dataEndpointUri/$id"; + final response = await service._get(url); int httpStatusCode = response.statusCode; Map responseJson = @@ -244,7 +238,7 @@ class DataPointReference extends CarpReference { // GET the data points from the CARP web service // TODO - for some reason the CARP web service don't like encoded url's.... // http.Response response = await httpr.get(Uri.encodeFull(url), headers: restHeaders); - http.Response response = await httpr.get(url, headers: headers); + final response = await service._get(url); int httpStatusCode = response.statusCode; @@ -297,10 +291,9 @@ class DataPointReference extends CarpReference { /// Returns on success. Throws a [CarpServiceException] if data point is not /// found or otherwise unsuccessful. Future delete(int id) async { - String url = "$dataEndpointUri/$id"; + final url = "$dataEndpointUri/$id"; - http.Response response = - await httpr.delete(Uri.encodeFull(url), headers: headers); + final response = await service._delete(url); final int httpStatusCode = response.statusCode; if (httpStatusCode == HttpStatus.ok) return; diff --git a/backends/carp_webservices/lib/carp_services/document_reference.dart b/backends/carp_webservices/lib/carp_services/document_reference.dart index f4695fe5..e6a6c9ee 100644 --- a/backends/carp_webservices/lib/carp_services/document_reference.dart +++ b/backends/carp_webservices/lib/carp_services/document_reference.dart @@ -34,16 +34,16 @@ class DocumentReference extends CarpReference { /// The path to this document String get path => _path; - /// The full CARP web service path to this document. + /// The full CARP Web Service (CAWS) path to this document. /// /// If the id of this document is known, use the `documents` CARP endpoint, /// otherwise use the `collections` endpoint. - String get carpPath => (_id != null) + String get cawsPath => (_id != null) ? "/api/studies/${service.app!.studyId}/documents/$id" : "/api/studies/${service.app!.studyId}/collections/$path"; /// The full URI for the document endpoint for this document. - String get documentUri => "${service.app!.uri.toString()}$carpPath"; + String get documentUri => "${service.app!.uri.toString()}$cawsPath"; /// Writes to the document referred to by this [DocumentReference]. /// @@ -55,8 +55,10 @@ class DocumentReference extends CarpReference { // If this document does not already exist on the server (i.e., have an ID), then create it if (id == null) { - http.Response response = await httpr.post(Uri.encodeFull(documentUri), - headers: headers, body: json.encode(data)); + final response = await service._post( + documentUri, + body: json.encode(data), + ); int httpStatusCode = response.statusCode; Map responseJson = json.decode(response.body) as Map; @@ -91,13 +93,12 @@ class DocumentReference extends CarpReference { Map payload = {'name': name, 'data': data}; - debug('REQUEST: PUT $documentUri\n$payload'); - - http.Response response = await httpr.put(Uri.encodeFull(documentUri), - headers: headers, body: json.encode(payload)); + final response = await service._put( + documentUri, + body: json.encode(payload), + ); int httpStatusCode = response.statusCode; - debug('RESPONSE: $httpStatusCode\n${response.body}'); Map responseJson = json.decode(response.body) as Map; @@ -131,9 +132,8 @@ class DocumentReference extends CarpReference { } Map payload = {'name': name}; - http.Response response = await httpr.put( + final response = await service._put( Uri.encodeFull(documentUri), - headers: headers, body: json.encode(payload), ); @@ -156,15 +156,9 @@ class DocumentReference extends CarpReference { /// /// If no document exists, the read will return `null`. Future get() async { - debug('REQUEST: GET $documentUri\n'); - - http.Response response = - await httpr.get(Uri.encodeFull(documentUri), headers: headers); - + final response = await service._get(documentUri); int httpStatusCode = response.statusCode; - debug('RESPONSE: $httpStatusCode\n${response.body}'); - if (httpStatusCode == HttpStatus.ok) { Map jsonResponse = json.decode(response.body) as Map; @@ -181,10 +175,9 @@ class DocumentReference extends CarpReference { if (id == null) _id = (await get())?.id; if (_id == null) return; // early out if this document does not exist - http.Response response = await http - .delete(Uri.parse(Uri.encodeFull(documentUri)), headers: headers); - + final response = await service._delete(documentUri); int httpStatusCode = response.statusCode; + if (httpStatusCode == HttpStatus.ok) { return; } else { @@ -286,7 +279,9 @@ class DocumentSnapshot { } /// Contains all the data of this snapshot - Map get data => _snapshot['data'] as Map; + Map get data => _snapshot['data'] != null + ? _snapshot['data'] as Map + : {}; /// Reads individual data values from the snapshot dynamic operator [](String key) => data[key]; diff --git a/backends/carp_webservices/lib/carp_services/file_reference.dart b/backends/carp_webservices/lib/carp_services/file_reference.dart index 99a8dce5..d837dfd8 100644 --- a/backends/carp_webservices/lib/carp_services/file_reference.dart +++ b/backends/carp_webservices/lib/carp_services/file_reference.dart @@ -49,14 +49,11 @@ class FileStorageReference extends CarpReference { assert(id > 0); final String url = "$fileEndpointUri/$id"; - http.Response response = - await httpr.get(Uri.encodeFull(url), headers: headers); + final response = await service._get(url); int httpStatusCode = response.statusCode; Map map = json.decode(response.body) as Map; - print(response.body); - switch (httpStatusCode) { case HttpStatus.ok: { @@ -79,8 +76,7 @@ class FileStorageReference extends CarpReference { assert(id > 0); final String url = "$fileEndpointUri/$id"; - http.Response response = - await httpr.delete(Uri.encodeFull(url), headers: headers); + final response = await service._delete(url); int httpStatusCode = response.statusCode; switch (httpStatusCode) { diff --git a/backends/carp_webservices/lib/carp_services/http_retry.dart b/backends/carp_webservices/lib/carp_services/http_retry.dart index c79fe745..ad1c9400 100644 --- a/backends/carp_webservices/lib/carp_services/http_retry.dart +++ b/backends/carp_webservices/lib/carp_services/http_retry.dart @@ -83,7 +83,7 @@ class HTTPRetry { maxAttempts: 15, retryIf: (e) => e is SocketException || e is TimeoutException, onRetry: (e) { - print('${e.runtimeType} - Retrying to SEND ${request.url}'); + debugPrint('${e.runtimeType} - Retrying to SEND ${request.url}'); // when retrying sending form data, the request needs to be cloned // see e.g. >> https://github.com/flutterchina/dio/issues/482 @@ -101,31 +101,19 @@ class HTTPRetry { } /// Sends an HTTP GET request with the given [headers] to the given [url]. - Future get(String url, {Map? headers}) async { - final response = await retry( - () => client - .get( - Uri.parse(Uri.encodeFull(url)), - headers: headers, - ) - .timeout(const Duration(seconds: 20)), - delayFactor: const Duration(seconds: 5), - maxAttempts: 15, - retryIf: (e) => e is SocketException || e is TimeoutException, - onRetry: (e) => print('${e.runtimeType} - Retrying to GET $url'), - ); - - // Check if we are accessing a newly created resource and refresh token once - // if we get a 403 forbidden response. - // - // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 - if (response.statusCode == HttpStatus.forbidden) { - await CarpAuthService().refresh(); - return get(url, headers: headers); - } - - return clean(response); - } + Future get(String url, {Map? headers}) async => + await retry( + () => client + .get( + Uri.parse(Uri.encodeFull(url)), + headers: headers, + ) + .timeout(const Duration(seconds: 20)), + delayFactor: const Duration(seconds: 5), + maxAttempts: 15, + retryIf: (e) => e is SocketException || e is TimeoutException, + onRetry: (e) => debugPrint('${e.runtimeType} - Retrying to GET $url'), + ); /// Sends an HTTP POST request with the given [headers] and [body] to the given [url]. Future post( @@ -133,34 +121,21 @@ class HTTPRetry { Map? headers, Object? body, Encoding? encoding, - }) async { - // calling the http POST method using the retry approach - final response = await retry( - () => client - .post( - Uri.parse(Uri.encodeFull(url)), - headers: headers, - body: body, - encoding: encoding, - ) - .timeout(const Duration(seconds: 20)), - delayFactor: const Duration(seconds: 5), - maxAttempts: 15, - retryIf: (e) => e is SocketException || e is TimeoutException, - onRetry: (e) => print('${e.runtimeType} - Retrying to POST $url'), - ); - - // Check if we are accessing a newly created resource and refresh token once - // if we get a 403 forbidden response. - // - // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 - if (response.statusCode == HttpStatus.forbidden) { - await CarpAuthService().refresh(); - return post(url, headers: headers, body: body, encoding: encoding); - } - - return clean(response); - } + }) async => + await retry( + () => client + .post( + Uri.parse(Uri.encodeFull(url)), + headers: headers, + body: body, + encoding: encoding, + ) + .timeout(const Duration(seconds: 20)), + delayFactor: const Duration(seconds: 5), + maxAttempts: 15, + retryIf: (e) => e is SocketException || e is TimeoutException, + onRetry: (e) => debugPrint('${e.runtimeType} - Retrying to POST $url'), + ); /// Sends an HTTP PUT request with the given [headers] and [body] to the given [url]. Future put( @@ -168,84 +143,38 @@ class HTTPRetry { Map? headers, Object? body, Encoding? encoding, - }) async { - // calling the http PUT method using the retry approach - final response = await retry( - () => client - .put( - Uri.parse(Uri.encodeFull(url)), - headers: headers, - body: body, - encoding: encoding, - ) - .timeout(const Duration(seconds: 20)), - delayFactor: const Duration(seconds: 5), - maxAttempts: 15, - retryIf: (e) => e is SocketException || e is TimeoutException, - onRetry: (e) => print('${e.runtimeType} - Retrying to PUT $url'), - ); - - // Check if we are accessing a newly created resource and refresh token once - // if we get a 403 forbidden response. - // - // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 - if (response.statusCode == HttpStatus.forbidden) { - await CarpAuthService().refresh(); - return put(url, headers: headers, body: body, encoding: encoding); - } - - return clean(response); - } + }) async => + await retry( + () => client + .put( + Uri.parse(Uri.encodeFull(url)), + headers: headers, + body: body, + encoding: encoding, + ) + .timeout(const Duration(seconds: 20)), + delayFactor: const Duration(seconds: 5), + maxAttempts: 15, + retryIf: (e) => e is SocketException || e is TimeoutException, + onRetry: (e) => debugPrint('${e.runtimeType} - Retrying to PUT $url'), + ); /// Sends an HTTP DELETE request with the given [headers] to the given [url]. Future delete( String url, { Map? headers, - }) async { - // calling the http DELETE method using the retry approach - final response = await retry( - () => client - .delete( - Uri.parse(Uri.encodeFull(url)), - headers: headers, - ) - .timeout(const Duration(seconds: 15)), - delayFactor: const Duration(seconds: 5), - maxAttempts: 15, - retryIf: (e) => e is SocketException || e is TimeoutException, - onRetry: (e) => print('${e.runtimeType} - Retrying to DELETE $url'), - ); - - // Check if we are accessing a newly created resource and refresh token once - // if we get a 403 forbidden response. - // - // See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/392 - if (response.statusCode == HttpStatus.forbidden) { - await CarpAuthService().refresh(); - return put(url, headers: headers); - } - - return clean(response); - } - - /// Check if we get an Nginx reverse proxy error in HTML format, and if so - /// convert it to a JSON error message. - /// - /// See issue : https://github.com/cph-cachet/carp.sensing-flutter/issues/369 - http.Response clean(http.Response response) => - response.body.startsWith('') - ? http.Response( - '{' - '"statusCode": 502,' - '"message": "502 Bad Gateway.",' - '"path": "POST ${response.request?.url}"' - '}', - response.statusCode, - headers: response.headers, - isRedirect: response.isRedirect, - persistentConnection: response.persistentConnection, - reasonPhrase: response.reasonPhrase, - request: response.request, + }) async => + await retry( + () => client + .delete( + Uri.parse(Uri.encodeFull(url)), + headers: headers, ) - : response; + .timeout(const Duration(seconds: 15)), + delayFactor: const Duration(seconds: 5), + maxAttempts: 15, + retryIf: (e) => e is SocketException || e is TimeoutException, + onRetry: (e) => + debugPrint('${e.runtimeType} - Retrying to DELETE $url'), + ); } diff --git a/backends/carp_webservices/test/carp_data_stream_service_test.dart b/backends/carp_webservices/test/carp_data_stream_service_test.dart index 972d7fc6..5bc11486 100644 --- a/backends/carp_webservices/test/carp_data_stream_service_test.dart +++ b/backends/carp_webservices/test/carp_data_stream_service_test.dart @@ -36,8 +36,8 @@ void main() { group("Base services", () { test('- authentication', () async { - print('CarpService : ${CarpService().app}'); - print(" - signed in as: $user"); + debugPrint('CarpService : ${CarpService().app}'); + debugPrint(" - signed in as: $user"); }, skip: false); }); @@ -83,7 +83,7 @@ void main() { triggerIds: {0}), ]; - print(toJsonString(batch)); + debugPrint(toJsonString(batch)); await CarpDataStreamService() .appendToDataStreams(testDeploymentId, batch); @@ -93,7 +93,7 @@ void main() { test( '- append - measurements UNKNOWN to carp-core.kotlin', () async { - print('Start uploading...'); + debugPrint('Start uploading...'); var m1 = Measurement( sensorStartTime: 1642505045000000, @@ -131,7 +131,7 @@ void main() { DataStreamId( studyDeploymentId: testDeploymentId, deviceRoleName: phoneRoleName, - dataType: Geolocation.dataType, + dataType: BatteryState.dataType, ), 0, 100, @@ -141,6 +141,7 @@ void main() { }, ); + // Some test data List geoLocationBatch = [ DataStreamBatch( dataStream: DataStreamId( @@ -186,14 +187,14 @@ void main() { var list = await getGeoLocationBatches(); print('N = ${list.length}'); - print('Uploading another batch of Geolocation measurements...'); - await CarpDataStreamService() - .appendToDataStreams(testDeploymentId, geoLocationBatch); + // print('Uploading another batch of Geolocation measurements...'); + // await CarpDataStreamService() + // .appendToDataStreams(testDeploymentId, geoLocationBatch); - var list2 = await getGeoLocationBatches(); - print('N = ${list2.length}'); + // var list2 = await getGeoLocationBatches(); + // print('N = ${list2.length}'); - expect(list2.length, list.length + 1); + // expect(list2.length, list.length + 1); }, ); }); diff --git a/backends/carp_webservices/test/carp_service_test.dart b/backends/carp_webservices/test/carp_service_test.dart index 10a25f2c..7303e05d 100644 --- a/backends/carp_webservices/test/carp_service_test.dart +++ b/backends/carp_webservices/test/carp_service_test.dart @@ -124,13 +124,15 @@ void main() { }); test('- get', () async { - ConsentDocument uploaded = await CarpService().createConsentDocument( - {"text": "The original terms text.", "signature": "Image Blob"}); + // ConsentDocument uploaded = await CarpService().createConsentDocument( + // {"text": "The original terms text.", "signature": "Image Blob"}); - expect(uploaded.id, isNotNull); + // print(uploaded); + // expect(uploaded.id, isNotNull); ConsentDocument downloaded = - await CarpService().getConsentDocument(uploaded.id); + await CarpService().getConsentDocument(1); + // await CarpService().getConsentDocument(uploaded.id); print(downloaded); print('id : ${downloaded.id}'); @@ -180,6 +182,9 @@ void main() { }); test('- batch', () async { + final before = await CarpService().getDataPointReference().getAll(); + print('N_before = ${before.length}'); + List batch = []; batch.addAll([ DataPoint.fromData(lightData), @@ -196,14 +201,13 @@ void main() { await reference.batch(batch); // wait for the batch requests to finish - await Future.delayed(const Duration(seconds: 2), () {}); + await Future.delayed(const Duration(seconds: 5), () {}); - List data = - await CarpService().getDataPointReference().getAll(); - print('N=${data.length}'); + final after = await CarpService().getDataPointReference().getAll(); + print('N_after = ${after.length}'); // data.forEach((datapoint) => print(_encode((datapoint.toJson())))); - assert(data.length >= 5); + assert(after.length > before.length); }); test('- upload', () async { @@ -227,6 +231,9 @@ void main() { test('- query for test data points', () async { String query = 'carp_header.data_format.namespace==test'; + // String query = + // 'carp_header.data_format.name==${lightData.format.name}'; + print("query : $query"); List data = await CarpService().getDataPointReference().query(query); @@ -287,7 +294,7 @@ void main() { List data = await CarpService().getDataPointReference().getAll(); - //data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + data.forEach((datapoint) => print(_encode((datapoint.toJson())))); expect(data, isNotNull); print('N=${data.length}'); }, @@ -309,7 +316,8 @@ void main() { // String query = // 'carp_header.user_id==$userId;carp_body.timestamp>2019-11-02T12:53:40.219598Z'; //String query = 'carp_header.data_format.namespace==test'; - String query = 'carp_header.data_format.name==light'; + String query = + 'carp_header.data_format.name==${lightData.format.name}'; // String query = 'carp_header.user_id==$userId'; //String query = 'carp_body.timestamp>2019-11-02T12:53:40.219598Z'; //String query = 'carp_header.data_format.namespace=in=(carp,omh)'; @@ -368,8 +376,17 @@ void main() { skip: false, ); - group("Documents & Collections", () { - test(' - delete document by path', () async { + /// In order to run the test in this group you need to be authenticated + /// as a participant. + group("Documents & Collections - PARTICIPANT", () { + test(' - clean up old test documents', () async { + await CarpService() + .collection(collectionName) + .document(userId) + .collection('activities') + .document('cooking') + .delete(); + await CarpService() .collection(collectionName) .document(userId) @@ -505,87 +522,37 @@ void main() { // assert(serverDocument.data.length == document.data.length); // }, skip: true); - // NOTE :: In order to run the following two tests (query) you need to be - // authenticated as a researcher (and not as a participant). - test(' - get documents by query', () async { - var document = await CarpService() - .collection(collectionName) - .document(userId) - .setData({'email': userId, 'role': 'Administrator'}); - - expect(document, isNotNull); - - String query = 'name==$userId'; - List documents = - await CarpService().documentsByQuery(query); - - print("Found ${documents.length} document(s) for user '$userId'"); - for (var document in documents) { - print(' - $document'); - } - - expect(documents.length, greaterThan(0)); - }); - - test(' - get all documents', () async { - List documents = await CarpService().documents(); - - print('Found ${documents.length} document(s)'); - for (var document in documents) { - print(' - $document'); - } - expect(documents.length, greaterThan(0)); - }); - - test(' - add document in nested collections', () async { + test(' - add & get document in nested collections', () async { // is not providing an document id, so this should create a new document // if the collection don't exist, it is created (according to David). - DocumentSnapshot newDocument = await CarpService() + DocumentSnapshot doc1 = await CarpService() .collection(collectionName) .document(userId) .collection('activities') .document('cooking') .setData({'what': 'breakfast', 'time': 'morning'}); - print(newDocument); - expect(newDocument.id, greaterThan(0)); - expect(newDocument.path, - equals('$collectionName/$userId/activities/cooking')); - - // delete document again - await CarpService() - .collection(collectionName) - .document(userId) - .delete(); - }); - - test(' - get nested document', () async { - var document = await CarpService() - .collection(collectionName) - .document(userId) - .setData({'email': userId, 'role': 'Administrator'}); - - expect(document, isNotNull); + print(doc1); + expect(doc1.id, greaterThan(0)); + expect( + doc1.path, equals('$collectionName/$userId/activities/cooking')); - DocumentSnapshot? newDocument = await CarpService() + DocumentSnapshot? doc2 = await CarpService() .collection(collectionName) .document(userId) .collection('activities') .document('cooking') .get(); - // expect(newDocument?.id, greaterThan(0)); - - print(newDocument); - print(newDocument?.snapshot); - print(newDocument?.createdAt); - print(newDocument?.data); - // print(newDocument['what']); + expect(doc2, isNotNull); + expect(doc2?.id, doc1.id); // delete document again await CarpService() .collection(collectionName) .document(userId) + .collection('activities') + .document('cooking') .delete(); }); @@ -604,14 +571,21 @@ void main() { }); test(" - get a collection from path name", () async { + await CarpService() + .collection(collectionName) + .document(userId) + .setData({'email': userId, 'role': 'Administrator'}); + CollectionReference collection = await CarpService().collection(collectionName).get(); - print(collection); + expect(collection.path, collectionName); }); test(" - list documents in a collection", () async { List documents = await CarpService().collection(collectionName).documents; + + print('N = ${documents.length}'); for (var doc in documents) { print(doc); } @@ -675,9 +649,41 @@ void main() { .document(document.name) .delete(); }); + }, skip: false); + + /// In order to run the test in this group you need to be authenticated + /// as a researcher. + group("Documents & Collections - RESEARCHER", () { + test(' - get documents by query', () async { + var document = await CarpService() + .collection(collectionName) + .document(userId) + .setData({'email': userId, 'role': 'Administrator'}); + + expect(document, isNotNull); + + String query = 'name==$userId'; + List documents = + await CarpService().documentsByQuery(query); + + print("Found ${documents.length} document(s) for user '$userId'"); + for (var document in documents) { + print(' - $document'); + } + + expect(documents.length, greaterThan(0)); + }); + + test(' - get all documents', () async { + List documents = await CarpService().documents(); + + print('Found ${documents.length} document(s)'); + for (var document in documents) { + print(' - $document'); + } + expect(documents.length, greaterThan(0)); + }); - // NOTE :: In order to run the following two tests (rename & delete) - // you need to be authenticated as a researcher. test(' - rename collection', () async { CollectionReference collection = await CarpService().collection(collectionName).get(); @@ -692,10 +698,12 @@ void main() { test(' - delete collection', () async { CollectionReference collection = - await CarpService().collection(newCollectionName).get(); + await CarpService().collection(collectionName).get(); + await collection.delete(); expect(collection.id, -1); print(collection); + try { collection = await CarpService().collection(newCollectionName).get(); @@ -707,42 +715,7 @@ void main() { }); }, skip: false); - group("iPDM-GO", () { - test(" - get 'patients' collection from path", () async { - CollectionReference collection = - await CarpService().collection('patients').get(); - expect(collection.id!, greaterThan(0)); - print(collection); - }); - - test(" - list all nested documents in 'patients' collection", () async { - List documents = - await CarpService().collection('patients').documents; - for (var doc in documents) { - print(doc); - for (var col in doc.collections) { - print(col); - } - } - }); - test( - " - list all nested documents in 'patients/s174238@student.dtu.dk/chapters' collection", - () async { - List documents = await CarpService() - .collection('patients/s174238@student.dtu.dk/chapters') - .documents; - for (var doc in documents) { - print(doc); - for (var col in doc.collections) { - print(col); - } - } - }); - }, skip: true); - group("Files", () { - // int id = -1; - test('- upload', () async { final File myFile = File("test/img.jpg"); diff --git a/backends/carp_webservices/test/json/batch_2.json b/backends/carp_webservices/test/json/batch_2.json index 48fed598..9dae1dc3 100644 --- a/backends/carp_webservices/test/json/batch_2.json +++ b/backends/carp_webservices/test/json/batch_2.json @@ -1,281 +1,2693 @@ [ -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.012504Z","data_format":{"namespace":"test","name":"device"}},"body":{"id":"e5827520-3d8c-11eb-9c5f-b9727a7bb39f","timestamp":"2020-12-13T21:48:12.012504Z","platform":"Android","device_id":"QP1A.190711.020","hardware":"exynos9820","device_name":"beyond0","device_manufacturer":"samsung","device_model":"SM-G970F","operating_system":"REL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.084662Z","data_format":{"namespace":"test","name":"pedometer"}},"body":{"id":"e58cae50-3d8c-11eb-862e-33201a3f785f","timestamp":"2020-12-13T21:48:12.084662Z","step_count":0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.142111Z","data_format":{"namespace":"test","name":"battery"}},"body":{"id":"e59560e0-3d8c-11eb-8d00-fd47e60237a8","timestamp":"2020-12-13T21:48:12.142111Z","battery_level":100,"battery_status":"full"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.178226Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"e59adf20-3d8c-11eb-a81a-d7f10d6f9622","timestamp":"2020-12-13T21:48:12.178226Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.225741Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"e5a23220-3d8c-11eb-9d4e-a96364848492","timestamp":"2020-12-13T21:48:12.225741Z","time":"2020-12-13T21:48:12.210Z","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.376648Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"e5b91580-3d8c-11eb-b03d-c9529d231e90","timestamp":"2020-12-13T21:48:12.376648Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.379782Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"e5b9b1c0-3d8c-11eb-b6d2-5dfb76d768ac","timestamp":"2020-12-13T21:48:12.379782Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.382835Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"e5ba4e00-3d8c-11eb-8fb7-77563fc74837","timestamp":"2020-12-13T21:48:12.382835Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.484619Z","data_format":{"namespace":"test","name":"weather"}},"body":{"id":"e5c99040-3d8c-11eb-b3b9-7343e2749bf3","timestamp":"2020-12-13T21:48:12.484619Z","country":"DK","area_name":"Virum","weather_main":"Clouds","weather_description":"scattered clouds","date":"2020-12-13T22:48:12.000","sunrise":"2020-12-13T08:32:35.000","sunset":"2020-12-13T15:36:41.000","latitude":55.79,"longitude":12.45,"pressure":1013.0,"wind_speed":0.89,"wind_degree":105.0,"humidity":86.0,"cloudiness":29.0,"rain_last_hour":0.0,"rain_last3_hours":0.0,"snow_last_hour":0.0,"snow_last3_hours":0.0,"temperature":4.830000000000041,"temp_min":4.439999999999998,"temp_max":5.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.622245Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"e5de9ee0-3d8c-11eb-9b42-ffd13ddf3868","timestamp":"2020-12-13T21:48:12.622245Z","time":"2020-12-13T22:48:12.129","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:12.646145Z","data_format":{"namespace":"test","name":"battery"}},"body":{"id":"e5e24860-3d8c-11eb-883b-191890b08ff0","timestamp":"2020-12-13T21:48:12.646145Z","battery_level":100,"battery_status":"full"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:13.688509Z","data_format":{"namespace":"test","name":"air_quality"}},"body":{"id":"e6814780-3d8c-11eb-9727-45f093ababc3","timestamp":"2020-12-13T21:48:13.688509Z","air_quality_index":10,"source":"The Department of Environmental Science at Aarhus University","place":"H.C. Ørsted Institutet, Copenhagen, Denmark","latitude":55.7007621,"longitude":12.5613124,"air_quality_level":"GOOD"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:22.822578Z","data_format":{"namespace":"test","name":"battery"}},"body":{"id":"ebf30460-3d8c-11eb-9d97-932bd6af8d63","timestamp":"2020-12-13T21:48:22.822578Z","battery_level":100,"battery_status":"full"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:24.097434Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"ecb59110-3d8c-11eb-8781-11dd1fbb293a","timestamp":"2020-12-13T21:48:24.097434Z","mean_lux":11.5,"std_lux":0.5,"min_lux":11,"max_lux":12}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:34.025069Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f2a07590-3d8c-11eb-831e-25d6ad87ccc7","timestamp":"2020-12-13T21:48:34.025069Z","mean_lux":13.0,"std_lux":0.7071067811865476,"min_lux":12,"max_lux":14}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:44.021225Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f895ba50-3d8c-11eb-b3dd-f3b750bdd810","timestamp":"2020-12-13T21:48:44.021225Z","mean_lux":10.666666666666666,"std_lux":0.4714045207910317,"min_lux":10,"max_lux":11}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:47.272532Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"fa85ca80-3d8c-11eb-a4d6-319dbd59ded1","timestamp":"2020-12-13T21:48:47.272532Z","time":"2020-12-13T22:48:47.231","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:48:54.025946Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"fe8c5ea0-3d8c-11eb-a94b-398e1d0230d5","timestamp":"2020-12-13T21:48:54.025946Z","mean_lux":65.5,"std_lux":0.5,"min_lux":65,"max_lux":66}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:04.027098Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"048266b0-3d8d-11eb-88d2-bd718db1785a","timestamp":"2020-12-13T21:49:04.027098Z","mean_lux":90.57142857142857,"std_lux":0.9035079029052513,"min_lux":89,"max_lux":92}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:12.029027Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"094768d0-3d8d-11eb-ba0d-af9b787947a9","timestamp":"2020-12-13T21:49:12.029027Z","free_physical_memory":697745408,"free_virtual_memory":2510422016}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:14.024325Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"0a77d280-3d8d-11eb-bafd-e136d9e513dd","timestamp":"2020-12-13T21:49:14.024325Z","mean_lux":89.5,"std_lux":0.5,"min_lux":89,"max_lux":90}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:18.732835Z","data_format":{"namespace":"test","name":"battery"}},"body":{"id":"0d4634c0-3d8d-11eb-9b96-f9d3476f7e61","timestamp":"2020-12-13T21:49:18.732835Z","battery_level":100,"battery_status":"discharging"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:24.021791Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"106d6560-3d8d-11eb-aa6c-05efd750787d","timestamp":"2020-12-13T21:49:24.021791Z","mean_lux":73.14285714285714,"std_lux":37.42202778131225,"min_lux":5,"max_lux":100}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:34.027856Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"166430c0-3d8d-11eb-a5cc-25efeb98c7ea","timestamp":"2020-12-13T21:49:34.027856Z","mean_lux":99.66666666666667,"std_lux":0.4714045207910317,"min_lux":99,"max_lux":100}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:44.026311Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"1c59c3a0-3d8d-11eb-8344-d59202ed8140","timestamp":"2020-12-13T21:49:44.026311Z","mean_lux":99.66666666666667,"std_lux":0.4714045207910317,"min_lux":99,"max_lux":100}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:50.207056Z","data_format":{"namespace":"test","name":"screen"}},"body":{"id":"2008e8f0-3d8d-11eb-b282-f1e988191a90","timestamp":"2020-12-13T21:49:50.207056Z","screen_event":"SCREEN_OFF"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:49:54.026688Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"224fcbb0-3d8d-11eb-af2b-11bd9570aa6b","timestamp":"2020-12-13T21:49:54.026688Z","mean_lux":118.44444444444444,"std_lux":0.4969039949999533,"min_lux":118,"max_lux":119}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:04.026416Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"284585a0-3d8d-11eb-af8d-c3e802d965f9","timestamp":"2020-12-13T21:50:04.026416Z","mean_lux":116.33333333333333,"std_lux":0.596284793999944,"min_lux":115,"max_lux":117}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:12.014772Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"2d088bf0-3d8d-11eb-afa8-abaa05f8e936","timestamp":"2020-12-13T21:50:12.014772Z","free_physical_memory":553979904,"free_virtual_memory":2388783104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:14.022510Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"2e3af170-3d8d-11eb-8bee-a5a494fc3c96","timestamp":"2020-12-13T21:50:14.022510Z","mean_lux":117.52941176470588,"std_lux":0.4991341984846218,"min_lux":117,"max_lux":118}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:24.026853Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"34316eb0-3d8d-11eb-b62d-61c4802912d5","timestamp":"2020-12-13T21:50:24.026853Z","mean_lux":116.72727272727273,"std_lux":1.052348809344566,"min_lux":115,"max_lux":118}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:34.022331Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"3a268c60-3d8d-11eb-b7f1-1fc3553e45b8","timestamp":"2020-12-13T21:50:34.022331Z","mean_lux":103.54545454545455,"std_lux":0.49792959773196915,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:44.023780Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"401cbb80-3d8d-11eb-ab68-0df122a96c73","timestamp":"2020-12-13T21:50:44.023780Z","mean_lux":104.16666666666667,"std_lux":0.6871842709362769,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:50:54.028667Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"4613d500-3d8d-11eb-bea5-e7516d4b443c","timestamp":"2020-12-13T21:50:54.028667Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:04.031130Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"4c09b600-3d8d-11eb-b44c-ff156f65cbbd","timestamp":"2020-12-13T21:51:04.031130Z","mean_lux":104.6,"std_lux":0.4898979485566356,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:12.021959Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"50cce360-3d8d-11eb-ab78-21d2f4e9ae86","timestamp":"2020-12-13T21:51:12.021959Z","free_physical_memory":568209408,"free_virtual_memory":2402054144}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:14.029114Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"51ff21d0-3d8d-11eb-a151-33fced12efb3","timestamp":"2020-12-13T21:51:14.029114Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:24.026540Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"57f4b4b0-3d8d-11eb-9966-91bc573d9b70","timestamp":"2020-12-13T21:51:24.026540Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:34.027797Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"5deabcc0-3d8d-11eb-a111-8b6f763d41fa","timestamp":"2020-12-13T21:51:34.027797Z","mean_lux":104.4,"std_lux":0.4898979485566356,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:44.024998Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"63e02890-3d8d-11eb-bf6f-3f742af628f3","timestamp":"2020-12-13T21:51:44.024998Z","mean_lux":104.53333333333333,"std_lux":0.4988876515698588,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:51:54.029665Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"69d6cce0-3d8d-11eb-bb74-05771d49ee9c","timestamp":"2020-12-13T21:51:54.029665Z","mean_lux":104.33333333333333,"std_lux":0.4714045207910317,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:04.026245Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"6fcc11a0-3d8d-11eb-9a04-b965814930b5","timestamp":"2020-12-13T21:52:04.026245Z","mean_lux":104.46666666666667,"std_lux":0.4988876515698588,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:12.014269Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"748ef0e0-3d8d-11eb-adbe-27aeb147ae99","timestamp":"2020-12-13T21:52:12.014269Z","free_physical_memory":485261312,"free_virtual_memory":2320801792}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:14.019192Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"75c10840-3d8d-11eb-a186-b570310572ff","timestamp":"2020-12-13T21:52:14.019192Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:24.027888Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"7bb821c0-3d8d-11eb-8ade-3f651ec0474d","timestamp":"2020-12-13T21:52:24.027888Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:34.028506Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"81ae02c0-3d8d-11eb-984b-57835ebb147c","timestamp":"2020-12-13T21:52:34.028506Z","mean_lux":104.14285714285714,"std_lux":0.6388765649999399,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:44.027715Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"87a3e3c0-3d8d-11eb-820d-0728d4dee616","timestamp":"2020-12-13T21:52:44.027715Z","mean_lux":103.83333333333333,"std_lux":0.6871842709362769,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:52:54.024243Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"8d992880-3d8d-11eb-a07c-d372c4e022c2","timestamp":"2020-12-13T21:52:54.024243Z","mean_lux":101.36363636363636,"std_lux":2.185602778212965,"min_lux":99,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:04.029980Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"938ff3e0-3d8d-11eb-87b8-cf140f470590","timestamp":"2020-12-13T21:53:04.029980Z","mean_lux":105.83333333333333,"std_lux":0.6871842709362769,"min_lux":105,"max_lux":107}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.021797Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"98536f60-3d8d-11eb-8399-7b2181bfc54b","timestamp":"2020-12-13T21:53:12.021797Z","free_physical_memory":485474304,"free_virtual_memory":2322378752}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.259966Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"9877c040-3d8d-11eb-b857-d7f10c041956","timestamp":"2020-12-13T21:53:12.259966Z","time":"2020-12-13T21:53:12.247Z","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.374639Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"98894c70-3d8d-11eb-b637-b3dbcc458242","timestamp":"2020-12-13T21:53:12.374639Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.436869Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"9892c250-3d8d-11eb-a644-89cbfa6a4f3a","timestamp":"2020-12-13T21:53:12.436869Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.451145Z","data_format":{"namespace":"test","name":"weather"}},"body":{"id":"9894e530-3d8d-11eb-a081-43f2069e212d","timestamp":"2020-12-13T21:53:12.451145Z","country":"DK","area_name":"Virum","weather_main":"Clouds","weather_description":"scattered clouds","date":"2020-12-13T22:53:12.000","sunrise":"2020-12-13T08:32:35.000","sunset":"2020-12-13T15:36:41.000","latitude":55.79,"longitude":12.45,"pressure":1012.0,"wind_speed":2.39,"wind_degree":142.0,"humidity":90.0,"cloudiness":29.0,"rain_last_hour":0.0,"rain_last3_hours":0.0,"snow_last_hour":0.0,"snow_last3_hours":0.0,"temperature":4.830000000000041,"temp_min":4.439999999999998,"temp_max":5.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:12.463188Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"9896b9f0-3d8d-11eb-b070-a1681ea49ad0","timestamp":"2020-12-13T21:53:12.463188Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:14.026858Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"99855fb0-3d8d-11eb-b2d9-fb08fc8cb68e","timestamp":"2020-12-13T21:53:14.026858Z","mean_lux":105.5,"std_lux":0.5,"min_lux":105,"max_lux":106}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:14.724701Z","data_format":{"namespace":"test","name":"air_quality"}},"body":{"id":"99efe150-3d8d-11eb-a045-177b510f0446","timestamp":"2020-12-13T21:53:14.724701Z","air_quality_index":10,"source":"The Department of Environmental Science at Aarhus University","place":"H.C. Ørsted Institutet, Copenhagen, Denmark","latitude":55.7007621,"longitude":12.5613124,"air_quality_level":"GOOD"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:24.022086Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"9f7a7d60-3d8d-11eb-ba1e-5722f05093be","timestamp":"2020-12-13T21:53:24.022086Z","mean_lux":105.53333333333333,"std_lux":0.4988876515698588,"min_lux":105,"max_lux":106}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:34.029409Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"a5716fd0-3d8d-11eb-a78f-cf77b745b287","timestamp":"2020-12-13T21:53:34.029409Z","mean_lux":105.55555555555556,"std_lux":0.4969039949999533,"min_lux":105,"max_lux":106}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:44.028898Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"ab6750d0-3d8d-11eb-89c2-37e577c4f601","timestamp":"2020-12-13T21:53:44.028898Z","mean_lux":104.53846153846153,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:53:54.024378Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"b15c6e80-3d8d-11eb-82c4-b91267dd8beb","timestamp":"2020-12-13T21:53:54.024378Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:04.027805Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"b752ebc0-3d8d-11eb-a892-f5d934b6236c","timestamp":"2020-12-13T21:54:04.027805Z","mean_lux":104.0,"std_lux":0.7071067811865476,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:12.015650Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"bc15cb00-3d8d-11eb-900a-712de1ede559","timestamp":"2020-12-13T21:54:12.015650Z","free_physical_memory":479133696,"free_virtual_memory":2315419648}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:14.024263Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"bd483080-3d8d-11eb-8774-311fddd5cc41","timestamp":"2020-12-13T21:54:14.024263Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:24.024943Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"c33e3890-3d8d-11eb-9910-ab058f9a9cfd","timestamp":"2020-12-13T21:54:24.024943Z","mean_lux":104.46153846153847,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:34.025440Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"c9341990-3d8d-11eb-b51d-39fe673e76ec","timestamp":"2020-12-13T21:54:34.025440Z","mean_lux":103.42857142857143,"std_lux":0.4948716593053935,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:44.028545Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"cf2a6fc0-3d8d-11eb-9b25-af0e5252c620","timestamp":"2020-12-13T21:54:44.028545Z","mean_lux":103.53846153846153,"std_lux":0.4985185152621431,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:54:54.021912Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"d51f6660-3d8d-11eb-b2cc-1fa4092f3058","timestamp":"2020-12-13T21:54:54.021912Z","mean_lux":103.53846153846153,"std_lux":0.4985185152621431,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:04.024847Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"db15bc90-3d8d-11eb-9fa4-252073ead3aa","timestamp":"2020-12-13T21:55:04.024847Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:12.019725Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"dfd9ad40-3d8d-11eb-8168-4579d20b8f17","timestamp":"2020-12-13T21:55:12.019725Z","free_physical_memory":476667904,"free_virtual_memory":2313547776}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:14.029066Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"e10c39d0-3d8d-11eb-98e6-4baf04225a0b","timestamp":"2020-12-13T21:55:14.029066Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:24.025167Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"e7017e90-3d8d-11eb-a43a-c9a7d8e96edc","timestamp":"2020-12-13T21:55:24.025167Z","mean_lux":104.42857142857143,"std_lux":0.4948716593053935,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:34.029001Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"ecf7fbd0-3d8d-11eb-ba42-514e05ce859a","timestamp":"2020-12-13T21:55:34.029001Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:44.028430Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f2edb5c0-3d8d-11eb-b01d-ff061a934817","timestamp":"2020-12-13T21:55:44.028430Z","mean_lux":104.46153846153847,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:55:54.029738Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f8e3e4e0-3d8d-11eb-bc64-fddebfe3e182","timestamp":"2020-12-13T21:55:54.029738Z","mean_lux":104.46153846153847,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:04.025365Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"fed90290-3d8d-11eb-8094-cbb18f31c930","timestamp":"2020-12-13T21:56:04.025365Z","mean_lux":104.3076923076923,"std_lux":0.6056929133855239,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:12.016624Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"039c7e10-3d8e-11eb-af33-33ba748af5ec","timestamp":"2020-12-13T21:56:12.016624Z","free_physical_memory":482611200,"free_virtual_memory":2319937536}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:14.024481Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"04cebc80-3d8e-11eb-abd2-6394bbcfd179","timestamp":"2020-12-13T21:56:14.024481Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:23.300621Z","data_format":{"namespace":"test","name":"battery"}},"body":{"id":"0a562440-3d8e-11eb-87cc-fd10addb3a2c","timestamp":"2020-12-13T21:56:23.300621Z","battery_level":99,"battery_status":"discharging"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:24.028358Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"0ac539c0-3d8e-11eb-9af5-eb52da822e3e","timestamp":"2020-12-13T21:56:24.028358Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:34.026480Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"10bacca0-3d8e-11eb-a644-09a13d7e8870","timestamp":"2020-12-13T21:56:34.026480Z","mean_lux":104.45454545454545,"std_lux":0.49792959773196915,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:44.027617Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"16b0fbc0-3d8e-11eb-8278-b9335159970e","timestamp":"2020-12-13T21:56:44.027617Z","mean_lux":104.3,"std_lux":0.6403124237432848,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:56:54.029568Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"1ca703d0-3d8e-11eb-9bd1-f10e13cbd462","timestamp":"2020-12-13T21:56:54.029568Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:04.023342Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"229bfa70-3d8e-11eb-a402-15b37f1f617e","timestamp":"2020-12-13T21:57:04.023342Z","mean_lux":104.25,"std_lux":0.6614378277661477,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:12.020113Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"27603940-3d8e-11eb-8612-b5cec588215c","timestamp":"2020-12-13T21:57:12.020113Z","free_physical_memory":535998464,"free_virtual_memory":2372243456}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:14.027214Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"289277b0-3d8e-11eb-938f-75495810e502","timestamp":"2020-12-13T21:57:14.027214Z","mean_lux":103.5,"std_lux":0.5,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:24.027723Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"2e887fc0-3d8e-11eb-99e7-9f377a6fdb40","timestamp":"2020-12-13T21:57:24.027723Z","mean_lux":104.16666666666667,"std_lux":0.6871842709362769,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:34.026876Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"347e39b0-3d8e-11eb-8292-fd32bb64bccd","timestamp":"2020-12-13T21:57:34.026876Z","mean_lux":104.22222222222223,"std_lux":0.628539361054709,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:44.030068Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"3a74b6f0-3d8e-11eb-8118-e3d0fb692fe4","timestamp":"2020-12-13T21:57:44.030068Z","mean_lux":103.6923076923077,"std_lux":0.6056929133855239,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:57:54.025541Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"4069ad90-3d8e-11eb-a313-47e86e627abd","timestamp":"2020-12-13T21:57:54.025541Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:04.029232Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"46602ad0-3d8e-11eb-97d9-f50fb714f099","timestamp":"2020-12-13T21:58:04.029232Z","mean_lux":104.42857142857143,"std_lux":0.4948716593053935,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.014266Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"4b2294e0-3d8e-11eb-ace4-d1e686c9d74b","timestamp":"2020-12-13T21:58:12.014266Z","free_physical_memory":505942016,"free_virtual_memory":2347429888}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.247134Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"4b462270-3d8e-11eb-9e0c-6b78c952199b","timestamp":"2020-12-13T21:58:12.247134Z","time":"2020-12-13T21:58:12.241Z","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.358298Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"4b571260-3d8e-11eb-bdf5-6d020e31c01f","timestamp":"2020-12-13T21:58:12.358298Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.369453Z","data_format":{"namespace":"test","name":"weather"}},"body":{"id":"4b58c010-3d8e-11eb-8393-cff54a45872b","timestamp":"2020-12-13T21:58:12.369453Z","country":"DK","area_name":"Virum","weather_main":"Clouds","weather_description":"scattered clouds","date":"2020-12-13T22:53:12.000","sunrise":"2020-12-13T08:32:35.000","sunset":"2020-12-13T15:36:41.000","latitude":55.79,"longitude":12.45,"pressure":1012.0,"wind_speed":2.39,"wind_degree":142.0,"humidity":90.0,"cloudiness":29.0,"rain_last_hour":0.0,"rain_last3_hours":0.0,"snow_last_hour":0.0,"snow_last3_hours":0.0,"temperature":4.830000000000041,"temp_min":4.439999999999998,"temp_max":5.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.392120Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"4b5c4280-3d8e-11eb-8a82-9bd0c8a83866","timestamp":"2020-12-13T21:58:12.392120Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:12.425129Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"4b614b90-3d8e-11eb-9696-25ab132ed972","timestamp":"2020-12-13T21:58:12.425129Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:14.019023Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"4c548530-3d8e-11eb-92d5-d7b534fd9592","timestamp":"2020-12-13T21:58:14.019023Z","mean_lux":103.77777777777777,"std_lux":0.628539361054709,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:14.787356Z","data_format":{"namespace":"test","name":"air_quality"}},"body":{"id":"4cc9b530-3d8e-11eb-a196-c10d5421d156","timestamp":"2020-12-13T21:58:14.787356Z","air_quality_index":10,"source":"The Department of Environmental Science at Aarhus University","place":"H.C. Ørsted Institutet, Copenhagen, Denmark","latitude":55.7007621,"longitude":12.5613124,"air_quality_level":"GOOD"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:24.027254Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"524b9eb0-3d8e-11eb-a7b2-ad427e731593","timestamp":"2020-12-13T21:58:24.027254Z","mean_lux":104.42857142857143,"std_lux":0.4948716593053935,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:34.029411Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"5841cdd0-3d8e-11eb-ba74-6f8e829d2398","timestamp":"2020-12-13T21:58:34.029411Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:44.029137Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"5e37aed0-3d8e-11eb-a35e-e79c069bdbeb","timestamp":"2020-12-13T21:58:44.029137Z","mean_lux":104.33333333333333,"std_lux":0.4714045207910317,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:58:54.028396Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"642d8fd0-3d8e-11eb-896f-6b476006c43e","timestamp":"2020-12-13T21:58:54.028396Z","mean_lux":104.45454545454545,"std_lux":0.49792959773196915,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:04.027677Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"6a2349c0-3d8e-11eb-9667-331e99606c20","timestamp":"2020-12-13T21:59:04.027677Z","mean_lux":103.42857142857143,"std_lux":0.4948716593053935,"min_lux":103,"max_lux":104}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:12.021859Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"6ee71360-3d8e-11eb-897e-5f61962b4390","timestamp":"2020-12-13T21:59:12.021859Z","free_physical_memory":502018048,"free_virtual_memory":2343702528}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:14.027670Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"70192ac0-3d8e-11eb-8211-455c9aa6c12b","timestamp":"2020-12-13T21:59:14.027670Z","mean_lux":103.6923076923077,"std_lux":0.6056929133855239,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:24.026763Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"760ee4b0-3d8e-11eb-86b4-69bd1130e3fd","timestamp":"2020-12-13T21:59:24.026763Z","mean_lux":103.83333333333333,"std_lux":0.6871842709362769,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:34.029330Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"7c0513d0-3d8e-11eb-9975-8b7bee88416b","timestamp":"2020-12-13T21:59:34.029330Z","mean_lux":104.46153846153847,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:44.029616Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"81fb1be0-3d8e-11eb-b824-a9855d364d9f","timestamp":"2020-12-13T21:59:44.029616Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T21:59:54.027929Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"87f0aec0-3d8e-11eb-9ee1-1de9f854c311","timestamp":"2020-12-13T21:59:54.027929Z","mean_lux":104.42857142857143,"std_lux":0.4948716593053935,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:04.028325Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"8de68fc0-3d8e-11eb-ab11-e3e407a07152","timestamp":"2020-12-13T22:00:04.028325Z","mean_lux":104.25,"std_lux":0.6614378277661477,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:12.014625Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"92a947f0-3d8e-11eb-934e-37b3b490f2c1","timestamp":"2020-12-13T22:00:12.014625Z","free_physical_memory":498147328,"free_virtual_memory":2340532224}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:14.022880Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"93dbad70-3d8e-11eb-a13d-59f5c8713ef7","timestamp":"2020-12-13T22:00:14.022880Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:24.029505Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"99d29fe0-3d8e-11eb-930a-8155a2f23a10","timestamp":"2020-12-13T22:00:24.029505Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:34.028852Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"9fc859d0-3d8e-11eb-a6e7-cd071ce25790","timestamp":"2020-12-13T22:00:34.028852Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:44.021043Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"a5bd0250-3d8e-11eb-9ff3-53f034274e5c","timestamp":"2020-12-13T22:00:44.021043Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:00:54.025732Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"abb3a6a0-3d8e-11eb-a0bc-9f670e718bd0","timestamp":"2020-12-13T22:00:54.025732Z","mean_lux":104.46153846153847,"std_lux":0.4985185152621431,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:04.028934Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"b1a9fcd0-3d8e-11eb-ae0c-0198562aa9d6","timestamp":"2020-12-13T22:01:04.028934Z","mean_lux":104.16666666666667,"std_lux":0.6871842709362769,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:12.020715Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"b66d7850-3d8e-11eb-9719-df83214e58a0","timestamp":"2020-12-13T22:01:12.020715Z","free_physical_memory":488013824,"free_virtual_memory":2330046464}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:14.029707Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"b7a004e0-3d8e-11eb-a692-1534d2008de5","timestamp":"2020-12-13T22:01:14.029707Z","mean_lux":104.4,"std_lux":0.4898979485566356,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:24.028006Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"bd9597c0-3d8e-11eb-86ab-cb2ee764e91d","timestamp":"2020-12-13T22:01:24.028006Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:34.029126Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"c38b9fd0-3d8e-11eb-bedb-e598df60e75b","timestamp":"2020-12-13T22:01:34.029126Z","mean_lux":104.44444444444444,"std_lux":0.4969039949999533,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:44.021078Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"c9804850-3d8e-11eb-b143-ef5990863743","timestamp":"2020-12-13T22:01:44.021078Z","mean_lux":104.0,"std_lux":0.6324555320336759,"min_lux":103,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:01:54.025390Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"cf76c590-3d8e-11eb-89e2-53a3632dc620","timestamp":"2020-12-13T22:01:54.025390Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:04.018443Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"d56b9520-3d8e-11eb-be65-c5fd94186207","timestamp":"2020-12-13T22:02:04.018443Z","mean_lux":104.6,"std_lux":0.4898979485566356,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:12.014573Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"da2fd3f0-3d8e-11eb-b797-ef6073bf3d58","timestamp":"2020-12-13T22:02:12.014573Z","free_physical_memory":482865152,"free_virtual_memory":2325520384}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:14.021896Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"db621260-3d8e-11eb-bac7-df045232a867","timestamp":"2020-12-13T22:02:14.021896Z","mean_lux":104.42857142857143,"std_lux":0.4948716593053935,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:24.028912Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"e15904d0-3d8e-11eb-8726-5f51f9c3ed80","timestamp":"2020-12-13T22:02:24.028912Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:34.029191Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"e74ee5d0-3d8e-11eb-b0a8-9df563a41066","timestamp":"2020-12-13T22:02:34.029191Z","mean_lux":104.46666666666667,"std_lux":0.4988876515698588,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:44.028642Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"ed44c6d0-3d8e-11eb-a083-6b4c1a0c4db1","timestamp":"2020-12-13T22:02:44.028642Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:02:54.029584Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f33acee0-3d8e-11eb-9657-2de7b9943114","timestamp":"2020-12-13T22:02:54.029584Z","mean_lux":104.45454545454545,"std_lux":0.49792959773196915,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:04.027729Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"f93061c0-3d8e-11eb-9592-bd17d6460a1f","timestamp":"2020-12-13T22:03:04.027729Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.021060Z","data_format":{"namespace":"test","name":"memory"}},"body":{"id":"fdf40450-3d8e-11eb-a8a1-1befa095dfcb","timestamp":"2020-12-13T22:03:12.021060Z","free_physical_memory":499105792,"free_virtual_memory":2342580224}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.274211Z","data_format":{"namespace":"test","name":"location"}},"body":{"id":"fe1a9f20-3d8e-11eb-9e36-cb98ab60ee70","timestamp":"2020-12-13T22:03:12.274211Z","time":"2020-12-13T22:03:12.260Z","latitude":55.7943684,"longitude":12.4462731,"altitude":76.30000305175781,"accuracy":20.0,"speed":0.0,"speed_accuracy":0.0,"heading":0.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.362078Z","data_format":{"namespace":"test","name":"weather"}},"body":{"id":"fe280ca0-3d8e-11eb-aeae-55df0128232f","timestamp":"2020-12-13T22:03:12.362078Z","country":"DK","area_name":"Virum","weather_main":"Clouds","weather_description":"scattered clouds","date":"2020-12-13T22:53:12.000","sunrise":"2020-12-13T08:32:35.000","sunset":"2020-12-13T15:36:41.000","latitude":55.79,"longitude":12.45,"pressure":1012.0,"wind_speed":2.39,"wind_degree":142.0,"humidity":90.0,"cloudiness":29.0,"rain_last_hour":0.0,"rain_last3_hours":0.0,"snow_last_hour":0.0,"snow_last3_hours":0.0,"temperature":4.830000000000041,"temp_min":4.439999999999998,"temp_max":5.0}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.391342Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"fe2ca080-3d8e-11eb-9b27-8164b4e47cef","timestamp":"2020-12-13T22:03:12.391342Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.422089Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"fe313460-3d8e-11eb-b199-331296a58877","timestamp":"2020-12-13T22:03:12.422089Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:12.507743Z","data_format":{"namespace":"test","name":"activity"}},"body":{"id":"fe3e2cb0-3d8e-11eb-ae04-37150bb95525","timestamp":"2020-12-13T22:03:12.507743Z","confidence":100,"type":"STILL"}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:14.025597Z","data_format":{"namespace":"test","name":"light"}},"body":{"id":"ff25f4a0-3d8e-11eb-b9d1-a517a6ce18b8","timestamp":"2020-12-13T22:03:14.025597Z","mean_lux":104.5,"std_lux":0.5,"min_lux":104,"max_lux":105}} -, -{"header":{"study_id":"2","user_id":"72c04755-5189-4f8e-87be-19962cffe1b4","start_time":"2020-12-13T22:03:14.592919Z","data_format":{"namespace":"test","name":"air_quality"}},"body":{"id":"ff7c7910-3d8e-11eb-b727-6f118311cc18","timestamp":"2020-12-13T22:03:14.592919Z","air_quality_index":10,"source":"The Department of Environmental Science at Aarhus University","place":"H.C. Ørsted Institutet, Copenhagen, Denmark","latitude":55.7007621,"longitude":12.5613124,"air_quality_level":"GOOD"}} -] + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.012504Z", + "data_format": { + "namespace": "test", + "name": "device" + } + }, + "body": { + "id": "e5827520-3d8c-11eb-9c5f-b9727a7bb39f", + "timestamp": "2020-12-13T21:48:12.012504Z", + "platform": "Android", + "device_id": "QP1A.190711.020", + "hardware": "exynos9820", + "device_name": "beyond0", + "device_manufacturer": "samsung", + "device_model": "SM-G970F", + "operating_system": "REL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.084662Z", + "data_format": { + "namespace": "test", + "name": "pedometer" + } + }, + "body": { + "id": "e58cae50-3d8c-11eb-862e-33201a3f785f", + "timestamp": "2020-12-13T21:48:12.084662Z", + "step_count": 0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.142111Z", + "data_format": { + "namespace": "test", + "name": "battery" + } + }, + "body": { + "id": "e59560e0-3d8c-11eb-8d00-fd47e60237a8", + "timestamp": "2020-12-13T21:48:12.142111Z", + "battery_level": 100, + "battery_status": "full" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.178226Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "e59adf20-3d8c-11eb-a81a-d7f10d6f9622", + "timestamp": "2020-12-13T21:48:12.178226Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.225741Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "e5a23220-3d8c-11eb-9d4e-a96364848492", + "timestamp": "2020-12-13T21:48:12.225741Z", + "time": "2020-12-13T21:48:12.210Z", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.376648Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "e5b91580-3d8c-11eb-b03d-c9529d231e90", + "timestamp": "2020-12-13T21:48:12.376648Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.379782Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "e5b9b1c0-3d8c-11eb-b6d2-5dfb76d768ac", + "timestamp": "2020-12-13T21:48:12.379782Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.382835Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "e5ba4e00-3d8c-11eb-8fb7-77563fc74837", + "timestamp": "2020-12-13T21:48:12.382835Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.484619Z", + "data_format": { + "namespace": "test", + "name": "weather" + } + }, + "body": { + "id": "e5c99040-3d8c-11eb-b3b9-7343e2749bf3", + "timestamp": "2020-12-13T21:48:12.484619Z", + "country": "DK", + "area_name": "Virum", + "weather_main": "Clouds", + "weather_description": "scattered clouds", + "date": "2020-12-13T22:48:12.000", + "sunrise": "2020-12-13T08:32:35.000", + "sunset": "2020-12-13T15:36:41.000", + "latitude": 55.79, + "longitude": 12.45, + "pressure": 1013.0, + "wind_speed": 0.89, + "wind_degree": 105.0, + "humidity": 86.0, + "cloudiness": 29.0, + "rain_last_hour": 0.0, + "rain_last3_hours": 0.0, + "snow_last_hour": 0.0, + "snow_last3_hours": 0.0, + "temperature": 4.830000000000041, + "temp_min": 4.439999999999998, + "temp_max": 5.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.622245Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "e5de9ee0-3d8c-11eb-9b42-ffd13ddf3868", + "timestamp": "2020-12-13T21:48:12.622245Z", + "time": "2020-12-13T22:48:12.129", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:12.646145Z", + "data_format": { + "namespace": "test", + "name": "battery" + } + }, + "body": { + "id": "e5e24860-3d8c-11eb-883b-191890b08ff0", + "timestamp": "2020-12-13T21:48:12.646145Z", + "battery_level": 100, + "battery_status": "full" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:13.688509Z", + "data_format": { + "namespace": "test", + "name": "air_quality" + } + }, + "body": { + "id": "e6814780-3d8c-11eb-9727-45f093ababc3", + "timestamp": "2020-12-13T21:48:13.688509Z", + "air_quality_index": 10, + "source": "The Department of Environmental Science at Aarhus University", + "place": "H.C. Ørsted Institutet, Copenhagen, Denmark", + "latitude": 55.7007621, + "longitude": 12.5613124, + "air_quality_level": "GOOD" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:22.822578Z", + "data_format": { + "namespace": "test", + "name": "battery" + } + }, + "body": { + "id": "ebf30460-3d8c-11eb-9d97-932bd6af8d63", + "timestamp": "2020-12-13T21:48:22.822578Z", + "battery_level": 100, + "battery_status": "full" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:24.097434Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "ecb59110-3d8c-11eb-8781-11dd1fbb293a", + "timestamp": "2020-12-13T21:48:24.097434Z", + "mean_lux": 11.5, + "std_lux": 0.5, + "min_lux": 11, + "max_lux": 12 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:34.025069Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f2a07590-3d8c-11eb-831e-25d6ad87ccc7", + "timestamp": "2020-12-13T21:48:34.025069Z", + "mean_lux": 13.0, + "std_lux": 0.7071067811865476, + "min_lux": 12, + "max_lux": 14 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:44.021225Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f895ba50-3d8c-11eb-b3dd-f3b750bdd810", + "timestamp": "2020-12-13T21:48:44.021225Z", + "mean_lux": 10.666666666666666, + "std_lux": 0.4714045207910317, + "min_lux": 10, + "max_lux": 11 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:47.272532Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "fa85ca80-3d8c-11eb-a4d6-319dbd59ded1", + "timestamp": "2020-12-13T21:48:47.272532Z", + "time": "2020-12-13T22:48:47.231", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:48:54.025946Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "fe8c5ea0-3d8c-11eb-a94b-398e1d0230d5", + "timestamp": "2020-12-13T21:48:54.025946Z", + "mean_lux": 65.5, + "std_lux": 0.5, + "min_lux": 65, + "max_lux": 66 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:04.027098Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "048266b0-3d8d-11eb-88d2-bd718db1785a", + "timestamp": "2020-12-13T21:49:04.027098Z", + "mean_lux": 90.57142857142857, + "std_lux": 0.9035079029052513, + "min_lux": 89, + "max_lux": 92 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:12.029027Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "094768d0-3d8d-11eb-ba0d-af9b787947a9", + "timestamp": "2020-12-13T21:49:12.029027Z", + "free_physical_memory": 697745408, + "free_virtual_memory": 2510422016 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:14.024325Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "0a77d280-3d8d-11eb-bafd-e136d9e513dd", + "timestamp": "2020-12-13T21:49:14.024325Z", + "mean_lux": 89.5, + "std_lux": 0.5, + "min_lux": 89, + "max_lux": 90 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:18.732835Z", + "data_format": { + "namespace": "test", + "name": "battery" + } + }, + "body": { + "id": "0d4634c0-3d8d-11eb-9b96-f9d3476f7e61", + "timestamp": "2020-12-13T21:49:18.732835Z", + "battery_level": 100, + "battery_status": "discharging" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:24.021791Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "106d6560-3d8d-11eb-aa6c-05efd750787d", + "timestamp": "2020-12-13T21:49:24.021791Z", + "mean_lux": 73.14285714285714, + "std_lux": 37.42202778131225, + "min_lux": 5, + "max_lux": 100 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:34.027856Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "166430c0-3d8d-11eb-a5cc-25efeb98c7ea", + "timestamp": "2020-12-13T21:49:34.027856Z", + "mean_lux": 99.66666666666667, + "std_lux": 0.4714045207910317, + "min_lux": 99, + "max_lux": 100 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:44.026311Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "1c59c3a0-3d8d-11eb-8344-d59202ed8140", + "timestamp": "2020-12-13T21:49:44.026311Z", + "mean_lux": 99.66666666666667, + "std_lux": 0.4714045207910317, + "min_lux": 99, + "max_lux": 100 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:50.207056Z", + "data_format": { + "namespace": "test", + "name": "screen" + } + }, + "body": { + "id": "2008e8f0-3d8d-11eb-b282-f1e988191a90", + "timestamp": "2020-12-13T21:49:50.207056Z", + "screen_event": "SCREEN_OFF" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:49:54.026688Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "224fcbb0-3d8d-11eb-af2b-11bd9570aa6b", + "timestamp": "2020-12-13T21:49:54.026688Z", + "mean_lux": 118.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 118, + "max_lux": 119 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:04.026416Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "284585a0-3d8d-11eb-af8d-c3e802d965f9", + "timestamp": "2020-12-13T21:50:04.026416Z", + "mean_lux": 116.33333333333333, + "std_lux": 0.596284793999944, + "min_lux": 115, + "max_lux": 117 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:12.014772Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "2d088bf0-3d8d-11eb-afa8-abaa05f8e936", + "timestamp": "2020-12-13T21:50:12.014772Z", + "free_physical_memory": 553979904, + "free_virtual_memory": 2388783104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:14.022510Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "2e3af170-3d8d-11eb-8bee-a5a494fc3c96", + "timestamp": "2020-12-13T21:50:14.022510Z", + "mean_lux": 117.52941176470588, + "std_lux": 0.4991341984846218, + "min_lux": 117, + "max_lux": 118 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:24.026853Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "34316eb0-3d8d-11eb-b62d-61c4802912d5", + "timestamp": "2020-12-13T21:50:24.026853Z", + "mean_lux": 116.72727272727273, + "std_lux": 1.052348809344566, + "min_lux": 115, + "max_lux": 118 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:34.022331Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "3a268c60-3d8d-11eb-b7f1-1fc3553e45b8", + "timestamp": "2020-12-13T21:50:34.022331Z", + "mean_lux": 103.54545454545455, + "std_lux": 0.49792959773196915, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:44.023780Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "401cbb80-3d8d-11eb-ab68-0df122a96c73", + "timestamp": "2020-12-13T21:50:44.023780Z", + "mean_lux": 104.16666666666667, + "std_lux": 0.6871842709362769, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:50:54.028667Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "4613d500-3d8d-11eb-bea5-e7516d4b443c", + "timestamp": "2020-12-13T21:50:54.028667Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:04.031130Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "4c09b600-3d8d-11eb-b44c-ff156f65cbbd", + "timestamp": "2020-12-13T21:51:04.031130Z", + "mean_lux": 104.6, + "std_lux": 0.4898979485566356, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:12.021959Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "50cce360-3d8d-11eb-ab78-21d2f4e9ae86", + "timestamp": "2020-12-13T21:51:12.021959Z", + "free_physical_memory": 568209408, + "free_virtual_memory": 2402054144 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:14.029114Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "51ff21d0-3d8d-11eb-a151-33fced12efb3", + "timestamp": "2020-12-13T21:51:14.029114Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:24.026540Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "57f4b4b0-3d8d-11eb-9966-91bc573d9b70", + "timestamp": "2020-12-13T21:51:24.026540Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:34.027797Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "5deabcc0-3d8d-11eb-a111-8b6f763d41fa", + "timestamp": "2020-12-13T21:51:34.027797Z", + "mean_lux": 104.4, + "std_lux": 0.4898979485566356, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:44.024998Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "63e02890-3d8d-11eb-bf6f-3f742af628f3", + "timestamp": "2020-12-13T21:51:44.024998Z", + "mean_lux": 104.53333333333333, + "std_lux": 0.4988876515698588, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:51:54.029665Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "69d6cce0-3d8d-11eb-bb74-05771d49ee9c", + "timestamp": "2020-12-13T21:51:54.029665Z", + "mean_lux": 104.33333333333333, + "std_lux": 0.4714045207910317, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:04.026245Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "6fcc11a0-3d8d-11eb-9a04-b965814930b5", + "timestamp": "2020-12-13T21:52:04.026245Z", + "mean_lux": 104.46666666666667, + "std_lux": 0.4988876515698588, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:12.014269Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "748ef0e0-3d8d-11eb-adbe-27aeb147ae99", + "timestamp": "2020-12-13T21:52:12.014269Z", + "free_physical_memory": 485261312, + "free_virtual_memory": 2320801792 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:14.019192Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "75c10840-3d8d-11eb-a186-b570310572ff", + "timestamp": "2020-12-13T21:52:14.019192Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:24.027888Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "7bb821c0-3d8d-11eb-8ade-3f651ec0474d", + "timestamp": "2020-12-13T21:52:24.027888Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:34.028506Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "81ae02c0-3d8d-11eb-984b-57835ebb147c", + "timestamp": "2020-12-13T21:52:34.028506Z", + "mean_lux": 104.14285714285714, + "std_lux": 0.6388765649999399, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:44.027715Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "87a3e3c0-3d8d-11eb-820d-0728d4dee616", + "timestamp": "2020-12-13T21:52:44.027715Z", + "mean_lux": 103.83333333333333, + "std_lux": 0.6871842709362769, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:52:54.024243Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "8d992880-3d8d-11eb-a07c-d372c4e022c2", + "timestamp": "2020-12-13T21:52:54.024243Z", + "mean_lux": 101.36363636363636, + "std_lux": 2.185602778212965, + "min_lux": 99, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:04.029980Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "938ff3e0-3d8d-11eb-87b8-cf140f470590", + "timestamp": "2020-12-13T21:53:04.029980Z", + "mean_lux": 105.83333333333333, + "std_lux": 0.6871842709362769, + "min_lux": 105, + "max_lux": 107 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.021797Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "98536f60-3d8d-11eb-8399-7b2181bfc54b", + "timestamp": "2020-12-13T21:53:12.021797Z", + "free_physical_memory": 485474304, + "free_virtual_memory": 2322378752 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.259966Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "9877c040-3d8d-11eb-b857-d7f10c041956", + "timestamp": "2020-12-13T21:53:12.259966Z", + "time": "2020-12-13T21:53:12.247Z", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.374639Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "98894c70-3d8d-11eb-b637-b3dbcc458242", + "timestamp": "2020-12-13T21:53:12.374639Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.436869Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "9892c250-3d8d-11eb-a644-89cbfa6a4f3a", + "timestamp": "2020-12-13T21:53:12.436869Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.451145Z", + "data_format": { + "namespace": "test", + "name": "weather" + } + }, + "body": { + "id": "9894e530-3d8d-11eb-a081-43f2069e212d", + "timestamp": "2020-12-13T21:53:12.451145Z", + "country": "DK", + "area_name": "Virum", + "weather_main": "Clouds", + "weather_description": "scattered clouds", + "date": "2020-12-13T22:53:12.000", + "sunrise": "2020-12-13T08:32:35.000", + "sunset": "2020-12-13T15:36:41.000", + "latitude": 55.79, + "longitude": 12.45, + "pressure": 1012.0, + "wind_speed": 2.39, + "wind_degree": 142.0, + "humidity": 90.0, + "cloudiness": 29.0, + "rain_last_hour": 0.0, + "rain_last3_hours": 0.0, + "snow_last_hour": 0.0, + "snow_last3_hours": 0.0, + "temperature": 4.830000000000041, + "temp_min": 4.439999999999998, + "temp_max": 5.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:12.463188Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "9896b9f0-3d8d-11eb-b070-a1681ea49ad0", + "timestamp": "2020-12-13T21:53:12.463188Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:14.026858Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "99855fb0-3d8d-11eb-b2d9-fb08fc8cb68e", + "timestamp": "2020-12-13T21:53:14.026858Z", + "mean_lux": 105.5, + "std_lux": 0.5, + "min_lux": 105, + "max_lux": 106 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:14.724701Z", + "data_format": { + "namespace": "test", + "name": "air_quality" + } + }, + "body": { + "id": "99efe150-3d8d-11eb-a045-177b510f0446", + "timestamp": "2020-12-13T21:53:14.724701Z", + "air_quality_index": 10, + "source": "The Department of Environmental Science at Aarhus University", + "place": "H.C. Ørsted Institutet, Copenhagen, Denmark", + "latitude": 55.7007621, + "longitude": 12.5613124, + "air_quality_level": "GOOD" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:24.022086Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "9f7a7d60-3d8d-11eb-ba1e-5722f05093be", + "timestamp": "2020-12-13T21:53:24.022086Z", + "mean_lux": 105.53333333333333, + "std_lux": 0.4988876515698588, + "min_lux": 105, + "max_lux": 106 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:34.029409Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "a5716fd0-3d8d-11eb-a78f-cf77b745b287", + "timestamp": "2020-12-13T21:53:34.029409Z", + "mean_lux": 105.55555555555556, + "std_lux": 0.4969039949999533, + "min_lux": 105, + "max_lux": 106 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:44.028898Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "ab6750d0-3d8d-11eb-89c2-37e577c4f601", + "timestamp": "2020-12-13T21:53:44.028898Z", + "mean_lux": 104.53846153846153, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:53:54.024378Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "b15c6e80-3d8d-11eb-82c4-b91267dd8beb", + "timestamp": "2020-12-13T21:53:54.024378Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:04.027805Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "b752ebc0-3d8d-11eb-a892-f5d934b6236c", + "timestamp": "2020-12-13T21:54:04.027805Z", + "mean_lux": 104.0, + "std_lux": 0.7071067811865476, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:12.015650Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "bc15cb00-3d8d-11eb-900a-712de1ede559", + "timestamp": "2020-12-13T21:54:12.015650Z", + "free_physical_memory": 479133696, + "free_virtual_memory": 2315419648 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:14.024263Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "bd483080-3d8d-11eb-8774-311fddd5cc41", + "timestamp": "2020-12-13T21:54:14.024263Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:24.024943Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "c33e3890-3d8d-11eb-9910-ab058f9a9cfd", + "timestamp": "2020-12-13T21:54:24.024943Z", + "mean_lux": 104.46153846153847, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:34.025440Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "c9341990-3d8d-11eb-b51d-39fe673e76ec", + "timestamp": "2020-12-13T21:54:34.025440Z", + "mean_lux": 103.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:44.028545Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "cf2a6fc0-3d8d-11eb-9b25-af0e5252c620", + "timestamp": "2020-12-13T21:54:44.028545Z", + "mean_lux": 103.53846153846153, + "std_lux": 0.4985185152621431, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:54:54.021912Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "d51f6660-3d8d-11eb-b2cc-1fa4092f3058", + "timestamp": "2020-12-13T21:54:54.021912Z", + "mean_lux": 103.53846153846153, + "std_lux": 0.4985185152621431, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:04.024847Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "db15bc90-3d8d-11eb-9fa4-252073ead3aa", + "timestamp": "2020-12-13T21:55:04.024847Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:12.019725Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "dfd9ad40-3d8d-11eb-8168-4579d20b8f17", + "timestamp": "2020-12-13T21:55:12.019725Z", + "free_physical_memory": 476667904, + "free_virtual_memory": 2313547776 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:14.029066Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "e10c39d0-3d8d-11eb-98e6-4baf04225a0b", + "timestamp": "2020-12-13T21:55:14.029066Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:24.025167Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "e7017e90-3d8d-11eb-a43a-c9a7d8e96edc", + "timestamp": "2020-12-13T21:55:24.025167Z", + "mean_lux": 104.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:34.029001Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "ecf7fbd0-3d8d-11eb-ba42-514e05ce859a", + "timestamp": "2020-12-13T21:55:34.029001Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:44.028430Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f2edb5c0-3d8d-11eb-b01d-ff061a934817", + "timestamp": "2020-12-13T21:55:44.028430Z", + "mean_lux": 104.46153846153847, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:55:54.029738Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f8e3e4e0-3d8d-11eb-bc64-fddebfe3e182", + "timestamp": "2020-12-13T21:55:54.029738Z", + "mean_lux": 104.46153846153847, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:04.025365Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "fed90290-3d8d-11eb-8094-cbb18f31c930", + "timestamp": "2020-12-13T21:56:04.025365Z", + "mean_lux": 104.3076923076923, + "std_lux": 0.6056929133855239, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:12.016624Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "039c7e10-3d8e-11eb-af33-33ba748af5ec", + "timestamp": "2020-12-13T21:56:12.016624Z", + "free_physical_memory": 482611200, + "free_virtual_memory": 2319937536 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:14.024481Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "04cebc80-3d8e-11eb-abd2-6394bbcfd179", + "timestamp": "2020-12-13T21:56:14.024481Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:23.300621Z", + "data_format": { + "namespace": "test", + "name": "battery" + } + }, + "body": { + "id": "0a562440-3d8e-11eb-87cc-fd10addb3a2c", + "timestamp": "2020-12-13T21:56:23.300621Z", + "battery_level": 99, + "battery_status": "discharging" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:24.028358Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "0ac539c0-3d8e-11eb-9af5-eb52da822e3e", + "timestamp": "2020-12-13T21:56:24.028358Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:34.026480Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "10bacca0-3d8e-11eb-a644-09a13d7e8870", + "timestamp": "2020-12-13T21:56:34.026480Z", + "mean_lux": 104.45454545454545, + "std_lux": 0.49792959773196915, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:44.027617Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "16b0fbc0-3d8e-11eb-8278-b9335159970e", + "timestamp": "2020-12-13T21:56:44.027617Z", + "mean_lux": 104.3, + "std_lux": 0.6403124237432848, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:56:54.029568Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "1ca703d0-3d8e-11eb-9bd1-f10e13cbd462", + "timestamp": "2020-12-13T21:56:54.029568Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:04.023342Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "229bfa70-3d8e-11eb-a402-15b37f1f617e", + "timestamp": "2020-12-13T21:57:04.023342Z", + "mean_lux": 104.25, + "std_lux": 0.6614378277661477, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:12.020113Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "27603940-3d8e-11eb-8612-b5cec588215c", + "timestamp": "2020-12-13T21:57:12.020113Z", + "free_physical_memory": 535998464, + "free_virtual_memory": 2372243456 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:14.027214Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "289277b0-3d8e-11eb-938f-75495810e502", + "timestamp": "2020-12-13T21:57:14.027214Z", + "mean_lux": 103.5, + "std_lux": 0.5, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:24.027723Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "2e887fc0-3d8e-11eb-99e7-9f377a6fdb40", + "timestamp": "2020-12-13T21:57:24.027723Z", + "mean_lux": 104.16666666666667, + "std_lux": 0.6871842709362769, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:34.026876Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "347e39b0-3d8e-11eb-8292-fd32bb64bccd", + "timestamp": "2020-12-13T21:57:34.026876Z", + "mean_lux": 104.22222222222223, + "std_lux": 0.628539361054709, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:44.030068Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "3a74b6f0-3d8e-11eb-8118-e3d0fb692fe4", + "timestamp": "2020-12-13T21:57:44.030068Z", + "mean_lux": 103.6923076923077, + "std_lux": 0.6056929133855239, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:57:54.025541Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "4069ad90-3d8e-11eb-a313-47e86e627abd", + "timestamp": "2020-12-13T21:57:54.025541Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:04.029232Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "46602ad0-3d8e-11eb-97d9-f50fb714f099", + "timestamp": "2020-12-13T21:58:04.029232Z", + "mean_lux": 104.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.014266Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "4b2294e0-3d8e-11eb-ace4-d1e686c9d74b", + "timestamp": "2020-12-13T21:58:12.014266Z", + "free_physical_memory": 505942016, + "free_virtual_memory": 2347429888 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.247134Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "4b462270-3d8e-11eb-9e0c-6b78c952199b", + "timestamp": "2020-12-13T21:58:12.247134Z", + "time": "2020-12-13T21:58:12.241Z", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.358298Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "4b571260-3d8e-11eb-bdf5-6d020e31c01f", + "timestamp": "2020-12-13T21:58:12.358298Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.369453Z", + "data_format": { + "namespace": "test", + "name": "weather" + } + }, + "body": { + "id": "4b58c010-3d8e-11eb-8393-cff54a45872b", + "timestamp": "2020-12-13T21:58:12.369453Z", + "country": "DK", + "area_name": "Virum", + "weather_main": "Clouds", + "weather_description": "scattered clouds", + "date": "2020-12-13T22:53:12.000", + "sunrise": "2020-12-13T08:32:35.000", + "sunset": "2020-12-13T15:36:41.000", + "latitude": 55.79, + "longitude": 12.45, + "pressure": 1012.0, + "wind_speed": 2.39, + "wind_degree": 142.0, + "humidity": 90.0, + "cloudiness": 29.0, + "rain_last_hour": 0.0, + "rain_last3_hours": 0.0, + "snow_last_hour": 0.0, + "snow_last3_hours": 0.0, + "temperature": 4.830000000000041, + "temp_min": 4.439999999999998, + "temp_max": 5.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.392120Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "4b5c4280-3d8e-11eb-8a82-9bd0c8a83866", + "timestamp": "2020-12-13T21:58:12.392120Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:12.425129Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "4b614b90-3d8e-11eb-9696-25ab132ed972", + "timestamp": "2020-12-13T21:58:12.425129Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:14.019023Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "4c548530-3d8e-11eb-92d5-d7b534fd9592", + "timestamp": "2020-12-13T21:58:14.019023Z", + "mean_lux": 103.77777777777777, + "std_lux": 0.628539361054709, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:14.787356Z", + "data_format": { + "namespace": "test", + "name": "air_quality" + } + }, + "body": { + "id": "4cc9b530-3d8e-11eb-a196-c10d5421d156", + "timestamp": "2020-12-13T21:58:14.787356Z", + "air_quality_index": 10, + "source": "The Department of Environmental Science at Aarhus University", + "place": "H.C. Ørsted Institutet, Copenhagen, Denmark", + "latitude": 55.7007621, + "longitude": 12.5613124, + "air_quality_level": "GOOD" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:24.027254Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "524b9eb0-3d8e-11eb-a7b2-ad427e731593", + "timestamp": "2020-12-13T21:58:24.027254Z", + "mean_lux": 104.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:34.029411Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "5841cdd0-3d8e-11eb-ba74-6f8e829d2398", + "timestamp": "2020-12-13T21:58:34.029411Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:44.029137Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "5e37aed0-3d8e-11eb-a35e-e79c069bdbeb", + "timestamp": "2020-12-13T21:58:44.029137Z", + "mean_lux": 104.33333333333333, + "std_lux": 0.4714045207910317, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:58:54.028396Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "642d8fd0-3d8e-11eb-896f-6b476006c43e", + "timestamp": "2020-12-13T21:58:54.028396Z", + "mean_lux": 104.45454545454545, + "std_lux": 0.49792959773196915, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:04.027677Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "6a2349c0-3d8e-11eb-9667-331e99606c20", + "timestamp": "2020-12-13T21:59:04.027677Z", + "mean_lux": 103.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 103, + "max_lux": 104 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:12.021859Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "6ee71360-3d8e-11eb-897e-5f61962b4390", + "timestamp": "2020-12-13T21:59:12.021859Z", + "free_physical_memory": 502018048, + "free_virtual_memory": 2343702528 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:14.027670Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "70192ac0-3d8e-11eb-8211-455c9aa6c12b", + "timestamp": "2020-12-13T21:59:14.027670Z", + "mean_lux": 103.6923076923077, + "std_lux": 0.6056929133855239, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:24.026763Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "760ee4b0-3d8e-11eb-86b4-69bd1130e3fd", + "timestamp": "2020-12-13T21:59:24.026763Z", + "mean_lux": 103.83333333333333, + "std_lux": 0.6871842709362769, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:34.029330Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "7c0513d0-3d8e-11eb-9975-8b7bee88416b", + "timestamp": "2020-12-13T21:59:34.029330Z", + "mean_lux": 104.46153846153847, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:44.029616Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "81fb1be0-3d8e-11eb-b824-a9855d364d9f", + "timestamp": "2020-12-13T21:59:44.029616Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T21:59:54.027929Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "87f0aec0-3d8e-11eb-9ee1-1de9f854c311", + "timestamp": "2020-12-13T21:59:54.027929Z", + "mean_lux": 104.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:04.028325Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "8de68fc0-3d8e-11eb-ab11-e3e407a07152", + "timestamp": "2020-12-13T22:00:04.028325Z", + "mean_lux": 104.25, + "std_lux": 0.6614378277661477, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:12.014625Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "92a947f0-3d8e-11eb-934e-37b3b490f2c1", + "timestamp": "2020-12-13T22:00:12.014625Z", + "free_physical_memory": 498147328, + "free_virtual_memory": 2340532224 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:14.022880Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "93dbad70-3d8e-11eb-a13d-59f5c8713ef7", + "timestamp": "2020-12-13T22:00:14.022880Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:24.029505Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "99d29fe0-3d8e-11eb-930a-8155a2f23a10", + "timestamp": "2020-12-13T22:00:24.029505Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:34.028852Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "9fc859d0-3d8e-11eb-a6e7-cd071ce25790", + "timestamp": "2020-12-13T22:00:34.028852Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:44.021043Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "a5bd0250-3d8e-11eb-9ff3-53f034274e5c", + "timestamp": "2020-12-13T22:00:44.021043Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:00:54.025732Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "abb3a6a0-3d8e-11eb-a0bc-9f670e718bd0", + "timestamp": "2020-12-13T22:00:54.025732Z", + "mean_lux": 104.46153846153847, + "std_lux": 0.4985185152621431, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:04.028934Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "b1a9fcd0-3d8e-11eb-ae0c-0198562aa9d6", + "timestamp": "2020-12-13T22:01:04.028934Z", + "mean_lux": 104.16666666666667, + "std_lux": 0.6871842709362769, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:12.020715Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "b66d7850-3d8e-11eb-9719-df83214e58a0", + "timestamp": "2020-12-13T22:01:12.020715Z", + "free_physical_memory": 488013824, + "free_virtual_memory": 2330046464 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:14.029707Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "b7a004e0-3d8e-11eb-a692-1534d2008de5", + "timestamp": "2020-12-13T22:01:14.029707Z", + "mean_lux": 104.4, + "std_lux": 0.4898979485566356, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:24.028006Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "bd9597c0-3d8e-11eb-86ab-cb2ee764e91d", + "timestamp": "2020-12-13T22:01:24.028006Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:34.029126Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "c38b9fd0-3d8e-11eb-bedb-e598df60e75b", + "timestamp": "2020-12-13T22:01:34.029126Z", + "mean_lux": 104.44444444444444, + "std_lux": 0.4969039949999533, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:44.021078Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "c9804850-3d8e-11eb-b143-ef5990863743", + "timestamp": "2020-12-13T22:01:44.021078Z", + "mean_lux": 104.0, + "std_lux": 0.6324555320336759, + "min_lux": 103, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:01:54.025390Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "cf76c590-3d8e-11eb-89e2-53a3632dc620", + "timestamp": "2020-12-13T22:01:54.025390Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:04.018443Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "d56b9520-3d8e-11eb-be65-c5fd94186207", + "timestamp": "2020-12-13T22:02:04.018443Z", + "mean_lux": 104.6, + "std_lux": 0.4898979485566356, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:12.014573Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "da2fd3f0-3d8e-11eb-b797-ef6073bf3d58", + "timestamp": "2020-12-13T22:02:12.014573Z", + "free_physical_memory": 482865152, + "free_virtual_memory": 2325520384 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:14.021896Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "db621260-3d8e-11eb-bac7-df045232a867", + "timestamp": "2020-12-13T22:02:14.021896Z", + "mean_lux": 104.42857142857143, + "std_lux": 0.4948716593053935, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:24.028912Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "e15904d0-3d8e-11eb-8726-5f51f9c3ed80", + "timestamp": "2020-12-13T22:02:24.028912Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:34.029191Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "e74ee5d0-3d8e-11eb-b0a8-9df563a41066", + "timestamp": "2020-12-13T22:02:34.029191Z", + "mean_lux": 104.46666666666667, + "std_lux": 0.4988876515698588, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:44.028642Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "ed44c6d0-3d8e-11eb-a083-6b4c1a0c4db1", + "timestamp": "2020-12-13T22:02:44.028642Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:02:54.029584Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f33acee0-3d8e-11eb-9657-2de7b9943114", + "timestamp": "2020-12-13T22:02:54.029584Z", + "mean_lux": 104.45454545454545, + "std_lux": 0.49792959773196915, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:04.027729Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "f93061c0-3d8e-11eb-9592-bd17d6460a1f", + "timestamp": "2020-12-13T22:03:04.027729Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.021060Z", + "data_format": { + "namespace": "test", + "name": "memory" + } + }, + "body": { + "id": "fdf40450-3d8e-11eb-a8a1-1befa095dfcb", + "timestamp": "2020-12-13T22:03:12.021060Z", + "free_physical_memory": 499105792, + "free_virtual_memory": 2342580224 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.274211Z", + "data_format": { + "namespace": "test", + "name": "location" + } + }, + "body": { + "id": "fe1a9f20-3d8e-11eb-9e36-cb98ab60ee70", + "timestamp": "2020-12-13T22:03:12.274211Z", + "time": "2020-12-13T22:03:12.260Z", + "latitude": 55.7943684, + "longitude": 12.4462731, + "altitude": 76.30000305175781, + "accuracy": 20.0, + "speed": 0.0, + "speed_accuracy": 0.0, + "heading": 0.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.362078Z", + "data_format": { + "namespace": "test", + "name": "weather" + } + }, + "body": { + "id": "fe280ca0-3d8e-11eb-aeae-55df0128232f", + "timestamp": "2020-12-13T22:03:12.362078Z", + "country": "DK", + "area_name": "Virum", + "weather_main": "Clouds", + "weather_description": "scattered clouds", + "date": "2020-12-13T22:53:12.000", + "sunrise": "2020-12-13T08:32:35.000", + "sunset": "2020-12-13T15:36:41.000", + "latitude": 55.79, + "longitude": 12.45, + "pressure": 1012.0, + "wind_speed": 2.39, + "wind_degree": 142.0, + "humidity": 90.0, + "cloudiness": 29.0, + "rain_last_hour": 0.0, + "rain_last3_hours": 0.0, + "snow_last_hour": 0.0, + "snow_last3_hours": 0.0, + "temperature": 4.830000000000041, + "temp_min": 4.439999999999998, + "temp_max": 5.0 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.391342Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "fe2ca080-3d8e-11eb-9b27-8164b4e47cef", + "timestamp": "2020-12-13T22:03:12.391342Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.422089Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "fe313460-3d8e-11eb-b199-331296a58877", + "timestamp": "2020-12-13T22:03:12.422089Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:12.507743Z", + "data_format": { + "namespace": "test", + "name": "activity" + } + }, + "body": { + "id": "fe3e2cb0-3d8e-11eb-ae04-37150bb95525", + "timestamp": "2020-12-13T22:03:12.507743Z", + "confidence": 100, + "type": "STILL" + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:14.025597Z", + "data_format": { + "namespace": "test", + "name": "light" + } + }, + "body": { + "id": "ff25f4a0-3d8e-11eb-b9d1-a517a6ce18b8", + "timestamp": "2020-12-13T22:03:14.025597Z", + "mean_lux": 104.5, + "std_lux": 0.5, + "min_lux": 104, + "max_lux": 105 + } + }, + { + "header": { + "study_id": "2", + "user_id": "72c04755-5189-4f8e-87be-19962cffe1b4", + "start_time": "2020-12-13T22:03:14.592919Z", + "data_format": { + "namespace": "test", + "name": "air_quality" + } + }, + "body": { + "id": "ff7c7910-3d8e-11eb-b727-6f118311cc18", + "timestamp": "2020-12-13T22:03:14.592919Z", + "air_quality_index": 10, + "source": "The Department of Environmental Science at Aarhus University", + "place": "H.C. Ørsted Institutet, Copenhagen, Denmark", + "latitude": 55.7007621, + "longitude": 12.5613124, + "air_quality_level": "GOOD" + } + } +] \ No newline at end of file From 8c7454be4ea626afb97c287245491f0a240427ce Mon Sep 17 00:00:00 2001 From: bardram Date: Fri, 31 May 2024 12:24:43 +0200 Subject: [PATCH 4/4] fixing linter issues --- backends/carp_webservices/CHANGELOG.md | 3 +- .../carp_webservices/example/pubspec.yaml | 2 + .../carp_services/data_point_reference.dart | 1 - .../lib/carp_services/document_reference.dart | 4 - backends/carp_webservices/pubspec.yaml | 2 +- .../test/carp_data_stream_service_test.dart | 26 +-- .../test/carp_deployment_service_test.dart | 84 ++++--- .../test/carp_protocol_service_test.dart | 18 +- .../test/carp_service_test.dart | 213 +++++++++--------- 9 files changed, 176 insertions(+), 177 deletions(-) diff --git a/backends/carp_webservices/CHANGELOG.md b/backends/carp_webservices/CHANGELOG.md index 9486d61b..6f3c3b5a 100644 --- a/backends/carp_webservices/CHANGELOG.md +++ b/backends/carp_webservices/CHANGELOG.md @@ -1,6 +1,7 @@ -## 3.1.0 +## 3.2.0 * upgrade of carp_serialization and carp_core +* fix of issues [#392](https://github.com/cph-cachet/carp.sensing-flutter/issues/392) and [#369](https://github.com/cph-cachet/carp.sensing-flutter/issues/369). ## 3.0.1 diff --git a/backends/carp_webservices/example/pubspec.yaml b/backends/carp_webservices/example/pubspec.yaml index 304dd822..941876cf 100644 --- a/backends/carp_webservices/example/pubspec.yaml +++ b/backends/carp_webservices/example/pubspec.yaml @@ -20,6 +20,8 @@ dependencies: carp_webservices: path: ../ + oidc: ^0.5.2 + dev_dependencies: # The following section is specific to Flutter. diff --git a/backends/carp_webservices/lib/carp_services/data_point_reference.dart b/backends/carp_webservices/lib/carp_services/data_point_reference.dart index c4281fa8..38b44cab 100644 --- a/backends/carp_webservices/lib/carp_services/data_point_reference.dart +++ b/backends/carp_webservices/lib/carp_services/data_point_reference.dart @@ -273,7 +273,6 @@ class DataPointReference extends CarpReference { int httpStatusCode = response.statusCode; if (httpStatusCode == HttpStatus.ok) { - print('count response = ${response.body}'); return int.tryParse(response.body) ?? 0; } // All other cases are treated as an error. diff --git a/backends/carp_webservices/lib/carp_services/document_reference.dart b/backends/carp_webservices/lib/carp_services/document_reference.dart index e6a6c9ee..086fc2ce 100644 --- a/backends/carp_webservices/lib/carp_services/document_reference.dart +++ b/backends/carp_webservices/lib/carp_services/document_reference.dart @@ -106,10 +106,6 @@ class DocumentReference extends CarpReference { return DocumentSnapshot._(path, responseJson); } - print('$httpStatusCode - ${response.reasonPhrase}'); - print(responseJson["message"]); - print(responseJson["path"]); - throw CarpServiceException( httpStatus: HTTPStatus(httpStatusCode, response.reasonPhrase), message: responseJson["message"].toString(), diff --git a/backends/carp_webservices/pubspec.yaml b/backends/carp_webservices/pubspec.yaml index 36a6c227..0f7666bf 100644 --- a/backends/carp_webservices/pubspec.yaml +++ b/backends/carp_webservices/pubspec.yaml @@ -1,6 +1,6 @@ name: carp_webservices description: Flutter API for accessing the CARP web services - authentication, file management, data points, and app-specific collections of documents. -version: 3.1.0 +version: 3.2.0 homepage: https://github.com/cph-cachet/carp.sensing-flutter/tree/master/backends/carp_webservices environment: diff --git a/backends/carp_webservices/test/carp_data_stream_service_test.dart b/backends/carp_webservices/test/carp_data_stream_service_test.dart index 5bc11486..1e0d087d 100644 --- a/backends/carp_webservices/test/carp_data_stream_service_test.dart +++ b/backends/carp_webservices/test/carp_data_stream_service_test.dart @@ -115,18 +115,18 @@ void main() { triggerIds: {0}), ]; - print(toJsonString(batch)); + debugPrint(toJsonString(batch)); await CarpDataStreamService() .appendToDataStreams(testDeploymentId, batch); - print('Done uploading.'); + debugPrint('Done uploading.'); }, ); test( '- get', () async { - print('Getting 100 ...'); + debugPrint('Getting 100 ...'); var list = await CarpDataStreamService().getDataStream( DataStreamId( studyDeploymentId: testDeploymentId, @@ -136,8 +136,8 @@ void main() { 0, 100, ); - print(toJsonString(list)); - print('N = ${list.length}'); + debugPrint(toJsonString(list)); + debugPrint('N = ${list.length}'); }, ); @@ -183,18 +183,18 @@ void main() { test( '- upload & get - checking consistency (Issue #16)', () async { - print('Getting Geolocation measurements ...'); + debugPrint('Getting Geolocation measurements ...'); var list = await getGeoLocationBatches(); - print('N = ${list.length}'); + debugPrint('N = ${list.length}'); - // print('Uploading another batch of Geolocation measurements...'); - // await CarpDataStreamService() - // .appendToDataStreams(testDeploymentId, geoLocationBatch); + debugPrint('Uploading another batch of Geolocation measurements...'); + await CarpDataStreamService() + .appendToDataStreams(testDeploymentId, geoLocationBatch); - // var list2 = await getGeoLocationBatches(); - // print('N = ${list2.length}'); + var list2 = await getGeoLocationBatches(); + debugPrint('N = ${list2.length}'); - // expect(list2.length, list.length + 1); + expect(list2.length, list.length + 1); }, ); }); diff --git a/backends/carp_webservices/test/carp_deployment_service_test.dart b/backends/carp_webservices/test/carp_deployment_service_test.dart index 6634ae94..3d913804 100644 --- a/backends/carp_webservices/test/carp_deployment_service_test.dart +++ b/backends/carp_webservices/test/carp_deployment_service_test.dart @@ -39,15 +39,15 @@ void main() { group("Base services", () { test('- authentication', () async { - print('CarpService : ${CarpService().app}'); - print(" - signed in as: $user"); + debugPrint('CarpService : ${CarpService().app}'); + debugPrint(" - signed in as: $user"); - print(CarpAuthService().manager?.discoveryDocument); + debugPrint('${CarpAuthService().manager?.discoveryDocument}'); }, skip: false); test('- device ID', () async { String id = CarpDeploymentService().deployment().registeredDeviceId; - print('Registered Device ID : $id'); + debugPrint('Registered Device ID : $id'); }, skip: false); }); @@ -58,11 +58,9 @@ void main() { List invitations = await CarpParticipationService() .getActiveParticipationInvitations(); - for (var invitation in invitations) { - print(invitation); - } + expect(invitations, isNotNull); - print(toJsonString(invitations)); + debugPrint(toJsonString(invitations)); }, skip: false, ); @@ -74,7 +72,7 @@ void main() { CarpParticipationService().participation(testDeploymentId); ParticipantData data = await participation.getParticipantData(); - print(toJsonString(data)); + debugPrint(toJsonString(data)); }, skip: false, ); @@ -89,12 +87,12 @@ void main() { {SexInput.type: SexInput(value: Sex.Male)}, 'Participant', ); - print(toJsonString(data)); + debugPrint(toJsonString(data)); // expect(); // ParticipantData data = await participation.getParticipantData(); - // print(toJsonString(data)); + // debugPrint(toJsonString(data)); // assert(data != null); }, skip: false, @@ -104,43 +102,43 @@ void main() { group("Deployment - using DeploymentReference", () { test('- get deployment status', () async { final status = await CarpDeploymentService().deployment().getStatus(); - print(toJsonString(status)); + debugPrint(toJsonString(status)); expect(status.studyDeploymentId, testDeploymentId); }); test('- register device', () async { final reference = CarpDeploymentService().deployment(testDeploymentId); var status = await reference.getStatus(); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('${status.primaryDeviceStatus!.device}'); var newStatus = await reference.registerPrimaryDevice(); - print(newStatus); + debugPrint('$newStatus'); expect(newStatus.studyDeploymentId, testDeploymentId); }, skip: false); test('- get primary device deployment', () async { final reference = CarpDeploymentService().deployment(testDeploymentId); final status = await reference.getStatus(); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('${status.primaryDeviceStatus!.device}'); PrimaryDeviceDeployment deployment = await reference.get(); - print(toJsonString(deployment)); + debugPrint(toJsonString(deployment)); expect(deployment.registration.deviceId, isNotNull); }, skip: false); test('- deployment success', () async { final reference = CarpDeploymentService().deployment(testDeploymentId); final status_1 = await reference.getStatus(); - print(toJsonString(status_1)); + debugPrint(toJsonString(status_1)); final deployment = await reference.get(); final status_2 = await reference.deployed(); - print(toJsonString(deployment)); - print(toJsonString(status_2)); + debugPrint(toJsonString(deployment)); + debugPrint(toJsonString(status_2)); expect(status_1.studyDeploymentId, status_2.studyDeploymentId); expect(status_2.studyDeploymentId, testDeploymentId); }, skip: false); @@ -148,12 +146,12 @@ void main() { test('- unregister device', () async { final reference = CarpDeploymentService().deployment(testDeploymentId); var status = await reference.getStatus(); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('${status.primaryDeviceStatus!.device}'); status = await reference.unRegisterDevice( deviceRoleName: status.primaryDeviceStatus!.device.roleName); - print(status); + debugPrint('$status'); expect(status.studyDeploymentId, testDeploymentId); }, skip: false); }, skip: true); @@ -162,42 +160,42 @@ void main() { test('- get deployment status', () async { StudyDeploymentStatus status = await CarpDeploymentService() .getStudyDeploymentStatus(testDeploymentId); - print(toJsonString(status.toJson())); - print(status); - print(status.primaryDeviceStatus!.device); - print(toJsonString(status)); + debugPrint(toJsonString(status.toJson())); + debugPrint('$status'); + debugPrint('{status.primaryDeviceStatus?.device}'); + debugPrint(toJsonString(status)); expect(status.studyDeploymentId, testDeploymentId); }, skip: false); test('- register device', () async { StudyDeploymentStatus status = await CarpDeploymentService() .getStudyDeploymentStatus(testDeploymentId); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('{$status.primaryDeviceStatus?.device}'); status = await CarpDeploymentService().registerDevice( testDeploymentId, status.primaryDeviceStatus!.device.roleName, DefaultDeviceRegistration(deviceDisplayName: 'Samsung A10')); - print(status); + debugPrint('$status'); expect(status.studyDeploymentId, testDeploymentId); }, skip: false); test('- get primary device deployment', () async { StudyDeploymentStatus status = await CarpDeploymentService() .getStudyDeploymentStatus(testDeploymentId); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('${status.primaryDeviceStatus!.device}'); PrimaryDeviceDeployment deployment = await CarpDeploymentService().getDeviceDeploymentFor( testDeploymentId, status.primaryDeviceStatus!.device.roleName, ); - print(deployment); + debugPrint('$deployment'); for (var task in deployment.tasks) { - print(task); - task.measures?.forEach(print); + debugPrint('$task'); + task.measures?.forEach((measure) => debugPrint('$measure')); } expect(deployment.registration.deviceId, isNotNull); }, skip: false); @@ -205,15 +203,15 @@ void main() { test('- device deployed', () async { StudyDeploymentStatus status_1 = await CarpDeploymentService() .getStudyDeploymentStatus(testDeploymentId); - print(status_1); + debugPrint('$status_1'); expect(status_1.primaryDeviceStatus!.device, isNotNull); - print(status_1.primaryDeviceStatus!.device); + debugPrint('${status_1.primaryDeviceStatus!.device}'); PrimaryDeviceDeployment deployment = await CarpDeploymentService().getDeviceDeploymentFor( testDeploymentId, status_1.primaryDeviceStatus!.device.roleName, ); - print(deployment); + debugPrint('$deployment'); StudyDeploymentStatus status_2 = await CarpDeploymentService().deviceDeployed( @@ -221,7 +219,7 @@ void main() { status_1.primaryDeviceStatus!.device.roleName, deployment.lastUpdatedOn, ); - print(status_2); + debugPrint('$status_2'); expect(status_1.studyDeploymentId, status_2.studyDeploymentId); expect(status_2.studyDeploymentId, testDeploymentId); }); @@ -230,12 +228,12 @@ void main() { DeploymentReference reference = CarpDeploymentService().deployment(testDeploymentId); StudyDeploymentStatus status = await reference.getStatus(); - print(status); + debugPrint('$status'); expect(status.primaryDeviceStatus!.device, isNotNull); - print(status.primaryDeviceStatus!.device); + debugPrint('${status.primaryDeviceStatus!.device}'); status = await reference.unRegisterDevice( deviceRoleName: status.primaryDeviceStatus!.device.roleName); - print(status); + debugPrint('$status'); expect(status.studyDeploymentId, testDeploymentId); }, skip: false); }, skip: true); diff --git a/backends/carp_webservices/test/carp_protocol_service_test.dart b/backends/carp_webservices/test/carp_protocol_service_test.dart index bb16b473..b92841c6 100644 --- a/backends/carp_webservices/test/carp_protocol_service_test.dart +++ b/backends/carp_webservices/test/carp_protocol_service_test.dart @@ -103,8 +103,8 @@ void main() { group("Base services", () { test('- authentication', () async { - print('CarpService : ${CarpService().app}'); - print(" - signed in as: $user"); + debugPrint('CarpService : ${CarpService().app}'); + debugPrint(" - signed in as: $user"); }); }); @@ -113,7 +113,7 @@ void main() { test( '- define', () async { - print(toJsonString(protocol)); + debugPrint(toJsonString(protocol)); }, ); @@ -139,17 +139,17 @@ void main() { '- getBy', () async { var p = await CarpProtocolService().getBy(testProtocolId); - print(toJsonString(p)); + debugPrint(toJsonString(p)); }, ); test( '- getAllFor', () async { - print('Getting protocols for owner id: $ownerId'); + debugPrint('Getting protocols for owner id: $ownerId'); List protocols = await CarpProtocolService().getAllForOwner(ownerId!); - print(toJsonString(protocols)); + debugPrint(toJsonString(protocols)); }, ); @@ -158,7 +158,7 @@ void main() { () async { List versions = await CarpProtocolService().getVersionHistoryFor(testProtocolId); - print(toJsonString(versions)); + debugPrint(toJsonString(versions)); }, ); @@ -176,7 +176,7 @@ void main() { ) ], ); - print(toJsonString(p)); + debugPrint(toJsonString(p)); }, ); @@ -192,7 +192,7 @@ void main() { '{"version":1}', ); - print(toJsonString(protocol)); + debugPrint(toJsonString(protocol)); }, ); }); diff --git a/backends/carp_webservices/test/carp_service_test.dart b/backends/carp_webservices/test/carp_service_test.dart index 7303e05d..6cf8ca89 100644 --- a/backends/carp_webservices/test/carp_service_test.dart +++ b/backends/carp_webservices/test/carp_service_test.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:carp_mobile_sensing/carp_mobile_sensing.dart'; import 'package:carp_webservices/carp_auth/carp_auth.dart'; import 'package:carp_webservices/carp_services/carp_services.dart'; +import 'package:flutter/foundation.dart'; import 'package:test/test.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -61,8 +62,8 @@ void main() { expect(user.token, isNotNull); expect(user.isAuthenticated, true); - print("signed in : $user"); - print("token : ${user.token}"); + debugPrint("signed in : $user"); + debugPrint("token : ${user.token}"); }); setUp(() async { @@ -79,8 +80,8 @@ void main() { CarpUser newUser = CarpAuthService().currentUser; - print("signed in : $newUser"); - print(" name : ${newUser.firstName} ${newUser.lastName}"); + debugPrint("signed in : $newUser"); + debugPrint(" name : ${newUser.firstName} ${newUser.lastName}"); expect(newUser.firstName, isNotEmpty); expect(newUser.lastName, isNotEmpty); @@ -88,7 +89,7 @@ void main() { }); test('- oauth token refreshes', () async { - print('expiring token...'); + debugPrint('expiring token...'); CarpAuthService().currentUser.token!.expire(); CarpAuthService().currentUser; @@ -106,8 +107,8 @@ void main() { assert(newUser.isAuthenticated); assert(newUser.username == user.username); - print("signed in : $newUser"); - print(" token : ${newUser.token}"); + debugPrint("signed in : $newUser"); + debugPrint(" token : ${newUser.token}"); }); }); @@ -116,29 +117,29 @@ void main() { ConsentDocument uploaded = await CarpService().createConsentDocument( {"text": "The original terms text.", "signature": "Image Blob"}); - print(uploaded); - print('id : ${uploaded.id}'); - print('createdAt : ${uploaded.createdAt}'); - print('createdBy : ${uploaded.createdBy}'); - print('document : ${uploaded.document}'); + debugPrint('$uploaded'); + debugPrint('id : ${uploaded.id}'); + debugPrint('createdAt : ${uploaded.createdAt}'); + debugPrint('createdBy : ${uploaded.createdBy}'); + debugPrint('document : ${uploaded.document}'); }); test('- get', () async { // ConsentDocument uploaded = await CarpService().createConsentDocument( // {"text": "The original terms text.", "signature": "Image Blob"}); - // print(uploaded); + // debugPrint(uploaded); // expect(uploaded.id, isNotNull); ConsentDocument downloaded = await CarpService().getConsentDocument(1); // await CarpService().getConsentDocument(uploaded.id); - print(downloaded); - print('id : ${downloaded.id}'); - print('createdAt : ${downloaded.createdAt}'); - print('createdBy : ${downloaded.createdBy}'); - print('document : ${downloaded.document}'); + debugPrint('$downloaded'); + debugPrint('id : ${downloaded.id}'); + debugPrint('createdAt : ${downloaded.createdAt}'); + debugPrint('createdBy : ${downloaded.createdBy}'); + debugPrint('document : ${downloaded.document}'); }); }); @@ -151,13 +152,13 @@ void main() { data.carpHeader.studyId = testStudyId; data.carpHeader.userId = userId; - print(_encode(data.toJson())); + debugPrint(_encode(data.toJson())); int dataPointId = await CarpService().getDataPointReference().post(data); assert(dataPointId > 0); - print("data_point_id : $dataPointId"); + debugPrint("data_point_id : $dataPointId"); }); test('- post w/o trigger id & device role name', () async { @@ -172,18 +173,18 @@ void main() { data.carpHeader.startTime = null; data.carpHeader.endTime = null; - print(_encode(data.toJson())); + debugPrint(_encode(data.toJson())); int dataPointId = await CarpService().getDataPointReference().post(data); assert(dataPointId > 0); - print("data_point_id : $dataPointId"); + debugPrint("data_point_id : $dataPointId"); }); test('- batch', () async { final before = await CarpService().getDataPointReference().getAll(); - print('N_before = ${before.length}'); + debugPrint('N_before = ${before.length}'); List batch = []; batch.addAll([ @@ -204,8 +205,8 @@ void main() { await Future.delayed(const Duration(seconds: 5), () {}); final after = await CarpService().getDataPointReference().getAll(); - print('N_after = ${after.length}'); - // data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + debugPrint('N_after = ${after.length}'); + // data.forEach((datapoint) => debugPrint(_encode((datapoint.toJson())))); assert(after.length > before.length); }); @@ -218,13 +219,13 @@ void main() { await Future.delayed(const Duration(seconds: 2), () {}); String query = 'carp_header.data_format.namespace==test'; - print("query : $query"); + debugPrint("query : $query"); List data = await CarpService().getDataPointReference().query(query); - print('N=${data.length}'); - // data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + debugPrint('N=${data.length}'); + // data.forEach((datapoint) => debugPrint(_encode((datapoint.toJson())))); assert(data.length >= 140); }); @@ -234,36 +235,36 @@ void main() { // String query = // 'carp_header.data_format.name==${lightData.format.name}'; - print("query : $query"); + debugPrint("query : $query"); List data = await CarpService().getDataPointReference().query(query); - print('N=${data.length}'); - // data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + debugPrint('N=${data.length}'); + // data.forEach((datapoint) => debugPrint(_encode((datapoint.toJson())))); expect(data, isNotNull); }); test('- count data points based on query', () async { String query = 'carp_header.data_format.namespace==test'; - print("query : $query"); + debugPrint("query : $query"); int count = await CarpService().getDataPointReference().count(query); - print('N=$count'); + debugPrint('N=$count'); expect(count, greaterThanOrEqualTo(0)); }); test('- delete test data points', () async { String query = 'carp_header.data_format.namespace==test'; - print("query : $query"); + debugPrint("query : $query"); List data = await CarpService().getDataPointReference().query(query); - print('N=${data.length}'); - print('deleting...'); + debugPrint('N=${data.length}'); + debugPrint('deleting...'); for (var datapoint in data) { - print(' ${datapoint.id}'); + debugPrint(' ${datapoint.id}'); await CarpService().getDataPointReference().delete(datapoint.id!); } }); @@ -274,7 +275,7 @@ void main() { dataPost.carpHeader.studyId = studyId; dataPost.carpHeader.userId = userId; - print(_encode(dataPost.toJson())); + debugPrint(_encode(dataPost.toJson())); int dataPointId = await CarpService().getDataPointReference().post(dataPost); @@ -284,7 +285,7 @@ void main() { DataPoint dataGet = await CarpService().getDataPointReference().get(dataPointId); - print(_encode(dataGet.toJson())); + debugPrint(_encode(dataGet.toJson())); assert(dataGet.id == dataPointId); }); @@ -294,9 +295,10 @@ void main() { List data = await CarpService().getDataPointReference().getAll(); - data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + data.forEach( + (datapoint) => debugPrint(_encode((datapoint.toJson())))); expect(data, isNotNull); - print('N=${data.length}'); + debugPrint('N=${data.length}'); }, skip: false, ); @@ -321,19 +323,19 @@ void main() { // String query = 'carp_header.user_id==$userId'; //String query = 'carp_body.timestamp>2019-11-02T12:53:40.219598Z'; //String query = 'carp_header.data_format.namespace=in=(carp,omh)'; - print("query : $query"); + debugPrint("query : $query"); List data = await CarpService().getDataPointReference().query(query); expect(data, isNotNull); - print('N=${data.length}'); + debugPrint('N=${data.length}'); String str = '['; for (var datapoint in data) { str += '${datapoint.id},'; } - // data.forEach((datapoint) => print(_encode((datapoint.toJson())))); + // data.forEach((datapoint) => debugPrint(_encode((datapoint.toJson())))); str += ']'; - print(str); + debugPrint(str); }); test('- delete', () async { @@ -342,7 +344,7 @@ void main() { .post(DataPoint.fromData(lightData) ..carpHeader.studyId = studyId ..carpHeader.userId = userId); - print("DELETE data_point_id : $dataPointId"); + debugPrint("DELETE data_point_id : $dataPointId"); await CarpService().getDataPointReference().delete(dataPointId); }); @@ -352,10 +354,10 @@ void main() { List data = await CarpService().getDataPointReference().getAll(); - print('N=${data.length}'); - print('deleting...'); + debugPrint('N=${data.length}'); + debugPrint('deleting...'); for (var datapoint in data) { - print(' ${datapoint.id}'); + debugPrint(' ${datapoint.id}'); await CarpService() .getDataPointReference() .delete(datapoint.id!); @@ -367,7 +369,7 @@ void main() { List empty = await CarpService().getDataPointReference().getAll(); - print('N=${empty.length}'); + debugPrint('N=${empty.length}'); assert(empty.isEmpty); }, skip: true, @@ -408,16 +410,16 @@ void main() { // get it back from the server final original = await reference.get(); - print(_encode(original?.data)); + debugPrint(_encode(original?.data)); // updating the role to super user final updated = await reference .updateData({'email': userId, 'role': 'Super User'}); - print('----------- updated -------------'); - print(updated); - print(_encode(updated.data)); - print(updated.data["role"]); + debugPrint('----------- updated -------------'); + debugPrint('$updated'); + debugPrint(_encode(updated.data)); + debugPrint('${updated.data["role"]}'); expect(updated.id, greaterThan(0)); expect(updated.data["role"], 'Super User'); @@ -435,13 +437,13 @@ void main() { .document(userId) .setData({'email': userId, 'role': 'Administrator'}); - print(document); + debugPrint('$document'); expect(document, isNotNull); // then get it back by the id var newDocument = await CarpService().documentById(document.id).get(); - print((newDocument)); + debugPrint('$newDocument'); expect(newDocument, isNotNull); expect(newDocument?.id, document.id); @@ -465,7 +467,7 @@ void main() { .document(document.name) .get(); - print((newDocument)); + debugPrint('$newDocument'); expect(newDocument?.id, document.id); // delete document again @@ -487,35 +489,35 @@ void main() { // test(' - rename document', () async { // assert(document != null); -// print('----------- local document -------------'); -// print(document); -// print(_encode(document.data)); +// debugPrint('----------- local document -------------'); +// debugPrint(document); +// debugPrint(_encode(document.data)); -// print('----------- renamed document -------------'); +// debugPrint('----------- renamed document -------------'); // DocumentSnapshot renamedDocument = await CarpService() // .collection(collectionName) // .document(document.name) // .rename('new_name'); -// print(renamedDocument); -// print(_encode(renamedDocument.data)); +// debugPrint(renamedDocument); +// debugPrint(_encode(renamedDocument.data)); // // get the document back from the server // // DocumentSnapshot server_document = // // await CarpService().collection(collectionName).document(renamed_document.name).get(); -// print('----------- server document by ID -------------'); +// debugPrint('----------- server document by ID -------------'); // DocumentSnapshot serverDocument = // await CarpService().documentById(documentId).get(); -// print(serverDocument); -// print(_encode(serverDocument.data)); +// debugPrint(serverDocument); +// debugPrint(_encode(serverDocument.data)); -// print('----------- server document by NAME -------------'); +// debugPrint('----------- server document by NAME -------------'); // serverDocument = await CarpService() // .collection(collectionName) // .document(renamedDocument.name) // .get(); -// print(serverDocument); -// print(_encode(serverDocument.data)); +// debugPrint(serverDocument); +// debugPrint(_encode(serverDocument.data)); // assert(serverDocument.id > 0); // assert(serverDocument.name == renamedDocument.name); @@ -532,7 +534,7 @@ void main() { .document('cooking') .setData({'what': 'breakfast', 'time': 'morning'}); - print(doc1); + debugPrint('$doc1'); expect(doc1.id, greaterThan(0)); expect( doc1.path, equals('$collectionName/$userId/activities/cooking')); @@ -557,17 +559,17 @@ void main() { }); test('- expire token and the upload document', () async { - print('expiring token...'); + debugPrint('expiring token...'); CarpAuthService().currentUser.token!.expire(); - print('trying to upload a document w/o a name...'); + debugPrint('trying to upload a document w/o a name...'); DocumentSnapshot d = await CarpService() .collection(collectionName) .document() .setData({'email': username, 'name': 'Administrator'}); expect(d.id, greaterThan(0)); - print(d); + debugPrint('$d'); }); test(" - get a collection from path name", () async { @@ -585,9 +587,9 @@ void main() { List documents = await CarpService().collection(collectionName).documents; - print('N = ${documents.length}'); + debugPrint('N = ${documents.length}'); for (var doc in documents) { - print(doc); + debugPrint('$doc'); } expect(documents.length, greaterThan(0)); }); @@ -597,16 +599,16 @@ void main() { .collection(collectionName) .document(userId) .get(); - newDocument?.collections.forEach((element) => print(element)); + newDocument?.collections.forEach((element) => debugPrint(element)); }); test(" - list all nested documents in a collection", () async { List documents = await CarpService().collection(collectionName).documents; for (var doc in documents) { - print(doc); + debugPrint('$doc'); for (var col in doc.collections) { - print(col); + debugPrint(col); } } }); @@ -614,18 +616,18 @@ void main() { // test(" - list all collections in the root", () async { // List root = await CarpService().collection("").collections; // for (String ref in root) { -// print(ref); +// debugPrint(ref); // // List all documents in each collection // List documents = // await CarpService().collection("/$ref").documents; // for (DocumentSnapshot doc in documents) { -// print(doc); +// debugPrint(doc); // } // } // // documents = await CarpService().collection(collectionName).documents; // for (DocumentSnapshot doc in documents) { -// print(doc); +// debugPrint(doc); // } // }); @@ -633,7 +635,7 @@ void main() { CollectionReference collection = await CarpService().collection(collectionName).get(); expect(collection.id!, greaterThan(0)); - print(collection); + debugPrint('$collection'); }); test(' - delete document', () async { @@ -666,9 +668,10 @@ void main() { List documents = await CarpService().documentsByQuery(query); - print("Found ${documents.length} document(s) for user '$userId'"); + debugPrint( + "Found ${documents.length} document(s) for user '$userId'"); for (var document in documents) { - print(' - $document'); + debugPrint(' - $document'); } expect(documents.length, greaterThan(0)); @@ -677,9 +680,9 @@ void main() { test(' - get all documents', () async { List documents = await CarpService().documents(); - print('Found ${documents.length} document(s)'); + debugPrint('Found ${documents.length} document(s)'); for (var document in documents) { - print(' - $document'); + debugPrint(' - $document'); } expect(documents.length, greaterThan(0)); }); @@ -687,13 +690,13 @@ void main() { test(' - rename collection', () async { CollectionReference collection = await CarpService().collection(collectionName).get(); - print('Collection before rename: $collection'); + debugPrint('Collection before rename: $collection'); await collection.rename(newCollectionName); expect(collection.name, newCollectionName); - print('Collection after rename: $collection'); + debugPrint('Collection after rename: $collection'); collection = await CarpService().collection(newCollectionName).get(); expect(collection.name, newCollectionName); - print('Collection after get: $collection'); + debugPrint('Collection after get: $collection'); }); test(' - delete collection', () async { @@ -702,13 +705,13 @@ void main() { await collection.delete(); expect(collection.id, -1); - print(collection); + debugPrint('$collection'); try { collection = await CarpService().collection(newCollectionName).get(); } catch (error) { - print(error); + debugPrint('$error'); expect((error as CarpServiceException).httpStatus!.httpResponseCode, HttpStatus.notFound); } @@ -731,9 +734,9 @@ void main() { final response = await uploadTask.onComplete; expect(response.id, greaterThan(0)); - print('response.storageName : ${response.storageName}'); - print('response.studyId : ${response.studyId}'); - print('response.createdAt : ${response.createdAt}'); + debugPrint('response.storageName : ${response.storageName}'); + debugPrint('response.studyId : ${response.studyId}'); + debugPrint('response.createdAt : ${response.createdAt}'); }); test('- get', () async { @@ -753,9 +756,9 @@ void main() { final CarpFileResponse result = await CarpService().getFileStorageReference(id).get(); - print(result); + debugPrint('$result'); expect(result.id, id); - print('result : $result'); + debugPrint('result : $result'); }); test('- download', () async { @@ -780,7 +783,7 @@ void main() { int downResponse = await downloadTask.onComplete; expect(downResponse, 200); - print('status code : $downResponse'); + debugPrint('status code : $downResponse'); }); // NOTE that the following "get non-existing, "get all", "query", @@ -792,7 +795,7 @@ void main() { try { await CarpService().getFileStorageReference(876872).get(); } catch (error) { - print(error); + debugPrint('$error'); expect(error, isA()); expect((error as CarpServiceException).httpStatus!.httpResponseCode, HttpStatus.notFound); @@ -801,7 +804,7 @@ void main() { test('- get all', () async { final List results = await CarpService().getAllFiles(); - print('result : $results'); + debugPrint('result : $results'); }); test('- query', () async { @@ -811,7 +814,7 @@ void main() { if (results.isNotEmpty) { expect(results[0].originalName, 'img.jpg'); } - print('result : $results'); + debugPrint('result : $results'); }); test('- get by name', () async { @@ -821,9 +824,9 @@ void main() { if (reference != null) { final CarpFileResponse result = await reference.get(); expect(result.originalName, 'img.jpg'); - print('result : $result'); + debugPrint('result : $result'); } else { - print('File not found.'); + debugPrint('File not found.'); } }); @@ -838,9 +841,9 @@ void main() { .getFileStorageReference(reference.id) .delete(); expect(result, greaterThan(0)); - print('result : $result'); + debugPrint('result : $result'); } else { - print('File not found.'); + debugPrint('File not found.'); } }); }, skip: false);