04-22-2018 04:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-22-2018 04:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Every clockface I create seems to be a major battery drain compared to fitbit stats clockface. Here's simple code where I'm just displaying battery, time, date. It uses about 5% battery/hour, whereas stats is only about 1%/hour.
Is there a trick to making it more efficient? I'm only updating time by minutes and other every 5 seconds.
BTW, should my variables be defined as "const", "let", or "var"? I've seen both in fitbit examples and they seem to work the same.
import clock from "clock"; import document from "document"; import { preferences } from "user-settings"; import * as util from "../common/utils"; import { today } from "user-activity"; import { battery } from "power"; //import userSettings from "user-settings"; //import { display } from "display"; //import { vibration } from "haptics"; //import { user } from "user-profile"; // Update the clock every minute clock.granularity = "minutes"; // Get a handle on the <text> element const batteryLabel = document.getElementById("batteryLabel"); const dateLabel = document.getElementById("dateLabel"); const timeLabel = document.getElementById("timeLabel"); // why "const" instead of "let" or "var"? const stepsLabel = document.getElementById("stepsLabel"); //----------------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------------- function updateActivity() { batteryLabel.text = Math.floor(battery.chargeLevel) + "%"; var stepsToday = today.local.steps || 0; stepsLabel.text = stepsToday; } //----------------------------------------------------------------------------------------- // Update the <text> element every tick with the current time //----------------------------------------------------------------------------------------- clock.ontick = (evt) => { let todayDate = evt.date; let todayDate = new Date(); let hours = todayDate.getHours(); let ampm = hours >= 12 ? 'PM' : 'AM' let mins = util.zeroPad(todayDate.getMinutes()); if (preferences.clockDisplay === "12h") { // 12h format hours = (hours % 12 || 12); // the hour '0' should be '12' } else { // 24h format hours = util.zeroPad(hours); } let monthNames = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]; let weekdays = [ "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ]; let weekdate = todayDate.getDate(); let weekindex = todayDate.getDay(); let monthIndex = todayDate.getMonth(); timeLabel.text = `${hours}:${mins}`; dateLabel.text = `${weekdays[weekindex]}` + ` ${monthNames[monthIndex]} ${weekdate}` + ` ${ampm}`; } //----------------------------------------------------------------------------------------- setInterval(updateActivity,5000); updateActivity(); // display activity at start
Answered! Go to the Best Answer.

Accepted Solutions
04-26-2018 09:30 - edited 04-27-2018 06:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-26-2018 09:30 - edited 04-27-2018 06:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@JonFitbit, My versa keeps locking up using your code. So, I've gone back to my simpler code and it's working to my satisfaction. It may not be optimized but it doesn't lock up my versa and it only burns about 1% per hour. Below is the relevant portions of the code.
function updateClock() { // get current time
let todayDate = new Date();
// do more clock functions
}
function updateHr() { hrm.start(); }
hrm.onreading = function() { // get current heart rate
if (!display.on) return; // do nothing if display is not on
hrmTest = hrm.heartRate;
// do more heart rate display stuff
hrm.stop();
}
function updateActivity() {
if (display.on) {
// do activity display stuff
}
}
clock.granularity = "minutes";
setInterval(updateActivity,1500); setInterval(updateHr,2000); clock.ontick = () => updateClock(); if (display.on) { // display activity at start updateClock(); hrm.start(); updateActivity(); updateHr(); }

04-22-2018 13:35 - edited 04-22-2018 13:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


04-22-2018 13:35 - edited 04-22-2018 13:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I don't know, but I wonder whether the setInterval() could be hurting you. An alternative approach would be to call updateActivity() from within clock.ontick() every fifth time, after changing granularity to seconds. It this helps, we'll know that setInterval() isn't implemented very well!
Another general idea is to only do once the things that only need doing once. For example, you're defining several constants in onTick() every time it's executed. While this makes for nice tight scoping of the variables, it wastes CPU time.
Gondwana Software
04-22-2018 15:59
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-22-2018 15:59
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Ok, I removed the setinterval and called updateActivity() at end of the ontick. That fixed it. ontick is only every minute in my code so it should be efficient! I'll move the variables outside of the functions next. Then I'll see if it'll work efficiently with seconds ontick like the fitbit stats clockface.
Thanks for the suggestions, @Gondwana!

04-23-2018 07:19
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-23-2018 07:19
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I moved most of the variable declarations out of the functions.That didn't seem to make much difference but seems like a good strategy.
I moved updateActivities() back into setInterval call for 30 seconds (30000 ms) and that seems to work comparably to the onTick() every minute. So setInterval() is not the problem. Whether I do onTick() by seconds and call updateActivities() every 5 or just use setInterval() with 5 seconds (5000 ms) it takes similar battery.
So I've made the clock semi-useful by limiting it to 30 second updates. The fitbit stats updates time in seconds; steps, calories and heart rate every few seconds at most and takes little battery.

04-23-2018 09:48 - edited 04-23-2018 09:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-23-2018 09:48 - edited 04-23-2018 09:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey there,
is it the clock event draining the battery, or is it the fact, that you update the display even if the display is off?
Try adding
if (display.on) { }
around your code and see if it helps.
You will need to add this to your imports too:
import { display } from "display";
I made a (geeky Dr Who) "Gallifreyan Clock" that rotates three circles and adds lines for seconds every second and it does not seem to drain my battery at all, I think because I added the code for "display.on". It's good practice to only update the display when it is actually on, since it is usually not (at least not on my FitBit Ionic).
I hope that helps you onwards a bit.. 🙂
Cheers,
JDT

04-23-2018 10:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-23-2018 10:15
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I will try the if (display.on). But, I thought the clock doesn't even run unless the display is on. Different for apps.

04-23-2018 10:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-23-2018 10:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I stand corrected. I just tried it out and you are right, it seems not to tick when the display is off.
So that can't be it then.. weird stuff.. if your clock only ticks when you have the display on, and you only have the display on when you turn it on (and it turns of in 10-20 seconds after that), then it doesn't really explain why the battery would go down faster than normal.

04-23-2018 14:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-23-2018 14:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I'm really confused. I added the display.on condition and it seems to help. I added a counter and console.log and it kept counting and printing to the log unless I added the display.on condition. And yet when I want it to save info when display is off, it won't because it stopped running when the display was off.
I suspect there's a bug. I think it's supposed to stop when the display is off but sometimes it doesn't so it's good practice to add the display.on condition.

04-24-2018 08:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


04-24-2018 08:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Here's an example of using setInterval to do something every second, only when the screen is on, using the Display API to start/stop the interval.
import { display } from "display";
let myTimer = {
watchID: null,
start: function() {
if (!this.watchID) {
this.watchID = setInterval(this.doInterval.bind(this), 1000);
}
},
stop: function() {
clearInterval(this.watchID);
this.watchID = null;
},
doInterval: function() {
// DO SOMETHING HERE
},
wake: function() {
this.doInterval();
this.start();
}
}
myTimer.start();
display.onchange = function() {
if (display.on) {
myTimer.wake();
} else {
myTimer.stop();
}
}

04-25-2018 06:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-25-2018 06:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@JonFitbit- Thanks for the code but that's far too complicated for me. I might try it on a simple clockface to understand it.
In the meantime, what I did which seems to resolve my issue:
function updateActivity() {
if (!display.on) return;
// do stuff
}
setInterval(updateActivity,1500);

04-25-2018 06:37
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


04-25-2018 06:37
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Unfortunately, your setInterval(updateActivity,1500); is going to keep the CPU running and drain the battery.
In my example code, you just need to put your updateActivity call where it says:
// DO SOMETHING HERE

04-25-2018 06:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-25-2018 06:50
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Ok, I pasted that in and it seems to be working. I'll test the battery drain over the next few hours.
BTW, is there a way to get CPU info or something directly so I can make instantaneous battery comparisons with code?

04-25-2018 06:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-25-2018 06:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Do console.log() calls take cpu or cause any problems when disconnected from the server? I'd prefer to leave them in for debugging.

04-26-2018 09:30 - edited 04-27-2018 06:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

04-26-2018 09:30 - edited 04-27-2018 06:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
@JonFitbit, My versa keeps locking up using your code. So, I've gone back to my simpler code and it's working to my satisfaction. It may not be optimized but it doesn't lock up my versa and it only burns about 1% per hour. Below is the relevant portions of the code.
function updateClock() { // get current time
let todayDate = new Date();
// do more clock functions
}
function updateHr() { hrm.start(); }
hrm.onreading = function() { // get current heart rate
if (!display.on) return; // do nothing if display is not on
hrmTest = hrm.heartRate;
// do more heart rate display stuff
hrm.stop();
}
function updateActivity() {
if (display.on) {
// do activity display stuff
}
}
clock.granularity = "minutes";
setInterval(updateActivity,1500); setInterval(updateHr,2000); clock.ontick = () => updateClock(); if (display.on) { // display activity at start updateClock(); hrm.start(); updateActivity(); updateHr(); }

