Acknowledged

SDK 7.3.0 --> BodyBatteryHistory broken

function getIteratorBodyBattery() {
    // Check device for SensorHistory compatibility
    if ((Toybox has :SensorHistory) && (Toybox.SensorHistory has :getBodyBatteryHistory)) {
        return Toybox.SensorHistory.getBodyBatteryHistory({});
    }
    return null;
}

var intBB = 0;
var sensorIterBodyBattery = getIteratorBodyBattery();
if (sensorIterBodyBattery != null) {
    intBB = sensorIterBodyBattery.next().data / 100;
}

Line 12:
intBB = sensorIterBodyBattery.next().data / 100;
stops with error in SDK 7.3.0:
Details: Failed invoking <symbol>

There is no probnlem with that in SDK 7.2.1:

SDK 7.2.1
sensorIterBodyBattery:
----------------------

mMax = 37 (Lang.Number)
mMin = 35 (Lang.Number)
mNewestSampleTime = Lang.Object
mOldestSampleTime = Lang.Object

Values with SDK 7.3.0:

SDK 7.3.0
sensorIterBodyBattery:
----------------------

mMax = 0 (Lang.Number)
mMin = 127 (Lang.Number)
mNewestSampleTime = Lang.Object
 mDateTime = 0 (Lang.Number)
mOldestSampleTime = Lang.Object
 mDateTime = 0 (Lang.Number)

The minimum-value is 127 (body battery cannot be greater than 100) and die maximum value is 0 (max is smaller than min).
The setup of the simulator is identically.
IMHO there is bug in
Toybox.SensorHistory.getBodyBatteryHistory({})

Is there an idea to fix that?

Greetings,
Ronny

Parents Comment Children
  • I appreciate the details you've provided. I don't believe there is a bug, but perhaps there was one that we have since addressed. I wasn't able to identify a specific fix related to this in 7.3.0. I'm surprised this worked without problems in 7.2.1, because I agree with 's and 's analysis that the problem is due to null values getting returned by the iterator that you were attempting to perform operations with.

  • Hi Brandon,
    with regard to your request I did some trouble shooting and null checks. First the code (that is finally working):

    function getIteratorBodyBattery() {
        // Check device for SensorHistory compatibility
        var twoHours = new Time.Duration(7200);
        if ((Toybox has :SensorHistory) && (Toybox.SensorHistory has :getBodyBatteryHistory)) {
            return Toybox.SensorHistory.getBodyBatteryHistory({
                :period => twoHours,
                :order => SensorHistory.ORDER_NEWEST_FIRST
            });
        }
        return null;
    }
    
    var sensorIterBodyBattery = getIteratorBodyBattery();
    var intBB = 0;
    var bbTop = 125;
    var bbBottom = 235;
    var bbMiddle = 0;
    var intBBData;
    var intBBNext;
    if (sensorIterBodyBattery != null) {
        intBBNext = sensorIterBodyBattery.next();
        if (intBBNext != null) {
            intBBData = intBBNext.data;
            if (intBBData != null) {
                intBB = intBBData / 100;
                bbMiddle = bbBottom - ((bbBottom - bbTop) * intBB);
                dc.setColor(0xff5555, 0x000000);
                dc.fillRectangle(123, 128, 52, bbMiddle - bbTop);
                dc.setColor(0x55ff55, 0x000000);
                dc.fillRectangle(123, 128 + bbMiddle - bbTop, 52, bbBottom - bbMiddle);
            } else {
                dc.setColor(0xffffff, 0x000000);
                dc.fillRectangle(123, 128, 52, 114);
            }
        } else {
            dc.setColor(0xaaaaaa, 0x000000);
            dc.fillRectangle(123, 128, 52, 114);
        }
    } else {
        dc.setColor(0x5555ff, 0x000000);
        dc.fillRectangle(123, 128, 52, 114);
    }
    var BodyOutline = Application.loadResource( Rez.Drawables.BodyOutline ) as BitmapResource;
    dc.drawBitmap(123, 128, BodyOutline);

    I implemented null checks for every step in between --> every object that could be null will draw the body battery indicator in a different color. The problem is obviously caused by the option ":period" in the method

    Toybox.SensorHistory.getBodyBatteryHistory({})

    According to the API-doc the option :period could have 3 states:

    • null
    • number
    • duration

    If :period is "null" or any number, then the return leads to a null-value of ".next()" of the SensorHistoryIterator - in my code:
    intBBNext = sensorIterBodyBattery.next();
    intBBNext is null --> the body battery indicator get the color light gray.
    body battery no data (light gray)

    Only if :period is a duration, the body battery value will be return properly:
    body batterie OK

    I tested on real device (fenix 7x)

    I hope, these checks will help you to find the problem in the body battery history.

    With best regards
    Ronny