Fit Contributor

Hi,

just a question to the FitContributor: If I calculate the average values of an high-intensity period of an interval and write those values to the Fit file, does Garmin connect web make those values somehow visible or is it just a value in the Fit file?
  • Hi,

    I have tried another implementation of the fitcontributor: writing a string to the lap section. It's not shown on GC website. I tried monkeygraph and it showed me this:
    https://www.dropbox.com/s/rf74mjgxe8gqev2/monkeygraph.JPG?dl=0


    The json file in the iq-archive showed me this:
    {"datafields":[{"id":0,"chart-visible":false,"activity-visible":false,"lap-visible":true,"chart-title-key":null,"label-key":"HrLabel","unit-label-key":"HrUnit","sort-order":0,"precision":null,"fill-color":null}],"strings":{"default":{"HrLabel":"HR av, lap, pred","HrUnit":"bpm"}}}

    What am I doing wrong that the things are screwed up?
  • Hi again,

    I don't know, what I changed (IMHO nothing), but now the lap fitcontribution works partly: in Garmin connect mobile, the values are correctly depicted whereas (the same activity) shows in Garmin connect web just 0.

    https://www.dropbox.com/s/9f889kvebbwebmv/Garmin%20Connect%20Web.JPG?dl=0

    How can I debug that?
  • Did another run today, changed the implementation a bit (by setting first data right in the constructor), the same results. GC mobile shows the values, GC web shows just zero. Can someone help please? I would e. g. send the code if it would be necessary...
  • If the data appears in the .FIT file and works correctly in Garmin Connect Mobile, what makes you think it isn't just a bug in Garmin Connect that prevents the values from being displayed?

    Travis
  • I feel your pain. I had lots of issues with the FitContributor and displaying custom values in GC, but GCM always seemed to work. I had problems displaying a string in GC and eventually gave up, but it sounds like you are trying to display floats? When trying to show a string like 00:10 hh:mm GC would show 0 hh:mm, but GCM always worked.

    One thing I did notice is that after I made any changes to the fit contributor part of my code, I had to uninstall the app from my watch, reboot and then reinstall the new version. If I just updated the new version without an uninstall, then GC wouldn't show any custom values at all (just the Recorded with: MyApp logo). But GCM always worked right away.

    The process seems a little flaky on GC for sure, but I'm pretty happy that we can display custom values on GC and GCM.

    Sorry I can't be any more help...maybe post the FitContributor part of your code?
  • @TRAVIS.VITEK: the problem I have with fit files I contributed to is, that 3rd party tools have problems reading it. E. g. the set of fit files I added a string to each lap can't read by sporttracks (offline tool). Strava shows only the first lap and online tools like http://garmin.kiesewetter.nl/ throws an error message while loading:
    The file could not be uploaded. The following error occured: Exception of type 'System.OutOfMemoryException' was thrown.

    Further example; the set of fit files (e. g. this one: https://connect.garmin.com/modern/activity/1372956586) I added values each second can't also not read by sporttracks, Strava shows them correctly but online tools like http://garmin.kiesewetter.nl/ throws an error:
    Upload status: The file could not be uploaded. The following error occured: Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.


    @bwd1: I have two datafields which contribute to the fit file:
    1. I add a string at each lap:
    <fitContributions>
    <fitField id="0" displayInChart="false" displayInActivityLaps="true" sortOrder="0" dataLabel="@Strings.HrLabel" unitLabel="@Strings.HrUnit"/>
    </fitContributions>


    In the constructor:
    avHrField = createField("different_HRs", 0, FitContributor.DATA_TYPE_STRING, { :mesgType=>Fit.MESG_TYPE_LAP, :count => 14 });
    avHrField.setData("0");


    And in the onTimerLap() method (avHr, and averageCadenceField are also numbers):
    avHrField.setData(avHr + ", " + temp.toNumber() + ", " + averageCadenceField);


    By the way: I put this code in the onTimerLap() method, nevertheless, it seems that the fit file is written __before__ this code is executed which means that the data is written to the next lap :-( Is this a bug or a feature and is there a workaround for this?

    _________________________________________________________
    2. I create in another app a graph:
    <fitContributions>
    <fitField id="0" displayInChart="true" sortOrder = "0" precision="0" chartTitle="@Strings.AvHrGraphLabel" fillColor="#FF0000"/>
    </fitContributions>


    In the constructor:
    avHrField = createField("average_heartrate", 0, FitContributor.DATA_TYPE_UINT8, { :mesgType=>Fit.MESG_TYPE_RECORD, :units=>"bpm" });
    avHrField.setData(0);


    In compute(info):
    avHrField.setData(hiAvHrField.toNumber());


    The problem here is, that (as you said) GC mobile shows the value correct, but GC web shows the curve not in red but in black. If I use the zoom button for that black graph, no curve at all is shown. Nevertheless, if I hover with my mouse over the not shown curve, the values at the cursor position are shown.


    Apart from the GC web problems I have problems with 3rd party tools and those fit files (as stated above).

    Thanks for your help in advance.
  • Ah, yeah I couldn't get FitContributor.DATA_TYPE_STRING to work in GC either (GCM was fine). As Travis mentioned, it may be a bug in GC.

    I also tried FitContributor.DATA_TYPE_UINT8 but had no luck, but FitContributor.DATA_TYPE_FLOAT worked fine for me. I'm not doing any laps though.

    Also my colour worked:
    <fitField id="0" displayInChart="true" sortOrder="0" precision="1" chartTitle="@Strings.waveplot_title" dataLabel="@Strings.waveplot_label" unitLabel="@Strings.waveplot_units" fillColor="#0000FF" />

    Gave me a blue graph.

    The zoom button on your IQ graph works for me, other than the colour is black.

    As for sporttracks, my values don't show there either but I didn't really expect them to. I would email support at Sporttracks. They have always been very quick to respond and would probably be interested in looking at the FIT file.
  • Thanks for sharing this. I just want to record numbers. Do you convert those floats to numbers by e. g. 123.0 ? Or is it possible to set the precision in the resources file to 0 but stating in the code FitContributor.DATA_TYPE_FLOAT? Do you have a screenshot of one of your graphs?

    Just an idea: You wrote:
    When trying to show a string like 00:10 hh:mm GC would show 0 hh:mm, but GCM always worked.

    I also start my string with a number. Maybe GC web interpretes the string different from GCM and can not depict strings which starts with a number. In my example I create strings like: "141, 136, 150". What GC web depicts is "0". Maybe it's worth to create stringls which starts with a letter like "H141, 136, 150". What do you think?


    @TRAVIS.VITEK: Do you know a workaround for that:
    By the way: I put this code in the onTimerLap() method, nevertheless, it seems that the fit file is written __before__ this code is executed which means that the data is written to the next lap :-( Is this a bug or a feature and is there a workaround for this?
  • The zoom button on your IQ graph works for me, other than the colour is black.

    As for sporttracks, my values don't show there either but I didn't really expect them to. I would email support at Sporttracks. They have always been very quick to respond and would probably be interested in looking at the FIT file.


    Really? Which browser? Can you send me a screen shot?

    Regarding sporttracks: what I mean is, that not only the values are shown but the entire FIT file is not readable. It is refused. Regarding contacting them: that's a great idea.
  • <fitContributions>
    <fitField id="0" displayInChart="true" sortOrder="0" precision="1" chartTitle="@Strings.waveplot_title" dataLabel="@Strings.waveplot_label" unitLabel="@Strings.waveplot_units" fillColor="#0000FF" />
    <fitField id="1" displayInActivitySummary="true" sortOrder="1" precision="0" dataLabel="@Strings.wavenum_label" unitLabel="@Strings.wavenum_units" />
    <fitField id="2" displayInActivitySummary="true" sortOrder="2" precision="2" dataLabel="@Strings.wavetime_label" unitLabel="@Strings.wavetime_units" />
    <fitField id="3" displayInActivitySummary="true" sortOrder="3" precision="0" dataLabel="@Strings.wavetime2_label" unitLabel="@Strings.wavetime2_units" />
    <fitField id="4" displayInActivitySummary="true" sortOrder="4" precision="1" dataLabel="@Strings.wavedist_label" unitLabel="@Strings.wavedist_units" />
    <fitField id="5" displayInActivitySummary="true" sortOrder="5" precision="1" dataLabel="@Strings.wavespd_label" unitLabel="@Strings.wavespd_units" />
    </fitContributions>

    function initialize() {
    DataField.initialize();
    waveplotField = createField("waveplot", 0, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_RECORD, :units => "kph" });
    wavenumField = createField("wavenum", 1, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_SESSION });
    wavetimeField = createField("wavetime", 2, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_SESSION });
    wavetime2Field = createField("wavetime2", 3, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_SESSION });
    wavedistField = createField("wavedist", 4, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_SESSION });
    wavespdField = createField("wavespd", 5, Fit.DATA_TYPE_FLOAT, { :mesgType=>Fit.MESG_TYPE_SESSION });
    waveplotField.setData(0);
    wavenumField.setData(0);
    wavetimeField.setData(0);
    wavetime2Field.setData(0);
    wavedistField.setData(0);
    wavespdField.setData(0);
    }

    function onTimerStop() {
    wavenumField.setData(WAVES_TOT);
    wavetimeField.setData((TOT_TIME2/60)%60+TOT_TIME2%60/100.0);
    wavetime2Field.setData(OL_MAX_T);
    wavedistField.setData(OL_MAX_D);
    wavespdField.setData(OL_MAX_S);
    }


    Results are shown here:
    https://forums.garmin.com/showthread.php?220947-Data-Field-Surf-Tracker&p=907434#post907434

    So yes, I used FLOAT then set the precision. I had to get tricky with my hh:mm string.

    For sporttracks, I have it synced to GC and it syncs and displays the FIT file as normal (without the custom values). I didn't try importing manually.

    I'm using Chrome on Win7: