watch_integration
haroon amjad 1 month ago
parent fbe9cd9dff
commit a25df34f42

@ -8,7 +8,7 @@ import 'model/Vitals.dart';
enum Durations { enum Durations {
daily("daily"), daily("daily"),
weekly("weekly"), weekly("weekly"),
monthly("weekly"), monthly("monthly"),
halfYearly("halfYearly"), halfYearly("halfYearly"),
yearly("yearly"); yearly("yearly");
@ -47,6 +47,7 @@ class HealthDataTransformation {
} // Group by day } // Group by day
} else if (filterType == Durations.monthly.value) { } else if (filterType == Durations.monthly.value) {
if(isBetweenInclusive(parseDate, currentDate.subtract(Duration(days: 30)), DateTime.now())) { if(isBetweenInclusive(parseDate, currentDate.subtract(Duration(days: 30)), DateTime.now())) {
print("the value for the monthly filter is ${vital.value} with the timestamp ${vital.timestamp} and the current date is $currentDate and the parse date is $parseDate");
key = DateFormat('yyyy-MM-dd').format(DateTime.parse(vital.timestamp)); key = DateFormat('yyyy-MM-dd').format(DateTime.parse(vital.timestamp));
groupedData.putIfAbsent(key, () => []).add(vital); groupedData.putIfAbsent(key, () => []).add(vital);
@ -67,8 +68,13 @@ class HealthDataTransformation {
groupedData.forEach((key, values) { groupedData.forEach((key, values) {
double sum = values.fold(0, (acc, v) => acc + num.parse(v.value)); double sum = values.fold(0, (acc, v) => acc + num.parse(v.value));
double mean = sum / values.length; double mean = sum / values.length;
if(selectedSection == "bodyOxygen" || selectedSection == "bodyTemperature") {
mean = sum / values.length;
}else {
mean = sum;
}
double finalValue = filterType == 'weekly' ? mean : sum; double finalValue = mean;
print("the final value is $finalValue for the key $key with the original values ${values.map((v) => v.value).toList()} and uom is ${values.first.unitOfMeasure}"); print("the final value is $finalValue for the key $key with the original values ${values.map((v) => v.value).toList()} and uom is ${values.first.unitOfMeasure}");
dataPoints.add(DataPoint( dataPoints.add(DataPoint(
value: smartScale(finalValue), value: smartScale(finalValue),

@ -125,12 +125,10 @@ class HealthProvider with ChangeNotifier {
if (result.isError) { if (result.isError) {
error = 'Error initializing device: ${result.asError}'; error = 'Error initializing device: ${result.asError}';
} else { } else {
LoaderBottomSheet.hideLoader();
LoaderBottomSheet.showLoader(); LoaderBottomSheet.showLoader();
await getVitals(); await getVitals();
LoaderBottomSheet.hideLoader(); // LoaderBottomSheet.hideLoader();
await Future.delayed(Duration(seconds: 5)); // await Future.delayed(Duration(seconds: 5));
getIt.get<NavigationService>().pushPage(page: SmartWatchActivity()); getIt.get<NavigationService>().pushPage(page: SmartWatchActivity());
print('Device initialized successfully'); print('Device initialized successfully');
} }
@ -162,7 +160,7 @@ class HealthProvider with ChangeNotifier {
break; break;
case Durations.weekly: case Durations.weekly:
if (weekly.isNotEmpty) { if (weekly.isNotEmpty) {
selectedData = daily; selectedData = weekly;
break; break;
} }
selectedData = weekly = healthDataTransformation.transformVitalsToDataPoints(vitals!, Durations.weekly.value, selectedSection); selectedData = weekly = healthDataTransformation.transformVitalsToDataPoints(vitals!, Durations.weekly.value, selectedSection);

@ -189,7 +189,6 @@ class HealthService {
return null; return null;
} }
try { try {
await watchHelper!.getActivity();
await watchHelper!.getHeartRate(); await watchHelper!.getHeartRate();
await watchHelper!.getSleep(); await watchHelper!.getSleep();
await watchHelper!.getSteps(); await watchHelper!.getSteps();

@ -16,6 +16,11 @@ class Vitals {
unitOfMeasure: map['uom'] ?? "", unitOfMeasure: map['uom'] ?? "",
); );
} }
toString(){
return "{\"value\": \"$value\", \"timeStamp\": \"$timestamp\", \"uom\": \"$unitOfMeasure\"}";
}
} }
class VitalsWRTType { class VitalsWRTType {
@ -47,7 +52,6 @@ class VitalsWRTType {
map["activity"].forEach((element) { map["activity"].forEach((element) {
element["uom"] = "Kcal"; element["uom"] = "Kcal";
var data = Vitals.fromMap(element); var data = Vitals.fromMap(element);
// data.value = (double.parse(data.value)/1000).toStringAsFixed(2);
activity.add(data); activity.add(data);
}); });
map["steps"].forEach((element) { map["steps"].forEach((element) {
@ -70,11 +74,6 @@ class VitalsWRTType {
bodyOxygen.add(Vitals.fromMap(element)); bodyOxygen.add(Vitals.fromMap(element));
}); });
map["distance"].forEach((element) {
element["uom"] = "m";
bodyOxygen.add(Vitals.fromMap(element));
});
map["bodyTemperature"].forEach((element) { map["bodyTemperature"].forEach((element) {
element["uom"] = "C"; element["uom"] = "C";
bodyTemperature.add(Vitals.fromMap(element)); bodyTemperature.add(Vitals.fromMap(element));

@ -11,6 +11,7 @@ class HealthConnectHelper extends WatchHelper {
final Health health = Health(); final Health health = Health();
final List<HealthDataType> _healthPermissions = [ final List<HealthDataType> _healthPermissions = [
HealthDataType.ACTIVE_ENERGY_BURNED,
HealthDataType.HEART_RATE, HealthDataType.HEART_RATE,
HealthDataType.STEPS, HealthDataType.STEPS,
HealthDataType.BLOOD_OXYGEN, HealthDataType.BLOOD_OXYGEN,
@ -24,10 +25,11 @@ class HealthConnectHelper extends WatchHelper {
@override @override
FutureOr<void> getHeartRate() async { FutureOr<void> getHeartRate() async {
try { try {
final types = [HealthDataType.HEART_RATE]; final types = HealthDataType.HEART_RATE;
final endDate = DateTime.now(); final endDate = DateTime.now();
// final startDate = endDate.subtract(Duration(days: 365));
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getHeartData(startDate, endDate, types);
addDataToMap("heartRate",data ); addDataToMap("heartRate",data );
} catch (e) { } catch (e) {
print('Error getting heart rate: $e'); print('Error getting heart rate: $e');
@ -37,7 +39,7 @@ class HealthConnectHelper extends WatchHelper {
@override @override
FutureOr<void> getSleep() async { FutureOr<void> getSleep() async {
try { try {
final types = [HealthDataType.SLEEP_IN_BED]; final types = HealthDataType.SLEEP_IN_BED;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
@ -50,7 +52,7 @@ class HealthConnectHelper extends WatchHelper {
@override @override
FutureOr<void> getSteps() async { FutureOr<void> getSteps() async {
try { try {
final types = [HealthDataType.STEPS]; final types = HealthDataType.STEPS;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
@ -64,7 +66,7 @@ class HealthConnectHelper extends WatchHelper {
@override @override
Future<void> getActivity() async { Future<void> getActivity() async {
try { try {
final types = [HealthDataType.ACTIVE_ENERGY_BURNED]; final types = HealthDataType.ACTIVE_ENERGY_BURNED;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
@ -77,17 +79,17 @@ class HealthConnectHelper extends WatchHelper {
@override @override
Future<dynamic> retrieveData() async { Future<dynamic> retrieveData() async {
return mappedData; return Result.value(getMappedData());
} }
@override @override
Future<dynamic> getBloodOxygen() async { Future<dynamic> getBloodOxygen() async {
try { try {
final types = [HealthDataType.BLOOD_OXYGEN]; final types = HealthDataType.BLOOD_OXYGEN;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
addDataToMap("bloodOxygen",data ); addDataToMapBloodOxygen("bloodOxygen", data);
} catch (e) { } catch (e) {
print('Error getting blood oxygen: $e'); print('Error getting blood oxygen: $e');
} }
@ -96,7 +98,7 @@ class HealthConnectHelper extends WatchHelper {
@override @override
Future<dynamic> getBodyTemperature() async { Future<dynamic> getBodyTemperature() async {
try { try {
final types = [HealthDataType.BODY_TEMPERATURE]; final types = HealthDataType.BODY_TEMPERATURE;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
@ -109,7 +111,7 @@ class HealthConnectHelper extends WatchHelper {
@override @override
FutureOr<void> getDistance() async { FutureOr<void> getDistance() async {
try { try {
final types = [HealthDataType.DISTANCE_WALKING_RUNNING]; final types = HealthDataType.DISTANCE_WALKING_RUNNING;
final endDate = DateTime.now(); final endDate = DateTime.now();
final startDate = endDate.subtract(Duration(days: 365)); final startDate = endDate.subtract(Duration(days: 365));
final data = await getData(startDate, endDate, types); final data = await getData(startDate, endDate, types);
@ -141,7 +143,8 @@ class HealthConnectHelper extends WatchHelper {
startDate: startTime, startDate: startTime,
endDate: endTime, endDate: endTime,
types: [type], types: [type],
interval: 86400, // interval: 86400,
interval: 3600,
); );
} }
@ -150,9 +153,9 @@ class HealthConnectHelper extends WatchHelper {
for (var point in data) { for (var point in data) {
if (point.value is NumericHealthValue) { if (point.value is NumericHealthValue) {
final numericValue = (point.value as NumericHealthValue).numericValue; final numericValue = (point.value as NumericHealthValue).numericValue;
point.value = NumericHealthValue( // point.value = NumericHealthValue(
numericValue: numericValue * 100, // numericValue: numericValue * 100,
); // );
Vitals vitals = Vitals( Vitals vitals = Vitals(
value: (point.value as NumericHealthValue).numericValue.toStringAsFixed(2), value: (point.value as NumericHealthValue).numericValue.toStringAsFixed(2),
timestamp: point.dateFrom.toString() timestamp: point.dateFrom.toString()
@ -161,4 +164,30 @@ class HealthConnectHelper extends WatchHelper {
} }
} }
} }
void addDataToMapBloodOxygen(String s, data) {
mappedData[s] = [];
for (var point in data) {
if (point.value is NumericHealthValue) {
final numericValue = (point.value as NumericHealthValue).numericValue;
point.value = NumericHealthValue(
numericValue: numericValue * 100,
);
Vitals vitals = Vitals(value: (point.value as NumericHealthValue).numericValue.toStringAsFixed(2), timestamp: point.dateFrom.toString());
mappedData[s]?.add(vitals);
}
}
}
getMappedData() {
return " { \"heartRate\": ${mappedData["heartRate"] ?? []}, \"sleep\": ${mappedData["sleep"] ?? []}, \"steps\": ${mappedData["steps"] ?? []}, \"activity\": ${mappedData["activity"] ?? []}, \"bloodOxygen\": ${mappedData["bloodOxygen"] ?? []}, \"bodyTemperature\": ${mappedData["bodyTemperature"] ?? []}, \"distance\": ${mappedData["distance"] ?? []} }";
}
getHeartData(DateTime startDate, DateTime endDate, HealthDataType types) async {
return await health.getHealthDataFromTypes(
startTime: startDate,
endTime: endDate,
types: [types],
);
}
} }

@ -125,6 +125,7 @@ class _ActivityDetailsState extends State<ActivityDetails> {
return Row( return Row(
crossAxisAlignment: CrossAxisAlignment.baseline, crossAxisAlignment: CrossAxisAlignment.baseline,
textBaseline: TextBaseline.alphabetic, textBaseline: TextBaseline.alphabetic,
spacing: 4.w,
children: [ children: [
(averageAsDouble?.toStringAsFixed(2) ?? averageAsString ?? "N/A").toText24(color: AppColors.textGreenColor, fontWeight: FontWeight.w600), (averageAsDouble?.toStringAsFixed(2) ?? averageAsString ?? "N/A").toText24(color: AppColors.textGreenColor, fontWeight: FontWeight.w600),
Visibility( Visibility(
@ -246,7 +247,7 @@ class _ActivityDetailsState extends State<ActivityDetails> {
height: 300.h, height: 300.h,
maxY: 150, maxY: 150,
barColor: AppColors.bgGreenColor, barColor: AppColors.bgGreenColor,
barWidth: context.read<HealthProvider>().selectedData.values.toList().first.length < 10 ? 26.w : 20.w, barWidth: getBarWidth(),
barRadius: BorderRadius.circular(8), barRadius: BorderRadius.circular(8),
bottomLabelColor: Colors.black, bottomLabelColor: Colors.black,
bottomLabelSize: 12, bottomLabelSize: 12,
@ -339,4 +340,20 @@ class _ActivityDetailsState extends State<ActivityDetails> {
static String getMonthName(DateTime date) { static String getMonthName(DateTime date) {
return DateUtil.getMonthDayAsOfLang(date.month); return DateUtil.getMonthDayAsOfLang(date.month);
} }
double getBarWidth() {
var duration = context.read<HealthProvider>().selectedDuration;
switch(duration){
case durations.Durations.daily:
return 26.w;
case durations.Durations.weekly:
return 26.w;
case durations.Durations.monthly:
return 6.w;
case durations.Durations.halfYearly:
return 26.w;
case durations.Durations.yearly:
return 18.w;
}
}
} }

@ -31,7 +31,7 @@ class SmartWatchActivity extends StatelessWidget {
description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation, description: "Activity rings give you a quick visual reference of how active you are each day. ".needTranslation,
trailingIcon: AppAssets.watchActivityTrailing, trailingIcon: AppAssets.watchActivityTrailing,
result: context.read<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.activity??[]), result: context.read<HealthProvider>().sumOfNonEmptyData(context.read<HealthProvider>().vitals?.activity??[]),
unitsOfMeasure: "Cal" unitsOfMeasure: "Kcal"
).onPress((){ ).onPress((){
// Map<String, List<Vitals>> getVitals() { // Map<String, List<Vitals>> getVitals() {
// return { // return {
@ -48,7 +48,7 @@ class SmartWatchActivity extends StatelessWidget {
context.read<HealthProvider>().deleteDataIfSectionIsDifferent("activity"); context.read<HealthProvider>().deleteDataIfSectionIsDifferent("activity");
context.read<HealthProvider>().saveSelectedSection("activity"); context.read<HealthProvider>().saveSelectedSection("activity");
context.read<HealthProvider>().fetchData(); context.read<HealthProvider>().fetchData();
context.read<HealthProvider>().navigateToDetails("activity", sectionName:"Activity Calories", uom: "cal"); context.read<HealthProvider>().navigateToDetails("activity", sectionName:"Activity Calories", uom: "Kcal");
}), }),
resultItem( resultItem(

@ -57,7 +57,7 @@ class _SplashScreenState extends State<SplashPage> {
await notificationService.initialize(onNotificationClick: (payload) { await notificationService.initialize(onNotificationClick: (payload) {
// Handle notification click here // Handle notification click here
}); });
ZoomService().initializeZoomSDK(); // ZoomService().initializeZoomSDK();
if (isAppOpenedFromCall) { if (isAppOpenedFromCall) {
navigateToTeleConsult(); navigateToTeleConsult();
} else { } else {

Loading…
Cancel
Save