What is the purpose of Toybox.Activity.Info.offCourseDistance?

I have a Garmin Edge 1030. When I am riding a course, the data field Dist. to Next shows the remaining distance to the next course point (situation 1). When I am riding off course, this data field shows a value that I think is the smallest distance between my current location and the nearest point on the course (situation 2). There is no documentation on the behavior of situation 2 in the Edge 1030 manual, but from experience, I believe that this is indeed the case. When I am riding off course, the value in this field decreases as I am nearing the course, and becomes 0 when I am back on course.

According to the API documentation, the attribute offCourseDistance in class Toybox.Activity.Info contains the distance to the nearest point on the current course in meters. Therefore, I assume that this attribute contains the value that is displayed in the data field Dist. to Next when I am riding off course (situation 2). I have tested this with a data field that shows info.offCourseDistance (in fact, it logs info.offCourseDistance with a System.println statement). However, the value of offCourseDistance is always null. It is even null when I am riding a course and I deliberately go off course. In this case, the data field Dist. to Next shows the distance between my location and the nearest point on the course, and I expected info.offCourseDistance to contain the same value. But obviously it does not.

Is this a bug? Is this intended behavior? If so, when does offCourseDistance have a non-null value? Does it matter if the Off Course Warnings setting on the Edge is on or off?

(As a side note, the API documentation is sometimes very minimal. For example, it would be useful if the documentation on e.g. the offCourseDistance attribute indicated when the value equals 0.0, and when the value equals null (for example, if there is no course, or whatever). The simulator does not help in these cases, in the simulator offCourseDistance is always 0. The simulator does not simulate the Edge 1030 in this case.

The lack of useful documentation is not limited to offCourseDistance. For example, from trial and error I have learned that info.elapsedDistance equals null when the timer on my Edge is not active, but info.timerTime equals 0 in this case. I am sure that there is a good reason for elapsedDistance to be null instead of 0 and for timerTime to be 0 instead of null, but I cannot think of one. Documentation on the values of attributes that a developer can expect in certain situations would be a great improvement.)

  • If timerState == TIMER_STATE_OFF ("The timer is off. There is not an active recording" according to the API doc), there is no timerTime, so maybe in this case null would make more sense than 0? A timerTime of 0 would then indicate that the timer has been switched on, but e.g. was immediately auto-paused, and therefore there is no elapsed time.

    When you are saying that it is up to the firmware, where the data is generated, does this mean that different devices can produce different values for an attribute in equal or similar situations? For example, that there can be a device where info.elapsedDistance is 0 and not null when there is no active recording?
  • I think he’s saying that you can’t rely on undocumented/unspecified behaviour like this to be consistent across all devices and at all points in the future. However, I could be wrong, but I think elapsed distance is always null when the timer hasn’t started.

    One example of quirky undocumented differences is that for some Fenix watches, when you discard an activity your data field app doesn’t restart, but onTimerReset is called. For forerunners (including 935 which is supposed to be similar to Fenix 5), when you discard an activity your app restarts on the real watch, if not in the simulator. (I may have gotten the device specifics wrong there, so don’t quote me. I’m sure about the 935 behaviour tho.)
  • Anyway, what I do for data field apps with respect to displaying null is:
    - For null time/pace I display "--:--".
    This includes paces derived from speeds of 0, since in that case the pace is undefined (or infinite time per unit distance). Of course, time will never be null, but that's what would I display if it was.

    For some apps if the pace is slower than around 59:59 per km or mile, then I also display "--:--", because it looks better (nobody wants to see paces like 1:30:00 per km, if you're moving very slowly) and because that's also what the native apps would do.

    - For any other null values, I display "--"
    This has led to some comments asking why I display "--" for distance before activity start, but I sort of brush them off.

    If you wanted to be exactly like the native activities, then you would have to make the exception for distance where a null distance would be displayed as 0.00.

    In general I don't know if users really care. I've seen data fields that display 0 when your HR or power is null, which I think is completely wrong, but it doesn't seem to bother anyone else.
  • I have to agree it'd be nice if things were more consistent. I just try to remember how much better things are now than a couple years ago when I was still trying to make things work on the Epix. This is still a fairly new environment and obviously still showing growing pains. I'm hoping that devices will get more consistent as CIQ matures. Just having so many more apps as test cases should help.

    I'd also like to see better documentation. Right now there is just the bare minimum and it does require a bit of trial and error. Sample code is helpful, but not a replacement.

    One problem that we keep seeing in many threads here is that it's nearly impossible to know exactly how something will behave on any given device. But given that most people do this development as a hobby, there is no way to expect people to have all the devices necessary for full testing.
  • One problem that we keep seeing in many threads here is that it's nearly impossible to know exactly how something will behave on any given device. But given that most people do this development as a hobby, there is no way to expect people to have all the devices necessary for full testing.


    This is something I cannot emphasize enough. The problem is that if Garmin keeps the status quo this way, CIQ will remain either:
    - A side project for big companies where maybe they'll test on all the real physical devices. You can find an app from a popular company that sells expensive gear with a review that states the app isn't coded properly for VAHR (because the activity is started using a screen tap instead of the physical start button).

    - A "fun" toy for hobbyists, where we release apps that may or may not work for your device.

    Well guess what, it's not so "fun" when you release something you thought was cool, and it just doesn't work for some people. It's frustrating and a little embarassing.

    I would like to see Garmin update the simulator with the real behaviour for the real devices, including bugs, quirks and inconsistencies. I also want to see behaviour that's not visible/overrideable by apps to be simulated, like "hold X for controls/settings menu" and "VA3 KEY is not supported for widget." Currently the situation is that the simulator pretends that apps can see certain keypresses which they can't in real life.

    I don't see the point of simulating some idealized version of a 230 (for example) that doesn't exist anywhere in real life.

    Sure I know people IRL who still own 235s or whatever. But I don't want to harass all my running friends into testing my apps for me. And I'll never be able to find ALL of the older devices to test with.

    I get that Garmin is doing things differently now, where most of the new devices at least have the same resolution and screen shape. But lots of people still own old devices. As a hobbyist I would like to support all of those older devices. But sometimes it doesn't seem worth the trouble.

    EDIT: I'm sure Garmin sees no benefit in supporting older devices in any way. Management would probably love it if nobody released apps for the older devices anymore. So I don't expect that part to change.
  • Getting back to the original topic of this thread, namely the value of offCourseDistance: I have done some further testing. It turns out that the value of offCourseDistance is always null when the Off Course Warnings setting on my Edge 1030 is off. When this setting is on, offCourseDistance is null when I am not off course, and some value (sometimes null, sometimes a numeric value that is never equal to the value in the native data field Dist. to Next) when I am off course.

    I believe this to be a bug, and I have submitted a bug report:

    https://forums.garmin.com/forum/developers/connect-iq/connect-iq-bug-reports/1442717-toybox-activity-info-offcoursedistance-is-always-null-when-off-course-warnings-is-off
  • I posted in your bug thread, but I don't think you should expect offCourseDistance to equal distanceToNext most of the time.