Fit contributor lap data not showing up on garmin connect web or mobile

I have a simple data field that is trying to save data to fit file.  I have it saving record, session and lap data.  I can see the record and session data on garmin connect web and mobile but the lap data is not showing up.  I can see the lap data being saved in the fit fille using java -jar fitcsvtool.jar activity.fit --defn none --data lap.

I have a fit.xml file in the resources folder as below:

<fitContributions>
    <!-- RECORD : Record Chart Definitions -->
    <fitField id="0" displayInChart="true" sortOrder="0" precision="2" chartTitle="@Strings.FITNESSTITLE" dataLabel="@Strings.FITNESSLABEL" unitLabel="@Strings.KPH" fillColor="#ff7b00" />

    <!-- SESSION : Session Data Definitions -->
    <fitField id="1" displayInActivitySummary="true" sortOrder="1" precision="2" dataLabel="@Strings.FITNESSLABEL2" unitLabel="@Strings.KPH2" />

    <!-- LAP : Lap Data Definitions -->
    <fitField id="2" displayInActivityLaps="true" sortOrder="2" precision="2" dataLabel="@Strings.FITNESSLABEL3"  unitLabel="@Strings.KPH3" />
</fitContributions>

and strings.xml looks like this:

<strings>
    <string id="AppName">RTFC</string>
    <string id="FITNESSTITLE">Fitness</string>
    <string id="FITNESSLABEL">Fitness</string>
    <string id="FITNESSLABEL2">Avg Fitness</string>
    <string id="FITNESSLABEL3">Avg Fitness</string>
    <string id="KPH">kph</string>
    <string id="KPH2">kph</string>
    <string id="KPH3">kph</string>
</strings>

I have this in function initialize() to create the fields:

        FitFit = createField(
            "FITNESS",
            0,
            FitContributor.DATA_TYPE_FLOAT,
            {:mesgType=>FitContributor.MESG_TYPE_RECORD, :units=>"kph"}
        );
        FitFitSum = createField(
            "FITNESS",
            1,
            FitContributor.DATA_TYPE_FLOAT,
            {:mesgType=>FitContributor.MESG_TYPE_SESSION, :units=>"kph"}
        );
        FitFitLap = createField(
            "FITNESS",
            2,
            FitContributor.DATA_TYPE_FLOAT,
            {:mesgType=>FitContributor.MESG_TYPE_LAP, :units=>"kph"}
        );

        FitFit.setData(0.0);
        FitFitSum.setData(0.0);
        FitFitLap.setData(0.0);

and this in function compute()

     if (info != null && thingtoreturn != null) {
        // Record
            FitFit.setData(thingtoreturn);
        // Session
            Scounter++;
            bigMean += thingtoreturn;
            FitFitSum.setData(bigMean / Scounter);
        // Lap
            Lcounter++;
            lapMean += thingtoreturn;
            FitFitLap.setData(lapMean / Lcounter);
        }

and this bit to reset the lap value:

    public function onTimerLap() as Void {
    //! Handle lap event
        Lcounter = 0;
        lapMean = 0.0;
    }

I can see the fit data in activity_data.csv made from running java -jar fitcsvtool.jar activity.fit --defn none --data lap against a real or simulated fit file:

and activity.csv made in same way:

But I have no lap data in garmin connect mobile (even if I scroll right) or web (I do get session and record data).

There seem to be threads from a few years back which say that garmin connect web and/or mobile is not to be trusted for fit data viewing but I figured this would be fixed by now.  I also spent some time in monkeygraph which again works well for session and record data but seems flaky with lap data. I was wondering if I had too many native lab fields and this was causing the issue... 48 seems like a lot.

Please help, thanks!

  • Yeah I gave up on getting lap data but the funny thing is someone else is using my datafield too and they have what looks like correct lap data in gcm and web Shrug.

  • Maybe there's a difference between automatic laps and when we click the lap button?

  • FlowState, looks that you are right - it's safe to set a session data inside the onTimerStop() because at this point user has 2 options - save the activity or resume it, so the data isn't yet written into the FIT. Whereas with laps the situation seems to be opposite - firstly device triggers a lap event, then probably writes lap values into tge FIT, and only then invokes the onTimerLap() method (making it totally useless for us). 

    Regarding the setting session data in the onTimerPause() method for safety reasons - that seems to be redundant too, because there is no way to save/discard an activity without hitting a physical start/stop button being in the pause/autopause mode, so onTimerStop() will be anyway invoked before the saving of activity. At least, that's valid for Edge devices, on watches this flow may be slightly different  

  • I have an app that records .fit files with added lap data fields. It has been working for years on many devices. It has both developer added lap and session variables.

    I am getting a recent report of issues with a FR965 running a recent firmware update to 18.22. It looks like this was released about Feb 29 for this and a few similar models.
    In examining a sample fit file i can see the session variables however the lap variables seem to be missing completely.

    I did not see mention of which models others are having issue with. It might be interesting to determine if this issue is related to specific device models.

    This might help to determine where the fault is. In looking at the firmware release notes it sounds like there are a lot of changes, one in particular relates to 'adds lap undo' which might be related to this.

    What models are causing others issues?

  • Regarding the setting session data in the onTimerPause() method for safety reasons - that seems to be redundant too, because there is no way to save/discard an activity without hitting a physical start/stop button being in the pause/autopause mode, so onTimerStop() will be anyway invoked before the saving of activity. At least, that's valid for Edge devices, on watches this flow may be slightly different  

    Thanks for explaining that! Yeah, I just tried auto-pause for the first time ever, on my Forerunner 955. When auto-pause kicks in, the timer stops and a big pause icon overlays the screen. But in order to access the normal "stopped activity menu", you do have to press START.

    So it should be sufficient to call setData() for session data in onTimerStop(). Whew, I don't have to go back and change a bunch of old apps.

  • In this thread someone wrote that the data is in the fit file it just isn't displayed in the Garmin app, website. So your issue might be different. I also have fr965 and I see in the forum so many complaints, so I wouldn't be surprised if you are up to something. I can even bet with you that something like this is happening: the lap undo feature means they don't write the lap data to the file at the moment the lap en's (to be able to undo) and they forgot to write it when the undo time expires, so the lap data is missing. Just a guess of course, but would make some sence

  • For those who are interested in why the MonkeyGraph tool displays these funky #VALUE? results in a lap or activity summary instead of the real numbers. The reason is in string formatting implemented by the MonkeyGraph itself.

    TL;DR integer values in lap/activity summary in FIT always cause #VALUE? in the MonkeyGraph.

    The MonkeyGraph code looks like this:

    package com.garmin.monkeybrains.fitgraphs.ui;
    
    import java.util.Formatter;
    
    public class UiUtil {
       public static String format(Object value, int precision) {
          if (value instanceof Number) {
             if (precision == -1) {
                return value.toString();
             } else {
                new StringBuilder();
                Formatter formatter = new Formatter();
                return formatter.format("%." + precision + "f", value).toString();
             }
          } else {
             return value.toString();
          }
       }
    }

    So basically it tries to format each subclass of number using a float formatter. For example, if the precision is 1 and the value in FIT is float 55.234512 then the formatter will be "%.1f", and the resulting string value will be "55.2", with no issues to be displayed.

    But if the precision is 0 and the value in FIT is integer 55 then the formatter will be "%.0f", and it will fail to format the 55 integer value into the "55" string because "%.0f" formatter works only with float values. For integers the correct formatter should be "%d".

    Note that if your code in Monkey C is something like this:

    var numerator = 5 as Number;
    var denominator = 3 as Number;
    var division = numerator/denominator;

    then the result will still be a Number with value 1, not Float 1.666667, which, in turn, will be displayed as #VALUE? in the MonkeyGraph.

    Note also that this seems to be not related to the original OP issue since values in his FIT file are valid floats.

    Note also that MonkeyGraph and Garmin Connect have different codebases, so this formatting issue is very likely present only in MonkeyGraph.

  • It is fixed now with beta 21.14 firmware for Edge1040, so lap and session fields from CIQ are recorded normally and displayed in Garmin Connect

  • That's bad. If that's the case then it means the bug isn't in Garmin Connect and the website, so fixing it will only be possible when "all" users upgrade to the new firmwares (and we can only hope that Garmin will fix the bug in all the devices...)