Skip to content

Commit 05b34e8

Browse files
authored
Merge pull request #509 from YarnoVdW/main
Updated stream probe for beacon monitoring
2 parents d871dea + 9b2f561 commit 05b34e8

5 files changed

Lines changed: 124 additions & 40 deletions

File tree

carp_core/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 1.9.4
2+
3+
* fix of issue [#506](https://github.com/cph-cachet/carp.sensing-flutter/issues/506)
4+
* added unit tests for input data types
5+
16
## 1.9.3
27

38
* fix of issue [#491](https://github.com/cph-cachet/carp.sensing-flutter/issues/491)

carp_core/lib/carp_core.json.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ void _registerFromJsonFunctions() {
154154
SexInput(value: Sex.Female),
155155
FullNameInput(),
156156
AddressInput(),
157+
PhoneNumberInput(countryCode: '', number: ''),
157158
SocialSecurityNumberInput(socialSecurityNumber: '', country: ''),
158159
InformedConsentInput(name: '', userId: '', consent: '', signatureImage: ''),
159160
DiagnosisInput(icd11Code: ''),

carp_core/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: carp_core
22
description: The core domain model for the Copenhagen Research Platform (CARP) in Dart.
3-
version: 1.9.3
3+
version: 1.9.4
44
homepage: https://github.com/cph-cachet/carp.sensing-flutter
55

66
environment:

carp_core/test/carp_core_dart_test.dart

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,4 +300,88 @@ void main() {
300300
expect(task.getUrl('12345-1234', 'ecec573e-442b-4563-8e2c-62b7693011df', 1),
301301
'https://cans.cachet.dk/portal/playground/studies/ecec573e-442b-4563-8e2c-62b7693011df/settings?participant=12345-1234&trigger_id=1');
302302
});
303+
304+
group('InputData - deep assert', () {
305+
test('- CustomInput', () async {
306+
final dataJson = toJsonString(CustomInput(value: {'key': 'value'}));
307+
308+
final dataFromJson =
309+
CustomInput.fromJson(json.decode(dataJson) as Map<String, dynamic>);
310+
print(toJsonString(dataFromJson));
311+
expect(toJsonString(dataFromJson), equals(dataJson));
312+
});
313+
314+
test('- SexInput', () async {
315+
final dataJson = toJsonString(SexInput(value: Sex.Male));
316+
317+
final dataFromJson =
318+
SexInput.fromJson(json.decode(dataJson) as Map<String, dynamic>);
319+
print(toJsonString(dataFromJson));
320+
expect(toJsonString(dataFromJson), equals(dataJson));
321+
});
322+
323+
test('- PhoneNumberInput', () async {
324+
final dataJson = toJsonString(
325+
PhoneNumberInput(countryCode: '+45', number: '12345678'));
326+
327+
final dataFromJson = PhoneNumberInput.fromJson(
328+
json.decode(dataJson) as Map<String, dynamic>);
329+
print(toJsonString(dataFromJson));
330+
expect(toJsonString(dataFromJson), equals(dataJson));
331+
});
332+
333+
test('- SocialSecurityNumberInput', () async {
334+
final dataJson = toJsonString(SocialSecurityNumberInput(
335+
country: '45', socialSecurityNumber: '123456-7890'));
336+
337+
final dataFromJson = SocialSecurityNumberInput.fromJson(
338+
json.decode(dataJson) as Map<String, dynamic>);
339+
print(toJsonString(dataFromJson));
340+
expect(toJsonString(dataFromJson), equals(dataJson));
341+
});
342+
343+
test('- FullNameInput', () async {
344+
final dataJson = toJsonString(
345+
FullNameInput(firstName: 'John', middleName: 'A.', lastName: 'Doe'));
346+
347+
final dataFromJson =
348+
FullNameInput.fromJson(json.decode(dataJson) as Map<String, dynamic>);
349+
print(toJsonString(dataFromJson));
350+
expect(toJsonString(dataFromJson), equals(dataJson));
351+
});
352+
353+
test('- AddressInput', () async {
354+
final dataJson =
355+
toJsonString(AddressInput(street: 'Main St', city: 'Anytown'));
356+
357+
final dataFromJson =
358+
AddressInput.fromJson(json.decode(dataJson) as Map<String, dynamic>);
359+
print(toJsonString(dataFromJson));
360+
expect(toJsonString(dataFromJson), equals(dataJson));
361+
});
362+
363+
test('- DiagnosisInput', () async {
364+
final dataJson =
365+
toJsonString(DiagnosisInput(diagnosis: 'Flu', icd11Code: '123456'));
366+
367+
final dataFromJson = DiagnosisInput.fromJson(
368+
json.decode(dataJson) as Map<String, dynamic>);
369+
print(toJsonString(dataFromJson));
370+
expect(toJsonString(dataFromJson), equals(dataJson));
371+
});
372+
373+
test('- InformedConsentInput', () async {
374+
final dataJson = toJsonString(InformedConsentInput(
375+
userId: '12345',
376+
name: 'John Doe',
377+
consent: 'true',
378+
signatureImage: 'blob',
379+
));
380+
381+
final dataFromJson = InformedConsentInput.fromJson(
382+
json.decode(dataJson) as Map<String, dynamic>);
383+
print(toJsonString(dataFromJson));
384+
expect(toJsonString(dataFromJson), equals(dataJson));
385+
});
386+
});
303387
}

packages/carp_connectivity_package/lib/connectivity_probes.dart

Lines changed: 33 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@ class ConnectivityProbe extends StreamProbe {
1313
@override
1414
Future<bool> onStart() async {
1515
// collect the current connectivity status on sampling start
16-
var connectivityStatus =
17-
await connectivity.Connectivity().checkConnectivity();
18-
addMeasurement(Measurement.fromData(
19-
Connectivity.fromConnectivityResult(connectivityStatus)));
16+
var connectivityStatus = await connectivity.Connectivity().checkConnectivity();
17+
addMeasurement(Measurement.fromData(Connectivity.fromConnectivityResult(connectivityStatus)));
2018

2119
return super.onStart();
2220
}
2321

2422
@override
25-
Stream<Measurement> get stream =>
26-
connectivity.Connectivity().onConnectivityChanged.map((event) =>
27-
Measurement.fromData(Connectivity.fromConnectivityResult(event)));
23+
Stream<Measurement> get stream => connectivity.Connectivity()
24+
.onConnectivityChanged
25+
.map((event) => Measurement.fromData(Connectivity.fromConnectivityResult(event)));
2826
}
2927

3028
// This probe requests access to location permissions (both on Android and iOS).
@@ -69,24 +67,17 @@ class BluetoothProbe extends BufferingPeriodicStreamProbe {
6967
Stream<dynamic> get bufferingStream => FlutterBluePlus.scanResults;
7068

7169
@override
72-
Future<Measurement?> getMeasurement() async =>
73-
_data != null ? Measurement.fromData(_data!) : null;
70+
Future<Measurement?> getMeasurement() async => _data != null ? Measurement.fromData(_data!) : null;
7471

7572
// if a BT-specific sampling configuration is used, we need to
7673
// extract the services and remoteIds from it so FlutterBluePlus can
7774
// perform filtered scanning
78-
List<Guid> get services => (samplingConfiguration
79-
is BluetoothScanPeriodicSamplingConfiguration)
80-
? (samplingConfiguration as BluetoothScanPeriodicSamplingConfiguration)
81-
.withServices
82-
.map((e) => Guid(e))
83-
.toList()
75+
List<Guid> get services => (samplingConfiguration is BluetoothScanPeriodicSamplingConfiguration)
76+
? (samplingConfiguration as BluetoothScanPeriodicSamplingConfiguration).withServices.map((e) => Guid(e)).toList()
8477
: [];
8578

86-
List<String> get remoteIds => (samplingConfiguration
87-
is BluetoothScanPeriodicSamplingConfiguration)
88-
? (samplingConfiguration as BluetoothScanPeriodicSamplingConfiguration)
89-
.withRemoteIds
79+
List<String> get remoteIds => (samplingConfiguration is BluetoothScanPeriodicSamplingConfiguration)
80+
? (samplingConfiguration as BluetoothScanPeriodicSamplingConfiguration).withRemoteIds
9081
: [];
9182

9283
@override
@@ -97,8 +88,7 @@ class BluetoothProbe extends BufferingPeriodicStreamProbe {
9788
FlutterBluePlus.startScan(
9889
withServices: services,
9990
withRemoteIds: remoteIds,
100-
timeout: samplingConfiguration?.duration ??
101-
const Duration(milliseconds: DEFAULT_TIMEOUT),
91+
timeout: samplingConfiguration?.duration ?? const Duration(milliseconds: DEFAULT_TIMEOUT),
10292
);
10393
} catch (error) {
10494
FlutterBluePlus.stopScan();
@@ -132,19 +122,15 @@ class BeaconProbe extends StreamProbe {
132122
super.samplingConfiguration as BeaconRangingPeriodicSamplingConfiguration;
133123

134124
List<Region> get beaconRegions =>
135-
samplingConfiguration?.beaconRegions
136-
.map((region) => region.toRegion())
137-
.toList() ??
138-
[];
125+
samplingConfiguration?.beaconRegions.map((region) => region.toRegion()).toList() ?? [];
139126

140127
int get beaconDistance => samplingConfiguration?.beaconDistance ?? 2;
141128

142129
@override
143130
bool onInitialize() {
144131
super.onInitialize();
145132
if (beaconRegions.isEmpty) {
146-
warning(
147-
'$runtimeType - No beacon regions specified for monitoring. Will not start monitoring.');
133+
warning('$runtimeType - No beacon regions specified for monitoring. Will not start monitoring.');
148134
return false;
149135
}
150136

@@ -165,15 +151,17 @@ class BeaconProbe extends StreamProbe {
165151
}
166152

167153
@override
168-
Stream<Measurement> get stream => flutterBeacon.ranging(beaconRegions).map(
169-
(RangingResult result) {
170-
final closeBeacons = result.beacons
171-
.where((beacon) => beacon.accuracy <= beaconDistance);
172-
173-
// If no beacons are close, still return an measurement with an empty
174-
// list of iBeacons for this region.
175-
return Measurement.fromData(
176-
BeaconData(region: result.region.identifier)
154+
Stream<Measurement> get stream async* {
155+
await for (final monitoringResult in flutterBeacon.monitoring(beaconRegions)) {
156+
if (monitoringResult.monitoringState == MonitoringState.inside) {
157+
info('$runtimeType - Entered region: ${monitoringResult.region.identifier}');
158+
159+
yield* flutterBeacon.ranging(beaconRegions).map(
160+
(rangingResult) {
161+
final closeBeacons = rangingResult.beacons.where((beacon) => beacon.accuracy <= beaconDistance);
162+
163+
return Measurement.fromData(
164+
BeaconData(region: rangingResult.region.identifier)
177165
..scanResult = closeBeacons
178166
.map((beacon) => BeaconDevice(
179167
uuid: beacon.proximityUUID,
@@ -183,7 +171,13 @@ class BeaconProbe extends StreamProbe {
183171
accuracy: beacon.accuracy,
184172
proximity: beacon.proximity,
185173
))
186-
.toList());
187-
},
188-
);
174+
.toList(),
175+
);
176+
},
177+
);
178+
} else if (monitoringResult.monitoringState == MonitoringState.outside) {
179+
info('$runtimeType - Exited region: ${monitoringResult.region.identifier}');
180+
}
181+
}
182+
}
189183
}

0 commit comments

Comments
 (0)