Example data field code, and tests replaying activity scenarios.

Hello,

I made a data field in 2021, to help me with ultra-distance cycling. I didn't really know what I was doing, but it seemed to work pretty well. Like most people I found the dev process pretty clunky, even if the code itself is easy.

In the last few days a user contacted me with a query about inaccurate data (it's now 2025). That prompted me to learn a bit more, rewrite the app, and republish it as a new version. It's been an informative process, though I readily accept I still don't know very much Slight smile

Anyway, I have made my repo public. In particular I found writing and using tests hard to figure out. So hopefully this can help someone else.

https://github.com/thisdougb/SinceStopped

What I was able to do was take scenarios where my data field appeared to be incorrect, and generate Activity.info data to replay those scenarios as tests. So I can generate 5 minutes of movement, then 2 minutes of stationary, etc. Because I am supplying the time as a value, the tests run near instantly.

Once I figured out how to use tests to replay scenarios it made the dev process quicker because I didn't have to rely on the simulator. I still don't really understand how to get the simulator to function predictably.

  • the simulator as the name suggest is simulating "real world" scenarios. It's not meant to be predictive. I'd say that is a feature, not a bug. Especially when you don't replay a recorded fit file but just start it, then it sends random data. Sometimes even crazy data, but it's a bit like the Netflix's chaos monkey (Monkey C pun intended), it helps you find some edge cases. Of course if you know how to write good unit tests, that's even better.

  • yeah, I get that. I tried replaying .fit files, but then I figured out you also have to 'start' the Data Field Timer Controls. Those two things being (seemingly) asynchronous is a bit odd. That more what I meant by not predictable, because you can't start both at the same time, or at repeatably predictable times.

  • Yeah the UX (and as you've found, the actual functionality) of the activity data dialog is really bad. It's changed over the years, but it still has issues.

  • For ages I didn't realise I ad to 'start the device'. Not to worry though, it made me have to learn a bit more. Thumbsup

  • Those two things being (seemingly) asynchronous is a bit odd.

    It kinda makes sense as a real watch can obviously act on sensor data while an activity is paused (or before it starts). So it might work that way to give devs a way to test that kind of scenario.

    But then again, none of the data is ever actually recorded to the FIT file.

    So I guess it depends on whether the goal of the FIT file playback feature is to be as "realistic" as possible (reflecting how the file was actually recorded, in terms of the activity timer) or to be as flexible as possible (allowing the timer controls and playback controls to be completely independent).

    It probably also has something to do with the fact that same controls are used for both data simulation and FIT playback. For data simulation is absolutely is "realistic" that data continues to be simulated regardless of whether the timer is started or stopped, as this is exactly how the real watch works.

    I think a good feature request would be to have the option of synchronizing the two sets of controls, so that starting the timer also starts playback, and stopping the timer pauses playback. This option could even be enabled by default.

    Going back to the UX of the activity data dialog, it does seem super confusing to have 2 completely independent sets of controls (timer start/stop, data start/pause).

  • For ages I didn't realise I ad to 'start the device'.

    I'm pretty sure this has happened to literally every new CIQ dev.

    They have tried to change the dialog to make it more user-friendly, but I'm not sure if it's quite there yet.

  • My wrong assumption was that replaying the .fit file replays what happens on the device. So you can sort of create scenarios on the device and replay them. Of course, I know that timer states aren't in the .fit file. But in developer mode/focus, with all the other challenges there are doing data fields, I got sucked into that assumption.

    I think you're right, treating timer state and .fit file as parallel tracks would be good. A bit like video editors, where video and audio are linked until you unlink them. Replayed on the same timeline. 

  • Of course, I know that timer states aren't in the .fit file

    Actually, they are. Timer start/stop events are recorded in the FIT file, which is why external sites like runalyze.com can show you the activity time [or "timer time" as Garmin calls it *] and duration for every pause.

    [*] tbf "activity time" probably isn't any better than "timer time"

    You can see the timer start/stop events in www.fitfileviewer.com (look in the Event table)

    But you are correct, using the FIT file as a data source does not literally replay what happens on the device. It's more like it's a practical way of feeding sensor data to the app, and it's apparently treated no differently than sensor data simulation.

    Honestly I don't know of a good way to fix this, given that the simulator just treats the FIT file as one of two possible data sources, as opposed to giving devs a way to literally replay an activity.

    Maybe have a literal replay mode? (Should this include lap, workout and multisport events? How would this work if you paused the activity for 2 hours? Do you have to wait 2 hours or fast forward through that time? Should there be an option to include/exclude pauses? Ofc the FIT file won't have any data during the pauses, either way.)

    Maybe just have the option for synced controls?

  • ha, another assumption fixed.

    I think a literal replay would give the opportunity to use the device to record various test scenarios. Which would be pretty useful.

    Having said that, it's (I now realise) easy to do the same thing with tests. And they get added to version control. This was enough for me because I was only working on timing data, rather than coordinate data.

  • For ages I didn't realise I ad to 'start the device'.

    I'm pretty sure this has happened to literally every new CIQ dev.

    The other thing that has always tripped up new devs is that if you press Save Fit Data without pressing Save in the timer controls, you end up with a corrupt FIT file.

    This goes back to how it's very unintuitive for the simulator to have separate controls for FIT data and the timer, given that it's a single set of controls on a real watch.

    Having said that, I get why this was done, and I really don't know if I have any better ideas.