Problem with SensorHistory.getHeartRateHistory and SDK versions

Former Member
Former Member
Hi there

I'm completely new to this and I'm trying to make my own watchface for a Fenix 3 HR, where I'm trying to show the current HeartRate.

The compiler doesn't like the line of code below.
var sensorHist = Toybox.SensorHistory.getHeartRateHistory({});

It gives the errormessage: "Could not find symbol SensorHistory"

As far as I can see in the documentation the SensorHistory is only supported from SDK version 2.1.0 an onwards, and I guess that is where the problem is.

I'm a bit confused, In the manifest file I have tried to set the App minimum SDK version to 1.3.X and then I can set the build target to fenix 3 HR, but then I guess I can't use the SensorHistory.

If I instead try to set the App minimum SDK version to 2.1.X or 2.2.X then I can not set the build target to fenix 3 HR, most of the watches is greyed out.

I have also enabled the permissons for Sensor History.

Any help is greatly appriciated here.

Thanks a lot

Br Kenth
  • If you look at the api doc for SensorHistory (2.2.1 version) you'll see:

    Since:
    2.1.0
    Supported Devices:
    Forerunner 735xt
    fenix Chronos
    Vivoactive HR

    Earlier doc still had "Since 2.1.0" but IIRC listed the F3-hr, when the F3-hr was a 1.3 device, so that doc was incorrect. So what's happening for you is what's supposed to happen - you're trying to make the call on a device that doesn't support the call (the f3-hr) and if you change the min version to 2.x, you can't build for any devices that are only 1.x

    But what you can do is use ActivityMonitor.getHeartRateHistory(), as that's supported on all devices with Wrist based HR.. starting with 1.2 devices For it you see:

    Since:
    1.2.1
    Supported Devices:
    Forerunner 235/735xt
    fenix 3 HR
    D2 Bravo Titanium
    Vivoactive HR

    So, you want to leave the CIQ version at the default, and then you can build for the f3-hr, but use the version of getHeartRateHisory() in ActivityMonitor instead of the one in SensorHistory.

    But, if you try to build for the f3 instead of the f3-hr, you'll still get an error, as the call is supported on the f3-hr and not the f3.

    What you can do is check if it's available on the target you're running on with something like:

    hasHR=(ActivityMonitor has :HeartRateIterator) ? true : false;

    and then only call ActivityMonitory.getHeartRateHistory() on devices where "hasHR" is true.
  • Former Member
    Former Member over 8 years ago
    and then only call ActivityMonitory.getHeartRateHistory() on devices where "hasHR" is true.


    Thanks a lot for excellent support.

    I'm afraid I need to ask for a little bit more help.

    I have now made the following code:

    var heartRateHistoryIterator = ActivityMonitor.getHeartRateHistory(1, true);
    var heartRateSample=heartRateHistoryIterator.next();
    dc.drawText(110, 145, Gfx.FONT_MEDIUM, Lang.format("hr $1$", [heartRateSample.heartRate]), Gfx.TEXT_JUSTIFY_CENTER);

    I'm not sure I have fully understood the concept of the iterator I get from calling the method getHeartRateHistory

    And sometimes the values is not the same values as the values I get when using the original Garmin HeartRate widget on the watch

    Have I done anything wrong here?
  • Here's the code I use. It's a bit different as I check for both null values as well as bad readings:

    var hrh=ActMon.getHeartRateHistory(1,true);
    var hr="--";
    if(hrh!=null) {
    var hrs=hrh.next();
    if(hrs!=null && hrs.heartRate!=null && hrs.heartRate!=ActMon.INVALID_HR_SAMPLE) {
    hr=hrs.heartRate.toString();
    }
    }
    ret="hr: "+hr;


    You'll see INVALID_HR_SAMPLE in a case where you're not wearing the watch for example, and "null" might happen if you have the WHR turned off on the watch.

    As far as not matching the widget, this is the "history" and not a live reading. The watch takes a reading every couple minutes, which you can "iterate" through. (In this case you're asking for one sample, and the newest one first, so nothing to really iterate through.. if you had requested more than one, by doing a ".next" you could go though all of the samples from newest to oldest for example.)

    The sample you're getting could still be a couple minutes old, while the widget is showing a current reading - that's why they might not always match.
  • Former Member
    Former Member over 8 years ago
    Thanks a lot Jim, magnificent help