Question about custom field in Garmin Connect created from Custom Sport App

There are many topics about custom field and I saw 2 sample applications (MO2Display and MoxyField) which are coming with Garmin Connect IQ SDK, but I still cannot find clear answers for these questions:

1. To create a custom field, only 3 things are enough from a coding point of view.

a. Create xml file like this

<resources xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://developer.garmin.com/downloads/connect-iq/resources.xsd">
    <fitContributions>
        <fitField id="0"
        displayInChart="false"
        sortOrder="0"
        precision="2"
        dataLabel="@Strings.my_data_label"
        unitLabel="@Strings.my_unit_label"
        displayInActivityLaps="true"
        fillColor="#0000ffff" />
    </fitContributions>
</resources>

b. In the code, do like this

//define field id like this
private enum FieldId {
	MY_FIELD_ID
}

//create field
_fitField = _session.createField(
	"MyField",
	MY_FIELD_ID,
	FitContributor.DATA_TYPE_STRING,
	{:mesgType=>FitContributor.MESG_TYPE_LAP, :count=>32}
);

//call this when I need to save the data
_fitField.setData(myFieldValue);

c. Permissions <iq:uses-permission id="FitContributor"/> inside manifest.xml.

Is it enough or do I miss something?

2. To see the fields, I must publish my app to Garmin store. If I just copy MyApp.prg file with MyApp-fit_contributions.json created by the build process to my watch, I will not see my custom fields in https://connect.garmin.com and in Garmin Connect mobile app. Is it correct, or can I still see the fields without publishing the app to Garmin store? I already tried it with copying prg file and I see fields inside.fit file if I download activity as .fit file, but I do not see these fields in UI (https://connect.garmin.com or in Garmin Connect mobile app).

3. Are custom fields usually visible in both https://connect.garmin.com and in Garmin Connect mobile app or only one place? Maybe can someone share a few screenshots how custom fields look like?

4. Are custom fields available for all sport types or only for some specific sport types? I am specifically interested in SPORT_GENERIC.

  • When I started with Monkey C I made several small projects to learn each function.

    Please find enclosed a working project for FitContribution. Perhaps you will find it useful.

    FitContribute.zip

    There's no need to upload your project to the store. You can use "MONKEY GRAPH" from the SDK to check if it works.
    (see description inside the view.mc file)

    …and to answer your questions:

    ad 1. …you forgot to mention: import Toybox.fitContributor;

    ad 2.  for a check you need to use SDK Monkey Graph or to upload the project to the store

    ad 3.  yes - both

    ad 4.  yes

  • I would use constants with Number values instead of enum, as the ID in the XML has to be the same. It's clearer to use the same number than to relay on the automatically given enum ordinal.

    Yes I see my data both in the phone app and on the web. There were some bugs related to how certain things were displayed in one or the other, but I think they were fixed (but of course it's possible some of them are back). 

    It doesn't matter what is the sport or sub sport, as long the chosen value is ok for the watch (meaning it doesn't crash because of a value unknown to it)

    You can try this app: https://apps.garmin.com/en-IL/apps/a478d5f2-0a0a-4ba3-87aa-4832e97007ed

    And even see it in github

  • I would use constants with Number values instead of enum, as the ID in the XML has to be the same. It's clearer to use the same number than to relay on the automatically given enum ordinal.

    Agree. Either that or explicitly assign the enum value:

    private enum FieldId {
        MY_FIELD_ID = 0
     }

    It doesn't matter what is the sport or sub sport,

    Well it does make a difference in how Connect presents your activity data, and in some cases, how Garmin processes certain sensor data during the activity (according to Garmin).

    People have also been bugs related to the choice of sport/sub sport in a CIQ app, like recording a sail race activity in a CIQ app and inappropriately receiving a once per minute alert that's related to the built-in sail race activity profile.

    So you can pick whatever sport and sub sport that your watch supports, but I wouldn't say it has no effect. (Not that you actually said that, but it was somewhat implied.)

  • Yes, but that mostly changes the 1st 2 tabs, and what you see in the default graphs. It shouldn't matter what custom fields you have and how they are displayed. If it does then I'd say it's more probably a bug than an intentional behavior

  • Right but, again, it can change how sensor data is processed during the activity.

    For example, swimming may use different algorithms than cycling, which may use different algorithms than running.

    My point is the sport that is chosen for activity recording can do more than simply affect the data that's displayed, as per Garmin.

    I agree that it won't affect the custom data, but it may affect the default data.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/ActivityRecording.html

    The SPORT_* defines the type of activity, but is not guaranteed to change device behavior. This may cause different algorithms to be applied to the sensor data. For example, a device that does not natively support SPORT_MULTISPORT recording will not gain SPORT_MULTISPORT transition features. However, the FIT file can be defined as SPORT_MULTISPORT and MULTI_SPORT algorithms may be applied to the sensor data.

  • Thank you very much. You answered all my questions!

  • So, is this what you mean?

    const MY_FIELD_ID = 22;
    ...
    //create field
    _fitField = _session.createField(
    	"MyField",
    	MY_FIELD_ID,
    	FitContributor.DATA_TYPE_STRING,
    	{:mesgType=>FitContributor.MESG_TYPE_LAP, :count=>32}
    );
    


    and xml should be like this
    <fitField id="22" .../>

  • I managed to make it working. Indeed the answers were confirmed. I needed something like lap field (slow lap or fast lap). 

    It looks like this in Garmin Connect mobile app

    i.ibb.co/.../Lap-Type-in-the-Garmin-Connect-app0.jpg

    but looks empty in https://connect.garmin.com (probably garmin bug or maybe it is only for my Fenix 7 device).


    i.ibb.co/.../Lap-Type-in-the-Garmin-Connect-website-0.jpg

    and I found that I need to call 

    _fitField.setData("Slow lap");

    just before I call
    _session.addLap();
    otherwise it does not work from time to time.
    Thank you all for your help.

     

  • I found that I need to call 

    _fitField.setData("Slow lap");

    just before I call
    _session.addLap();
    otherwise it does not work from time to time.

    Yeah it's well known that you have call to setData() before a lap is taken, otherwise it's too late for the data to be written for that lap. (It will be applied to the *next* lap).

    In practice this means that if you are writing a CIQ data field, where you do not have control over when a lap will be taken, you have to constantly call setData() (e.g. once per second) for lap fields. Ofc only the data in the final call to setData() - before a lap is taken - will be written.


    but looks empty in https://connect.garmin.com (probably garmin bug or maybe it is only for my Fenix 7 device).

    I would guess that the Garmin Connect website doesn't support displaying strings for lap data, only numbers.

    I'm actually surprised that it works in the Connect app.

    For a long time I assumed that strings were only supported in the summary (MESG_TYPE_SESSION).