getHeartRateZones() on fenix 5x not returning an array

Hi,

I got several messages back from fenix 5x users stating that they notice a bug related the heartratezones. I could limit it down to the below code. When this piece of code executes an error is thrown and the catch block is executed. My current investigations point to the lines where I start using the hrz-array - so to my best guess it does not seem to be initialized. The error does not occur in the simulator running fenix 5x emulator.
I did not get usable error logs back and I do not own the device myself.

Versions info: fenix 5x 6.00 (and various beta versions including 6.75), CIQ 2.3.5 in Eclipse

I assume it is the same bug reported here: https://forums.garmin.com/forum/deve...eports/154680-

function setHeartRateValues(field, value) {
field.value = (value == ActMon.INVALID_HR_SAMPLE ? 0 : value);
try {
var hrz = User.getHeartRateZones(User.HR_ZONE_SPORT_GENERIC);
var min = 2*hrz[0]-hrz[1];
var max = hrz[5].toFloat();
field.min = min;
field.max = max;
field.scalecolors = [
[(hrz[0]-min)/(max-min), Gfx.COLOR_DK_GRAY],
[(hrz[1]-min)/(max-min), Gfx.COLOR_DK_GREEN],
[(hrz[2]-min)/(max-min), Gfx.COLOR_GREEN],
[(hrz[3]-min)/(max-min), Gfx.COLOR_YELLOW],
[(hrz[4]-min)/(max-min), Gfx.COLOR_RED],
[(hrz[5]-min)/(max-min), Gfx.COLOR_DK_RED]
];
hrz = null; min = null; max = null;
} catch (ex) {
field.min = 0;
field.max = -1;
field.scalecolors = [
[1.0, Gfx.COLOR_DK_GRAY]
];
}
}
  • Hey,

    I've been playing around with this in the sim and on hardware. I'm getting the zones returned correctly on both. I was able to pair down your code to where it's just the getHeartRateZones() call and the min and max variables. I'm not sure how you're using the rest of your function here. However, the getHeartRateZones() API isn't failing here. I think the failure is happening in the "field" or "value" params you are passing into the function. It could still be a bug on our part and it's causing the failure here inside the function, but I'm not sure that it's the getHeartRateZones() call that is doing it.

    Thanks,
    -Coleman
  • Hi Coleman,

    I can confirm this is a problem. The getHeartRateZones() is crashing on Fenix 5X and Approach S60 (both devices with two CPUs), but only in some cases. Firmware version 6.0.0 or newer. It always works in the emulator.

    var currentSport = UserProfile.getCurrentSport();
    var zones = UserProfile.getHeartRateZones(currentSport);

    If you call this in the Watch face app in onLayout(dc), when the watch face preview is displayed (when you want to select the watch face), everything works well and the data are correctly returned. But when you select the watch face and onLayout(dc) is called again, it crashes. You can wrap it by try/catch block and load previously saved values (so it's OK, this is a workaround), but I think no meaningful exception is returned and no information is written into log file. It just crashes.
  • I was able to reproduce this. GidoG , is this happening on a watch face? After further investigation, it appears to be specific to dual processor devices as pointed out by TomasSlavicek . I've created a ticket for this issues.

    Thanks,
    -Coleman
  • Sorry for digging out this old thread, but has this bug ever been fixed?
    I just implemented getCurrentSport() and getHeartRateZones() into X-Face and got first replies that X-Face now crashes on Fenix 5X
  • I've just received some crash logs from a user with a Fenix 5X, which indicate a crash after calling getHeartRateZones(), so it seems this bug still exists!

    I was just doing this (optimistic I know):

    		heartMaxZone5 = UserProfile.getHeartRateZones(0/*UserProfile.HR_ZONE_SPORT_GENERIC*/)[5];
    

    But I've now changed it to this instead to try and be safe:

    var heartRateZones = UserProfile.getHeartRateZones(0/*UserProfile.HR_ZONE_SPORT_GENERIC*/);
    if (heartRateZones!=null && (heartRateZones instanceof Array) && heartRateZones.size()>5)
    {
    	heartMaxZone5 = heartRateZones[5];
    	if (heartMaxZone5==null || heartMaxZone5<=0)	// max must be at least 1 to avoid potential zero divide
    	{
    		heartMaxZone5 = 200;
    	}
    }

    Are there any other calls on Fenix 5X which could cause problems in the same way? E.g. other user profile calls?

  • However, you could write your own ActivityTracker based on the "ActivityTracker" sample in the Connect IQ API Docs. Unfortunately, that essentially means you would have to duplicate the logic of the display you currently see just to add the three fields mcdonalds survey code

  • i recently found that this is also affected on the EPIX

  • This is still happening on the Fenix 5X.  Why isn't this fixed yet?

  • In looking at this thread, it sounds like you're running into the "dual core" nature of the f5x (and S60).  While other watches have a single processor, the f5x has a main core and a display core, where the 2nd core is used by a watch face.   It sounds like what is happening is not everything you want is available to the second core.  Nothing unique with this as there are a number of things like this, such  as currentLocation and currentHeartrate When you need to do is cache some of the data when it's available and valid.  Things will be available when you are previewing/selecting a watch face, but not when it's running.  

    What this means is if you want to support the f5x, you probably need some work arounds, as it's due to the difference in HW, and it's things you won't see in the sim.  This is why you'll never see "real time" heart rate with a watch face on the f5x, and things like getting the location for things like weather require different steps than on other device,

  • it's accessible from any activity or a watch mode (it just needs to acquire GPS signal if GPS is not running).
    I'll be sure to keep an eye on this thread. Looking for the same issue. Bumped into your thread. Thanks for creating it. Looking forward for solution.panorama charter