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

New to Java ( Struggling to updates Stats on tick)

ANSWERED

Hi All, for some crazy reasons, I had recently decided I was going to try and teach my self Java and as I had a Versa I thought designing a clock face was a good place to start. After a few days, I had successfully managed to create and run a clock face on my Versa, but there was an issue that the steps and calories were not updating unless I manually did it. Looking around I have found that I can add the below text to my Java and this should solve the problem: 

 

clock.addEventListener("tick", updateStats);

 

But for the life of me, I can't find the correct place to place it in my code as it's just removing the stats from my clockface.

 

Here is my current code: 

 

import clock from "clock";
import document from "document";
import { preferences } from "user-settings";
import * as util from "../common/utils";
import { HeartRateSensor } from "heart-rate";
import { battery } from "power";
import userActivity from "user-activity"; 


// Update the clock every minute
clock.granularity = "seconds";


// Get a handle on the <text> element
const myLabel = document.getElementById("mytime");
const heartrateHandle = document.getElementById("heartrateLabel");
const stepsHandle = document.getElementById("stepsLabel");
const caloriesHandle = document.getElementById("caloriesLabel");
const myBattery = document.getElementById("myBattery");
const myMonth = document.getElementById("myMonth");
const myDay = document.getElementById("myDay");
const hrm = new HeartRateSensor();

// Update the <text> element every tick with the current time
clock.ontick = (evt) => {
  let today = evt.date;
  let hours = today.getHours();
  let monthnum = today.getMonth();
  let day = today.getDate();
  var month = new Array();
  month[0] = "Jan";
  month[1] = "Feb";
  month[2] = "Mar";
  month[3] = "Apr";
  month[4] = "May";
  month[5] = "Jun";  
  month[6] = "Jul";
  month[7] = "Aug";
  month[8] = "Sep";
  month[9] = "Oct";
  month[10] = "Nov";
  month[11] = "Dec";
  let monthname = month[monthnum];
        if (preferences.clockDisplay === "12h") {
    // 12h format
    hours = hours % 12 || 12;
  } else {
    // 24h format
    hours = util.zeroPad(hours);
  }
  let mins = util.zeroPad(today.getMinutes());
  myLabel.text = `${hours}:${mins}`;
  myMonth.text = `${monthname}`;
  myDay.text = `${day}`; 
 }


// Heart Rate 

hrm.onreading = function() {
  heartrateHandle.text = `${hrm.heartRate}`; // the measured HR is being sent to the heartrateHandle set at line 12
  
  // Stop monitoring the sensor
  hrm.stop();
}

// Begin monitoring the sensor
hrm.start();

myBattery.text = `${battery.chargeLevel}%`; // initialize on startup
battery.onchange = (charger, evt) => {
myBattery.text = `${battery.chargeLevel}%`;

// Activity Values: adjusted type
  let stepsValue = (userActivity.today.adjusted["steps"] || 0); // steps value measured from fitbit is assigned to the variable stepsValue
  let stepsString = stepsValue; // I concatenate a the stepsValue (line above) with th string ' steps' and assign to a new variable
  stepsHandle.text = stepsString; // the string stepsString is being sent to the stepsHandle set at line 16
    
  let caloriesValue = (userActivity.today.adjusted["calories"] || 0); // caloire value measured from fitbit is assigned to the variable stepsValue
  let caloriesString = caloriesValue; // 
  caloriesHandle.text = caloriesString; // 

}

 

Again, I appreciate any advice and hopefully, one day I will be able to repay the favor. 

 

Many thanks

 

Will 

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

I'd just adding some console.log command in your tick event and seeing what the values are when connected to the device.

 

I have a watchface that you can use as an example, the code is on github.  Doesn't do anything special but does have the basic stats.

 

https://github.com/grumpy-coders/rpg-time

View best answer in original post

Best Answer
0 Votes
8 REPLIES 8

Hi Will, great that you picked up programming!

One thing that you'll probably find out sooner or later is that the language used on Fitbit is actually called JavaScript, and Java is another programming language, which is used for example to create Android apps.

 

Regarding your question - you already have the tick event listener in your code, though in a different form. Look:

 

clock.ontick = (evt) => {
    updateStats()
}

 

 is equivalent to

 

clock.addEventListener("tick", updateStats);

 

(strictly speaking, they are not equivalent. Later please read here for better understanding https://www.simonewebdesign.it/onclick-vs-addeventlistener/)

 

So you can just add a call to updateStats() to your existing clock.ontick block. 

I don't see the declaration of the updateStats function in your code, I assume you are yet going to write that function, right?

Best Answer
0 Votes

Thank you for commenting and thank you for clearing that up. I am glad you mentioned the difference between Java and Javascript, it's probably why I have been struggling to pick up online.  

I have added the code 

clock.ontick = (evt) => {
    updateStats()
}​

 

But unfortunately, it's deleting the date text, which I am sure is my poor coding understanding so will look into this deeper. 

 

Not sure what you mean about function, so again will look into this. Thanks for your support. 

 

Best Answer
0 Votes

By the function I meant - what is the updateStats() actually doing? When you use a function (which, simply and not fully correctly said, is something that has parentheses at the end), the function has to be defined somewhere. 

 

Like this:

 

function updateStats() {
    console.log("Hello")
}

 

 

Then you can use it like you do:

 

updateStats()

 

 

Could you please also clarify what you mean by "it's deleting the date text"? Does the text disappear or freeze on the screen?

Best Answer
0 Votes

Thanks again for your help. It appears to have fixed it now, and I have a little more understanding of what you mean by function, and that's now checking every second and putting it in the log. The date is now showing as well. 

 

As usual, it's now causing more issues. On the simulator, it is showing the step and calories value, but on the actual watch, it's only updating the values after an undefined length of time and blank until it does this. 

Best Answer
0 Votes

I'd just adding some console.log command in your tick event and seeing what the values are when connected to the device.

 

I have a watchface that you can use as an example, the code is on github.  Doesn't do anything special but does have the basic stats.

 

https://github.com/grumpy-coders/rpg-time

Best Answer
0 Votes

A bit of advice, the Versa has a limited about of memory (ram 64k I think) and if your not careful you can get out of memory errors.  On that note you are recreating the month array on very tick (once a second).  But the way you are using the array you don't need it.  You can just use a function that returns a string.  I pasted an example of what I'm doing to get the week day name.

 

 

 

function dayOfWeek(day) {
	switch (day) {
		case 0:
			return 'Sun';
		case 1:
			return 'Mon';
		case 2:
			return 'Tue';
		case 3:
			return 'Wed';
		case 4:
			return 'Thu';
		case 5:
			return 'Fri';
		case 6:
			return 'Sat';
	}
}

 

 

Update:

This is a good read on memory on the Versa / Ionic 

https://github.com/gaperton/ionic-views/blob/master/docs/optimization-guidelines.md#do-not-use-funct...

Best Answer
0 Votes

Thank you both so much for your help. I started the code again and took your advice Durus and I have managed to get it fully working to what I wanted it to do. 

 

I have to say Durus looking through your Github files most definitely helped and I borrowed some code, so I  hope you don't mind?

 

Thanks again

 

Wizz

 

 

Best Answer
0 Votes

I don't mind at all.  That's why I posted it to GitHub.

Best Answer
0 Votes