Сhange dataLabel for fit fields?

Is it possible to change the dataLabel for the MESG_TYPE_SESSION field when closing the session, according to its results, and not only at the moment of field creation during application initialisation? Perhaps from a previously prepared string resource?

  • You mean the value? Yes, the last value you set with setData() overrides the previous value.

    If you mean the label you see in Garmin Connect, the probably not. But you don't need to create the session field until the last moment, when you know what it should be.

    However it's not as simple as to send a string to the function. You need to have all the possible labels in the fit contributor xml, with different id-s, and use the id that you need. See line 151 here: github.com/.../WalkerView.mc

  • I was referring specifically to the label. Creating a field at the last moment could be a way out, but I don't understand how to capture that last moment. It's not just the user hitting the stop button (or auto-pause being enabled), it's the user saving the activity. I'm not programming an application but a data field, so I can't create an activity or stop it

  • Try this: create the fields in the xml, then in compute() create a different one every second, and see what happens. Probably it'll crash after you use up the available bytes/fields.

    When do you want to change the label?

  • But you don't need to create the session field until the last moment, when you know what it should be.
    Creating a field at the last moment could be a way out

    Unfortunately, it can't, since (the last time I checked), createField() will fail if you call it past a certain point. [e.g. it will work if you call it in DataField.initialize, but it won’t work if you call it in onUpdate or compute]

    Another plausible solution, if you only have a handful of different labels (e.g. 2 or 3) could be to call createField() multiple times for the same session field (with a different IDs that correspond to the different labels), and only call setData() for the field that will actually be used. For a record field, the value in not graphed until you do call setData(), so it's plausible that if you don't call setData() for a session, it won't show up in Connect. However, you have the same problem where you can't capture the moment of the user saving the activity, you can only call setData() *before* saving the data (e.g. call setData() continuously or in onTimerStop()). So this isn't really a solution at all. (Not to mention that it could cause issues due to the per-app and per-activity CIQ FIT field limits)

    I know you won't like this, but the only way to truly have a dynamic "label" for a session field is to put the label in a separate field. i.e. have two fields: one for the session value (with a generic name), and one for the value's "label". I actually do this for a data field which has a session value where the "label" is user-specified (free tex).

  • Alternatively, you could have a single session field with a string type, and incorporate the label into the value itself.

    (Obviously both of my solutions depend on the label not being too long to fit in a single string field, and this solution means you have even less room for the label.)

  • If it's free text that's another story, 'cause even if you know it at the beginning it doesn't help.

    The problem with all the above solutions we gave though is that it wastes the fit fields, meaning it can cause either this or another DataField to crash, just because we created all the possible fields (even if we call setData only on one of them)

  • If it's free text that's another story, 'cause even if you know it at the beginning it doesn't help.

    I realize it's not the same situation, but my point was that the same solution can be used for both free text and OPs problem.

    And it's not exactly another story: in both cases the label is not known at the time the field is created.

    it wastes the fit fields

    As noted.

    Except for the solution where you use a single string field and combine the label with the value, unless ofc there is also a per-activity limit on total CIQ FIT field size, as well the limit on number of fields.

    This solution might also be a bit more user-friendly then having 2 fields.

    I guess it all depends on:

    - whether the session field is meant for end-user consumption (in which case a string should hopefully be ok), or whether it needs to be parsed by a 3rd party app or site (in which case non-numeric data may not be convenient or even feasible.)

    - whether the value + label can be guaranteed to fit into 31 characters (the limit is 32 bytes including nul terminator)

  • Thanks for the replies everyone! The idea was to make a summary table of two columns, and due to dynamic field labels to save the limit of 32 bytes. String fields are not an option at all, too much memory is used for them. It seems that the most reasonable solution is to output two fields sequentially, in pairs, the first column of the table, the second column, the first, the second and so on is the most reasonable solution. If UINT8 is used, such a table can be quite large

  • Interesting use case!

    It seems that the most reasonable solution is to output two fields sequentially, in pairs, the first column of the table, the second column, the first, the second and so on is the most reasonable solution. If UINT8 is used, such a table can be quite large

    Do you mean that you’ll have 32 UINT8 summary fields in your data field app? (Sorry if I misunderstood.)

    I don’t think that will work — last time I heard, the total CIQ FIT field limit for an entire activity was 16 fields [*]. Even if an individual data field stayed under the limit (e.g. by creating exactly 16 fields), a 2nd data field which also created fields would crash if it went over the per-app limit. (Ofc you can’t control which field gets to go first, so it’s possible that your field would be the one that crashes)

    [*] when this limit was discussed, most watches only allowed up to 2 CIQ data fields in a single activity. Fenix 8 supports 4 fields, and it’s not clear whether the per-activity CIQ FIT field limit has changed

    Couple of other ideas:

    1. if the data isn’t meant for end-user consumption, you could have 8 UINT32 fields and pack 4 bytes into each of them, for a total of 32 values. You could even have more fields than that, but you run the risk of going over the limit if another CIQ data field is present in the activity

    2. you could try to save array data (with count > 1). Ofc if string data takes too much memory, then I guess array data has the same problem. Other problems:

      - array data may not be supported by all devices (I used to think it wasn’t supported at all until someone mentioned differently)

      - even if it’s supposed to work on a given device, people have reported bugs (such as the device crashing when you try to write multiple values, or only the first value being written)

      - it probably won’t be rendered properly in Connect (if it all)

  • Do you mean that you’ll have 32 UINT8 summary fields in your data field app? (Sorry if I misunderstood.)

    You got that right. Of course I didn't plan a 2x16 table, but 2x10 is possible. I would like to have it all in an easy to read form, thanks for reminding me that I am not the only player on this field, so I will reduce my appetite :)