Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Current hour's steps

ANSWERED

I've seen a couple of posts from a few months ago asking if there was a way to get the 250 steps/hour value.  Is that still not available in the device API, and would the only way to get access to it to register a web app and get the intraday data from the web api?

 

What I'm basically trying to do is replicate my old Charge HR2's readings onto a single watch face for my Versa (HR, total steps, calories, floors, active minutes, and steps for the current hour).  That is the last piece I'm missing.

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

It's not available, but as you're doing a clock face you can just capture the hourly value yourself. You won't have data for the first hour, but if you persist the offset value, you should be ok to calculate it.

 

Something like this:

 

 

let stepsThisHour = 0;
let stepsOffset = today.adjusted.steps;

clock.ontick = evt => { let d = evt.date;

if (d.getMinutes() === 0) {
// Reset step count each hour
stepsThisHour = 0;
}

// Calculate steps since the hour
stepsThisHour = today.adjusted.steps - stepsOffset;
}

 

View best answer in original post

Best Answer
20 REPLIES 20

It's not available, but as you're doing a clock face you can just capture the hourly value yourself. You won't have data for the first hour, but if you persist the offset value, you should be ok to calculate it.

 

Something like this:

 

 

let stepsThisHour = 0;
let stepsOffset = today.adjusted.steps;

clock.ontick = evt => { let d = evt.date;

if (d.getMinutes() === 0) {
// Reset step count each hour
stepsThisHour = 0;
}

// Calculate steps since the hour
stepsThisHour = today.adjusted.steps - stepsOffset;
}

 

Best Answer

Awesome.  I'll give that a try.

Best Answer
0 Votes

I'm still trying to get my head around the whole life cycle of a clock face, but doesn't this solution have a problem if the clock face had been unloaded (and therefore not running) when the hour changes?  In other words, if the clock face was unloaded for some reason at xx:59 and was reloaded at xx:03, then the test for minutes === 0 would never succeed.

 

If this is correct, would a better approach  be to record the hour when the step count was reset and then compare that number to the current hour?  Of course the hour value must be persisted across unload/load events.

 

Or am I missing something?

 

Thanks,


John

Best Answer
0 Votes

@Drifty26I agree. I've had to do that sort of thing in a few clockfaces.

Peter McLennan
Gondwana Software
Best Answer
0 Votes

 


If this is correct, would a better approach  be to record the hour when the step count was reset and then compare that number to the current hour?  Of course the hour value must be persisted across unload/load events.

I probably wasn't clear, I said to persist the offset and the offset contains the current step count when minutes are 0.

Best Answer
0 Votes

Sorry for being thick but am I missing something in the code, or something becauseI have NO idea what that means.

 

Best Answer
0 Votes

JonFitbit:

 

I understand persisting the offset, but I don't see why that will work 100% of the time based on a check of minutes being 0.

 

Is this correct:  if the app is unloaded when the hour changes, then the code will never run when the minutes are 0 for that hour, and so the app will miss an hour transition.

 

Thanks,

 

John

Best Answer
0 Votes

I think you'd need to keep track of the last relevant Date (or equivalent). Then, every clock.ontick(), calculate how much time has passed since that Date.

 

It will be hard to work out how to handle values greater than one hour, because your clockface won't get direct visibility of when steps were taken while it wasn't running. You could try to fill this gap by using the Web API on a companion device, but this adds a lot of complexity and won't always work (eg, because no syncing).

Peter McLennan
Gondwana Software
Best Answer
0 Votes

Here's what I don't get:

If I initialize the stepsThisHour to 0, and the offset to today.adjusted.steps when the hour changes, otherwise, set the stepsThisHour to today.adjusted.steps - offset, why am I sometimes getting 250 as my displayed value when the hour changes? I added the hour as part of the text so that I could confirm the code was at least running when I expected it to.  That changes as expected.  It's the step counter that is sometimes not updating.

 

All of the below code is running inside clock.ontick, with the granularity as "seconds". 

 

if (t.getMinutes() === 0 && t.getSeconds() === 0) {
    stepsThisHour = 0; // Reset step count each hour 
    stepsOffset = today.adjusted.steps; //Reset the offset each hour to match total steps
    myHrSteps.text = `${hours}:${stepsThisHour}`; //set the text on the watch face
} else {
    stepsThisHour = today.adjusted.steps - stepsOffset; //Calculate the steps

    if (stepsThisHour >= 250) {
        stepsThisHour = 250; //I don't care about the count once I hit 250
    } else if (stepsThisHour < 0) {
        stepsThisHour = 0; //for some reason, first thing in the morning, it's a negative number
    }
myHrSteps.text = `${hours}:${stepsThisHour}`; //set the text on the watch face }
Best Answer
0 Votes

I've seen similar behavior right after midnight.  It seems like my code for the hour change is run before the daily step total has been reset to 0 by the watch.  Perhaps a race condition.

 

It looks like a bug in the watch to me, but it is hard to duplicate since I've only seen it just after midnight.

 

FYI, please see the feature suggestion at https://community.fitbit.com/t5/Feature-Suggestions/Enable-developing-clock-faces-that-support-Remin... and vote for it if appropriate.

 

John

Best Answer
0 Votes

I have used this code, but my stepsPerHour are always to high.

Are we not missing an update of the OFFSET during every tick-event?

Otherwise stepsOffset has just one value (at initial clock-face-installation-run) which then stays the same. When stepsThisHour gets reset to zero, it immediately get's re-updated by:

today.adjusted.steps - stepsOffset,

which will be the same same value, as just before setting the stepsPerHour back to zero.

In the slightly modified version below the stepsPerHour gets it's value from the re-update of:

today.adjusted.steps - stepsOffset

 

let stepsThisHour = 0;
let stepsOffset = today.adjusted.steps;

clock.ontick = evt => { let d = evt.date;

if (d.getMinutes() === 0) {
// Reset step count each hour
// stepsThisHour = 0; // <- IS COMMENTED OUT
stepsOffset = today.adjusted.steps; // <- THIS LINE IS NEW
}

// Calculate steps since the hour
stepsThisHour = today.adjusted.steps - stepsOffset;
}

Note: if tick-event is set to a granularity of "seconds",  stepsPerHour is set to zero, every second of the first minute on every hour. Meaning the first minute on every hour will not be counted.

 

Problem I encountered in the fitbit-studio simulation: Not always but sometimes the (new Date()).getMinutes() seems to be skipped by the tick-event. And then the update just does not happen for that hour (leading to stepsPerHour being to high for that hour)

 

Please let me know if I got this all wrong.

Best Answer
0 Votes

I'm not sure if this addresses your question, but I don't believe that checking for minutes === 0 is a good idea since the clock face may not be running at the hour change (the user could be looking at the Today app, checking the weather, etc).  If that happens your code will not recognize the hour change.

 

Instead I recommend that you remember the previous hour and check if the current hour is |= to the previous hour.  Note - don't check if the current hour > previous hour since that will fail at midnight.

 

Also, don't forget to persist the information when the clock face is unloaded and restore it on reload.

 

John

Best Answer
0 Votes

@Drifty26 Thanks for the reply. It does not exactly address the question about which binding should updated 😉

BUT you seem to have a very valid point regarding the WHEN to update it. Highly appreciated. I will definitely change that in my next update.

Best Answer
0 Votes

So I have code that works well, however, it fails to update my offset at the hour when my watchface is off.

 

Has anyone figured out how to get this or something happen on the hour without the face/display on?

I would like this to happen on the hour, even with the face off.

stepsOffset = today.adjusted.steps;

 

I know it can be figured out, because if I can see my hourly steps by swiping up and scrolling down to steps this hour. Would be nice if I could just pull this directly. 

Best Answer
0 Votes

You need to use something like SetInterval to get your code to run on a regular basis, even when the display is turned off.  In my Move It! clock face I run the interval every 5 seconds (5000 milliseconds).  Be careful what you do in the event handlers or it is easy to kill you battery.   I get 5 days out of mine.

 

Also, note as mentioned above that if the clock is unloaded then even the SetInterval handler won't run all of the time.  So you can't count on your code running at the top of every hour and you must handle this case.

 

John

Best Answer
0 Votes

I set a timeout for the beginning of the next hour, when it will update the step count offset. Timeouts happen even when the watch face is not active. Doing it only on the next hour saves a little on the battery.

 

let tday = new Date();
let mins = tday.getMinutes();
let secs = tday.getSeconds();

let secondsToNextHour = ((60 - mins) * 60) - secs;

setTimeout(updateHourlySteps, secondsToNextHour * 1000);

Best Answer

Would it theoretically be possible for a developer to contribute to the fitbit OS, adressing this issue?

What I mean is:

Could one file an issue/pull request that makes the "steps per hour" available to the clock-face api?

(As available as the totalsteps, not through an http-call to the web-api)

Or is this part of the OS just not openly available in any repository?

 

If it is something that could be edited:

At which repo and in which directory should one start to look at?

Best Answer
0 Votes

I have similar question.  How do I know what hours to check for the 250 goal.  Users can configure these hours on the FitBit app.  I would like to read those parameters and control which hours I could/remind them to move.

Good customer service is solving the customer's problem. Great customer service is making sure it never happens again.
Best Answer
0 Votes

Below is how I implemented JakeScott's solution in SDK 5.0 on my Versa 3 and it is working great. Upon loading the clockface, it runs a function to sets the "stepLastHr" variable; this function then fires off a function to set the timeout to run the function again on the next hour. So, each time the function sets the "stepLastHr" variable, it also sets itself to run again on the next hour, ad infinitum.

 

import { today } from "user-activity";

var stepLastHr = 0;
updateStepHr();

function updateStepHr() {
  let stepsValue = today.adjusted.steps;
  stepLastHr = stepsValue;
  timerStepHr();
}

function timerStepHr() {
  let tday = new Date();
  let mins = tday.getMinutes();
  let secs = tday.getSeconds();
  let secondsToNextHour = ((60 - mins) * 60) - secs;
  setTimeout(updateStepHr, secondsToNextHour * 1000);
}

 

Best Answer