From 0967e45752667e9dd6f8389808d728a4ac6c6203 Mon Sep 17 00:00:00 2001 From: Faiz Hashmi Date: Mon, 5 Feb 2024 11:24:23 +0300 Subject: [PATCH] Added till andesfit blood sugar device --- .../andesfit_blood_sugar_connect_screen.dart | 131 +++++++++++++ .../andesfit_temperature_connect_screen.dart | 138 ++++++++++++++ .../andesfit_weigth_scale_connect_screen.dart | 54 ++++-- .../ble_devices_screen.dart | 15 +- .../select_tracker_type.dart | 12 ++ .../my_trackers_view_model.dart | 172 +++++++++++++++--- 6 files changed, 483 insertions(+), 39 deletions(-) create mode 100644 lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_sugar_connect_screen.dart create mode 100644 lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_temperature_connect_screen.dart diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_sugar_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_sugar_connect_screen.dart new file mode 100644 index 00000000..77cf829a --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_blood_sugar_connect_screen.dart @@ -0,0 +1,131 @@ +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class AndesFitBloodSugarConnectScreen extends StatefulWidget { + final BluetoothDevice deviceModel; + + const AndesFitBloodSugarConnectScreen({this.deviceModel}); + + @override + State createState() => _AndesFitBloodSugarConnectScreenState(); +} + +class _AndesFitBloodSugarConnectScreenState extends State { + MyTrackersViewModel myTrackersVm; + + @override + void initState() { + myTrackersVm = context.read(); + myTrackersVm.connectAndesfitBloodSugarDevice(widget.deviceModel); + super.initState(); + } + + @override + void dispose() { + myTrackersVm.bloodSugarValuesStream.cancel(); + myTrackersVm.currentBloodGlucose = null; + myTrackersVm.selectedAndesFitScanResult = null; + myTrackersVm.isAndesfitDeviceConnected = null; + myTrackersVm.disConnectAndesfitDevice(widget.deviceModel); + super.dispose(); + } + + Widget buildWeightScaleUI(MyTrackersViewModel myTrackersViewModel) { + return Expanded( + child: ListView( + children: [ + if (myTrackersViewModel.currentBloodGlucose == null && myTrackersViewModel.isAndesfitDeviceConnected) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + mHeight(24.0), + Column( + children: [ + Text("Please Wait", style: TextStyle(fontSize: 20)), + ], + ), + mHeight(24.0), + ], + ), + ] else if (myTrackersViewModel.currentBloodGlucose != null) ...[ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(24.0), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + Text("Blood Sugar", style: TextStyle(fontSize: 20)), + Text(myTrackersViewModel.currentBloodGlucose.toString(), style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)), + Text("mg/dL", style: TextStyle(fontSize: 15)), + ], + ), + ], + ), + ], + ), + ] else ...[ + Padding( + padding: const EdgeInsets.all(24.0), + child: Center( + child: Text( + "Some animation with the instruction", + style: TextStyle(fontSize: 9.0), + ), + ), + ) + ], + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "${widget.deviceModel.localName}", + showNewAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: Padding( + padding: const EdgeInsets.all(24.0), + child: Consumer( + builder: (BuildContext context, MyTrackersViewModel myTrackersViewModel, Widget child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + buildWeightScaleUI(myTrackersViewModel), + if (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected) ...[ + Row( + children: [ + Expanded( + child: DefaultButton( + "Disconnect with ${widget.deviceModel.localName}", + () async { + myTrackersVm.disConnectAndesfitDevice(widget.deviceModel); + Navigator.pop(context); + }, + textColor: Colors.white, + ), + ), + ], + ), + ] + ], + ); + }, + ), + ), + ); + } +} diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_temperature_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_temperature_connect_screen.dart new file mode 100644 index 00000000..57552fd0 --- /dev/null +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_temperature_connect_screen.dart @@ -0,0 +1,138 @@ +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; +import 'package:flutter_blue_plus/flutter_blue_plus.dart'; +import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; +import 'package:diplomaticquarterapp/uitl/utils_new.dart'; +import 'package:diplomaticquarterapp/widgets/buttons/defaultButton.dart'; +import 'package:diplomaticquarterapp/widgets/others/app_scaffold_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; + +class AndesFitTemperatureConnectScreen extends StatefulWidget { + final BluetoothDevice deviceModel; + + const AndesFitTemperatureConnectScreen({this.deviceModel}); + + @override + State createState() => _AndesFitTemperatureConnectScreenState(); +} + +class _AndesFitTemperatureConnectScreenState extends State { + MyTrackersViewModel myTrackersVm; + + @override + void initState() { + myTrackersVm = context.read(); + myTrackersVm.connectAndesfitTemperatureDevice(widget.deviceModel); + super.initState(); + } + + @override + void dispose() { + myTrackersVm.currentTempInCelsius = null; + myTrackersVm.selectedAndesFitScanResult = null; + myTrackersVm.isAndesfitDeviceConnected = null; + myTrackersVm.disConnectAndesfitDevice(widget.deviceModel); + super.dispose(); + } + + Widget buildTemperatureScaleUI(MyTrackersViewModel myTrackersViewModel) { + return Expanded( + child: ListView( + children: [ + if (myTrackersViewModel.currentTempInCelsius == null && (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected)) ...[ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + mHeight(24.0), + Column( + children: [ + // Text("Please stay Still.", style: TextStyle(fontSize: 100, fontWeight: FontWeight.bold)), + Text("Please Wait", style: TextStyle(fontSize: 20)), + ], + ), + mHeight(24.0), + ], + ), + ] else if (myTrackersViewModel.currentTempInCelsius != null) ...[ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + mHeight(24.0), + Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Column( + children: [ + // Text("Temperature", style: TextStyle(fontSize: 20)), + Text((myTrackersViewModel.currentTempInCelsius.split(" / ")[0]).toString(), style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)), + Text("Celsius", style: TextStyle(fontSize: 15)), + ], + ), + Column( + children: [ + // Text("Temperature", style: TextStyle(fontSize: 20)), + Text((myTrackersViewModel.currentTempInCelsius.split(" / ")[1]).toString(), style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)), + Text("Fahrenheit", style: TextStyle(fontSize: 15)), + ], + ), + ], + ), + ], + ), + ] else ...[ + Padding( + padding: const EdgeInsets.all(24.0), + child: Center( + child: Text( + "Some animation with the instruction", + style: TextStyle(fontSize: 9.0), + ), + ), + ) + ], + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return AppScaffold( + appBarTitle: "${widget.deviceModel.localName}", + showNewAppBar: true, + isShowDecPage: false, + showNewAppBarTitle: true, + backgroundColor: Color(0xffF8F8F8), + body: Padding( + padding: const EdgeInsets.all(24.0), + child: Consumer( + builder: (BuildContext context, MyTrackersViewModel myTrackersViewModel, Widget child) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + buildTemperatureScaleUI(myTrackersViewModel), + if (myTrackersViewModel.isAndesfitDeviceConnected != null && myTrackersViewModel.isAndesfitDeviceConnected) ...[ + Row( + children: [ + Expanded( + child: DefaultButton( + "Disconnect with ${widget.deviceModel.localName}", + () async { + myTrackersVm.disConnectAndesfitDevice(widget.deviceModel); + Navigator.pop(context); + }, + textColor: Colors.white, + ), + ), + ], + ), + ] + ], + ); + }, + ), + ), + ); + } +} diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart index 00460ec6..615b1bad 100644 --- a/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/andesfit_device_types/andesfit_weigth_scale_connect_screen.dart @@ -1,3 +1,4 @@ +import 'package:diplomaticquarterapp/extensions/string_extensions.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart'; import 'package:diplomaticquarterapp/uitl/utils_new.dart'; @@ -38,21 +39,21 @@ class _AndesFitWeightScaleConnectScreenState extends State { break; case TrackerTypeEnum.BloodSugarTracker: if (myTrackersVm.isDeviceFromAndesFit(device.name)) { + myTrackersVm.currentBloodGlucose = null; + Navigator.pushReplacement(context, FadePage(page: AndesFitBloodSugarConnectScreen(deviceModel: device.andesfitBluetoothDevice))); return; } - // TODO: Handle this case. break; case TrackerTypeEnum.ECGTracker: if (myTrackersVm.isDeviceFromAndesFit(device.name)) { @@ -74,13 +79,21 @@ class _BleDevicesScreenState extends State { myTrackersVm.ecgRtModel = null; Navigator.pushReplacement(context, FadePage(page: ECGConnectScreen(deviceModel: device))); break; + case TrackerTypeEnum.WeightScale: if (myTrackersVm.isDeviceFromAndesFit(device.name)) { myTrackersVm.andesfitWeightScaleData = null; Navigator.pushReplacement(context, FadePage(page: AndesFitWeightScaleConnectScreen(deviceModel: device.andesfitBluetoothDevice))); return; } + break; + case TrackerTypeEnum.Temperature: + if (myTrackersVm.isDeviceFromAndesFit(device.name)) { + myTrackersVm.currentTempInCelsius = null; + Navigator.pushReplacement(context, FadePage(page: AndesFitTemperatureConnectScreen(deviceModel: device.andesfitBluetoothDevice))); + return; + } break; case TrackerTypeEnum.AllInOneTracker: if (myTrackersVm.isDeviceFromAndesFit(device.name)) { diff --git a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart index 6a82f2bc..276717eb 100644 --- a/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart +++ b/lib/pages/medical/my_trackers/ble_device_type_screens/select_tracker_type.dart @@ -71,6 +71,18 @@ class SelectTrackerType extends StatelessWidget { isEnable: true, ), )); + medical.add(InkWell( + onTap: () { + context.read().updateSelectedTrackerType(TrackerTypeEnum.Temperature); + Navigator.of(context).push(FadePage(page: BleDevicesScreen())); + }, + child: MedicalProfileItem( + title: "Temperature", + imagePath: 'tracker.svg', + subTitle: "Scale", + isEnable: true, + ), + )); medical.add(InkWell( onTap: () { context.read().updateSelectedTrackerType(TrackerTypeEnum.AllInOneTracker); diff --git a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart index a88346a1..0ee969b6 100644 --- a/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart +++ b/lib/pages/medical/my_trackers/my_trackers_view_model/my_trackers_view_model.dart @@ -20,7 +20,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:diplomaticquarterapp/pages/medical/my_trackers/ble_helpers/ble_connect_helper.dart'; import 'package:flutter/material.dart'; -enum TrackerTypeEnum { OxymeterTracker, BloodPressureTracker, BloodSugarTracker, ECGTracker, WeightScale, AllInOneTracker } +enum TrackerTypeEnum { OxymeterTracker, BloodPressureTracker, BloodSugarTracker, ECGTracker, WeightScale, Temperature, AllInOneTracker } //NativeEventNames @@ -60,6 +60,9 @@ class MyTrackersViewModel extends ChangeNotifier { "WeightScale": [ {"model": ""}, ], + "Temperature": [ + {"model": ""}, + ], "AllInOneTracker": [ {"model": ""}, ], @@ -73,7 +76,7 @@ class MyTrackersViewModel extends ChangeNotifier { {"model": "BPM"}, //Done ], "BloodSugarTracker": [ - {"model": ""}, + {"model": "Samico GL"}, ], "ECGTracker": [ {"model": "PM101897"}, //Done @@ -81,13 +84,16 @@ class MyTrackersViewModel extends ChangeNotifier { "WeightScale": [ {"model": "SDIC"}, ], + "Temperature": [ + {"model": "TEMP"}, + ], "AllInOneTracker": [ {"model": ""}, ], }; List ecgEnabledDevices = ["BP2 0567", "DuoEK", "ER1", "PM101897"]; - List andesFitDevices = ["BPM", "PM101897", "SDIC"]; + List andesFitDevices = ["BPM", "PM101897", "SDIC", "TEMP", "Samico GL"]; StreamSubscription bleDevicesStream; @@ -243,13 +249,12 @@ class MyTrackersViewModel extends ChangeNotifier { void filterOutTheSearchedDevicesFlutter(List allDevices) { if (devicesInfoJsonAndesfit.containsKey(currentSelectedTrackerType.name)) { + List devicesInSelectedType = devicesInfoJsonAndesfit[currentSelectedTrackerType.name]; for (var foundDevice in allDevices) { - List devicesInSelectedType = devicesInfoJsonAndesfit[currentSelectedTrackerType.name]; for (var device in devicesInSelectedType) { if (isAndesfitDeviceConnected != null && isAndesfitDeviceConnected) { return; } - log("heres: $devicesInSelectedType"); foundDevice.deviceType = currentSelectedTrackerType; log("here1: ${device['model']}"); log("here2: ${foundDevice.name}"); @@ -377,10 +382,16 @@ class MyTrackersViewModel extends ChangeNotifier { } void startFlutterScan() { + log("FlutterBluePlus.isScanningNow: ${FlutterBluePlus.isScanningNow}"); if (FlutterBluePlus.isScanningNow == false) { bleDevicesStream = FlutterBluePlus.scanResults.listen((results) { List blueToothDevices = results; List bleDevices = []; + if (isAndesfitDeviceConnected != null && isAndesfitDeviceConnected) { + bleDevicesStream.cancel(); + FlutterBluePlus.stopScan(); + return; + } blueToothDevices.forEach((element) async { if (element.device.localName.isNotEmpty) { log("blueToothDevicesFlutter: ${element.device.localName}"); @@ -457,7 +468,7 @@ class MyTrackersViewModel extends ChangeNotifier { if (state == BluetoothConnectionState.connected) { isAndesfitDeviceConnected = true; notifyListeners(); - + bleDevicesStream.cancel(); List services = await device.discoverServices(); services.forEach((service) { if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLOOD_PRESSURE_SERVICE) { @@ -574,7 +585,12 @@ class MyTrackersViewModel extends ChangeNotifier { notifyListeners(); } + String resultSet1 = ""; + String resultSet2 = ""; + Future connectAndesfitWeightDevice(BluetoothDevice device) async { + log("deviceToConnect: ${device.toString()}"); + device.connectionState.listen((BluetoothConnectionState state) async { if (state == BluetoothConnectionState.disconnected) { isAndesfitDeviceConnected = false; @@ -583,9 +599,11 @@ class MyTrackersViewModel extends ChangeNotifier { if (state == BluetoothConnectionState.connected) { isAndesfitDeviceConnected = true; notifyListeners(); - + bleDevicesStream.cancel(); List services = await device.discoverServices(); services.forEach((service) { + log("services in weightscale: ${service.serviceUuid}"); + if (service.serviceUuid.toString().toLowerCase() == BLEUtils.WEIGHT_MEASUREMENT_SERVICE) { print(service.serviceUuid); service.characteristics.forEach((characteristic) async { @@ -610,8 +628,6 @@ class MyTrackersViewModel extends ChangeNotifier { //Sample Results // ----------Result Set 1----------: 42;0;1;0;0;0;0;65;9;b0;d2;0;7f;3;44;0;ac;1;cc;0 // ----------Result Set 2----------: 42;1;32;0;2c;0;1;3;84;9;1b;0;29;2;9c;0;10;0;e9 - String resultSet1 = ""; - String resultSet2 = ""; if (event[1] == 0) { resultSet1 = convertResultSetToString(event); @@ -621,7 +637,7 @@ class MyTrackersViewModel extends ChangeNotifier { resultSet2 = convertResultSetToString(event); print("----------Result Set 1----------: $resultSet1"); print("----------Result Set 2----------: $resultSet2"); - parseResultData(resultSet1, resultSet2); + parseResultData(); } } }); @@ -670,7 +686,7 @@ class MyTrackersViewModel extends ChangeNotifier { return value.length == 1 ? "0" + value : value; } - void parseResultData(String resultSet1, String resultSet2) { + void parseResultData() { List hexStringResSet1 = resultSet1.split(";"); List hexStringResSet2 = resultSet2.split(";"); @@ -710,17 +726,125 @@ class MyTrackersViewModel extends ChangeNotifier { return resSet; } -// String convertIntListToHex(List byteArray) { -// String b = (byteArray.map((x) { -// return x.toRadixString(16); -// })).join(";"); -// List hexString = b.split(";"); -// print("HexString: $hexString"); -// String returnString = hexString[2] + hexString[3]; -// print("Temp Hex String: $returnString"); -// final number = int.parse(returnString, radix: 16); -// print("Temp Number: ${number * 0.1}"); -// -// return (number * 0.1).toStringAsFixed(1); -// } + String currentTempInCelsius; + + updateCurrentTempInCelsius(var value) { + currentTempInCelsius = value; + notifyListeners(); + } + + Future connectAndesfitTemperatureDevice(BluetoothDevice device) async { + device.connectionState.listen((BluetoothConnectionState state) async { + if (state == BluetoothConnectionState.disconnected) { + isAndesfitDeviceConnected = false; + notifyListeners(); + } + if (state == BluetoothConnectionState.connected) { + isAndesfitDeviceConnected = true; + notifyListeners(); + bleDevicesStream.cancel(); + List services = await device.discoverServices(); + services.forEach((service) { + if (service.serviceUuid.toString().toLowerCase() == BLEUtils.TEMPERATURE_SERVICE) { + print(service.serviceUuid); + service.characteristics.forEach((characteristic) async { + if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.TEMPERATURE_CHARACTERISTIC) { + print(characteristic.characteristicUuid); + characteristic.onValueReceived.listen((event) { + print("onValueReceived Stream"); + print(event); + updateCurrentTempInCelsius(convertIntListToHex(event)); + String currentTempInFahrenheit = ((num.parse(currentTempInCelsius) * 1.8) + 32).toStringAsFixed(1); + String tempCurrentTempInCelsius = currentTempInCelsius + "\u2103" + " / " + currentTempInFahrenheit + "\u2109"; + updateCurrentTempInCelsius(tempCurrentTempInCelsius); + }); + await characteristic.setNotifyValue(true); + } + }); + return true; + } + }); + } + }); + await device.connect(timeout: Duration(seconds: 35)); + } + + String convertIntListToHex(List byteArray) { + String b = (byteArray.map((x) { + return x.toRadixString(16); + })).join(";"); + List hexString = b.split(";"); + print("HexString: $hexString"); + String returnString = hexString[2] + hexString[3]; + print("Temp Hex String: $returnString"); + final number = int.parse(returnString, radix: 16); + print("Temp Number: ${number * 0.1}"); + + return (number * 0.1).toStringAsFixed(1); + } + + StreamSubscription bloodSugarValuesStream; + + String currentBloodGlucose; + + updateCurrentBloodGlucose(var value) { + currentBloodGlucose = value; + notifyListeners(); + } + + bool isDataMeasured = false; + + Future connectAndesfitBloodSugarDevice(BluetoothDevice device) async { + device.connectionState.listen((BluetoothConnectionState state) async { + if (state == BluetoothConnectionState.disconnected) { + isAndesfitDeviceConnected = false; + notifyListeners(); + } + if (state == BluetoothConnectionState.connected) { + isAndesfitDeviceConnected = true; + notifyListeners(); + bleDevicesStream.cancel(); + List services = await device.discoverServices(); + services.forEach((service) { + if (service.serviceUuid.toString().toLowerCase() == BLEUtils.BLOOD_GLUCOSE_SERVICE) { + service.characteristics.forEach((characteristic) async { + if (characteristic.characteristicUuid.toString().toLowerCase() == BLEUtils.BLOOD_GLUCOSE_CHARACTERISTIC) { + print(characteristic.characteristicUuid); + bloodSugarValuesStream = characteristic.onValueReceived.listen((event) { + print("onValueReceived Stream"); + print(event); + if (!isDataMeasured) { + updateCurrentBloodGlucose(getBloodGlucoseMeasurements(event)[0]); + } + }); + await characteristic.setNotifyValue(true); + } + }); + return true; + } + }); + } + }); + await device.connect(timeout: Duration(seconds: 35)); + } + + List getBloodGlucoseMeasurements(List byteArray) { + List results = []; + + //[85, 6, 2, 0, 4, 99] + //[85, 12, 3, 23, 9, 12, 12, 25, 0, 75, 0, 2] + + if (byteArray.length == 6) { + int secsRemaining = 0; + secsRemaining = byteArray[4]; + results.add("Measuring: $secsRemaining"); + } else { + num measuredValue = byteArray[9]; + results.add("Measured: $measuredValue"); + isDataMeasured = true; + bloodSugarValuesStream.cancel(); + } + + return results; + } }