Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/calories/ChangeLog
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
0.01: Initial app based on #4092
0.02: Adjust formula slightly and fix overestimated active calories by scaling based on max HR (#4286)
3 changes: 2 additions & 1 deletion apps/calories/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ The app uses the algorithm below:
**Not Set (avg):** `(-37.7495+(0.5390 x Heart Rate)+(0.0362 x Weight)+(0.1375 x Age))/4.184`

4. Blends the two according to the steps taken (Higher steps per min --> steps weighted more due to potential HRM inaccuracy)
5. Returns the total calories burned in that interval, active calories (calories actively burned), and BMR calories (calories passively burned)
5. Uses Max HRM to interpolate between how much it should weight active calories (avoids overestimates)
6. Returns the total calories burned in that interval, active calories (calories actively burned), and BMR calories (calories passively burned)

## Clock Info
This app adds a set of ClockInfos in the `Health` list:
Expand Down
43 changes: 22 additions & 21 deletions apps/calories/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ exports.calcBMR = function (myProfile) {
}
return bmr / 1440;
};

// Main formula for calculating calories. Takes health data with duration in minutes, and a myprofile data set.
exports.calcCalories = function (healthData, myProfile) {
if (!healthData || !healthData.duration) return;
Expand Down Expand Up @@ -123,13 +124,16 @@ exports.calcCalories = function (healthData, myProfile) {
print("Invalid or missing heart rate data");
return;
}


const lerp = (x, min, max) => Math.min(Math.max((x - min) / (max - min), 0), 1);

let ageMultiplier = 1.0;

let activeCaloriesCoefficient=lerp(hr, myProfile.maxHrm*0.5, myProfile.maxHrm*0.6) // use hr extertion level between 50% and 60% of max HR to determine active calories.
print("lerp: "+activeCaloriesCoefficient)
Comment thread
RKBoss6 marked this conversation as resolved.
Outdated

let stepsMet =
(stepsPerMin < 5 ? 1.0 : 2.0 + 0.05 * stepsPerMin) * ageMultiplier; // More realistic scaling with age adjustment

// calculate calories using current HR (not HRR - that was causing inflation)
// calculate calories using current HR
if (myProfile.gender != undefined && myProfile.gender != 2 /*not set*/) {
if (myProfile.gender == 0) {
//male
Expand All @@ -145,37 +149,34 @@ exports.calcCalories = function (healthData, myProfile) {
hrKcalMin =
(-37.7495 + 0.539 * hr + 0.0362 * weight + 0.1375 * age) / 4.184;
}

// extract active portion (subtract BMR)
hrKcalMin = Math.max(0, hrKcalMin - bmr); // formula adds BMR by default

hrKcalMin = Math.max(0, hrKcalMin - bmr) * activeCaloriesCoefficient;
print("hrcal: "+hrKcalMin)
let stepsKcalMin = (stepsMet * 3.5 * weight) / 200;
print("stepsCal: "+stepsKcalMin)
// blend METs
let finalActiveKcalMin = 0;
if (stepsPerMin > 120) {
print("stepsPerMin: "+stepsPerMin)
if (stepsPerMin > 180) {
// strenuous activity
finalActiveKcalMin = hrKcalMin * 0.8 + stepsKcalMin * 0.2;
} else if (stepsPerMin >= 10) {
// moderate activity
finalActiveKcalMin = hrKcalMin * 0.5 + stepsKcalMin * 0.5;
} else if (stepsPerMin >= 60) {
// moderate activity
finalActiveKcalMin = hrKcalMin * 0.8 + stepsKcalMin * 0.2;
} else {
// sedentary or non-step activity (weights)
// For elderly, don't penalize as much - might be resistance training
if (age > 65) {
finalActiveKcalMin = hrKcalMin * 0.8;
} else {
finalActiveKcalMin = hrKcalMin;
}
finalActiveKcalMin = hrKcalMin*0.96+stepsKcalMin * 0.04;
}

// ensure non-negative
finalActiveKcalMin = Math.max(0, finalActiveKcalMin);

// final Outputs
let activeTotal = finalActiveKcalMin * healthData.duration;
print("finalActive: "+activeTotal)
// boot.js adds bmr separately
return {
activeCalories: Math.round(Math.max(0, activeTotal)),
bmrCalories: Math.round(bmr * healthData.duration)
};
};
};
2 changes: 1 addition & 1 deletion apps/calories/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "Calorie Tracker (BETA)",
"shortName":"Calories",
"icon": "icon.png",
"version":"0.01",
"version":"0.02",
"description": "A health-integrated calorie tracker using `MyProfile`. Currently in Beta Testing - see README for more details.",
"type":"app",
"tags": "health,clkinfo",
Expand Down
Loading