Review of Run App

Posted on
of 8
  • Hi, I'm back. I feel like Cassandra, bringing the bad news all the time.
    The run app has a bug in settings that makes setting up boxes challenging. Whenever a box is set up to the same setting as another box, it cleans all the previous boxes. If it's unclear, just try to set up 3 boxes and you'll (very likely) see everything else disappear.
    By the way, about notifications, I suspect it's difficult to differenciate different patterns. If someone wants to setup different values. Maybe patterns with silences would be nice.
    eg: non buzzing is ()
    long buzzing is -
    short buzz is .
    maybe some patterns like -()- and -()-()- would be more easy to differenciate from -- and -.- and ---.

  • Whenever a box is set up to the same setting as another box, it cleans all the previous boxes

    You didn't try and set all boxes to the same thing did you? Because I actually added that behaviour because of an issue someone reported.


    Only thing I'd say about GPS altitude is IMO it's not that accurate - I forget the figures but because the GPS satellites are spaced out, GPS altitude accuracy is maybe 5x worse for altitude than lat/lon. However, actually using the built-in barometer, and then calibrating the altitude based on the GPS value when you start (if available) feels like it'd work really well.

  • There was a bug also. At the end of the run, I stopped the run app and... The recorder app was still on "on", stopping the run app didn't trigger "off" in the recorder. I had to go into settings/recorder to actually stop the recorder.

    I suffered recently this bug in bangle.js1, not only a record continua after stop but also after kill/exit Run it was recoding.

    I think the goals defined for "run" are out of the capacity of bangle.js1 specs.
    Is it possible to develop "Run" in modular way, so some functions can be optional; it can be good also for experimental features.

    I mean setting the dashboard interface is cool but most people will no customize, and low specs hw like bangle.js1 prefers the lack of gold plating :D

  • I didn't try that no :)). My problem is that I don't even need to select the content of a box to trigger that reaction, if I just scroll it (without selecting it) it cleans everything else. It makes the setting of the boxes very difficult.

  • @Gordon this is because the if check is happening in onchange, which is triggering even when the value isn't submitted.

    Edit: I was looking at master and not the RELEASE_2V12 tag for this analysis, which might still be true for master, but does not apply to this discussion. RELEASE_2V12 analysis appears below.


    If I'm reading it correctly it looks like there is a discrepency in E_showMenu_Q3.js where if the list is short it will use Bangle.setUI directly with updown and it will only call item.onchange when an item in the list is selected (dir is not set in the Bangle.setUI cb), but E.showScroller fires select (and therefore E.showMenu's item.onchange) every time the scroll position is updated.


    E_showMenu_Q3.js will trigger onchange every time the menu calls move.

    If that analysis is correct it would be nice to rectify it and have two functions, one for as the item scrolls and one for as the item is saved. For RELEASE_2V12 it would be straightforward to leave onchange where it is called within E_showMenu_Q3's move and add something like onsave to the else where the selection is made, but for the code in master it's not as straightforward.

  • My child had a run this weekend.
    The distance was 1500m.
    Unfortunately, I could not fully measure this run with the app, because the distance is rounded mathematically.

    With a planned distance of 15km, the app would already show 15km after 14501 meters.

    I think it would be better to round off the measured distance.
    Or is it just me who feels this is wrong?

  • I totally agree!

    Similarly, with the en_US locale I don't get much benefit from the distances before 1 mile being shown in yards and would rather it be in tenths of miles. Does anyone else have an opinion of that?

  • In terms of horizontal GPS accuracy, using raw position fixes is going to produce a zig-zagging line between two points so the measured distance is always going to be greater than the actual straight line distance.

    I wrote my own running app and I use a rolling average of 6 points (1 Hz rate) and then also apply a minimum distance of 7m between distance calculations. This filtering produces fairly good results. My running buddies mostly have Apple watches and my distances agree with their distances well.

    In terms of elevations, I use the barometer to measure elevation differences. I use the average GPS elevation from the first few minutes before my run as the start elevation. I also use a rolling average on the barometric readings.

    In terms of the net elevation changes, for a typical run in very hilly terrain over about an hour and a half, I have recorded up to 300m or so of up and 300m or so of down. So far, the net difference between ups and downs have been around 5m or less. This is much better than what my buddies' Apple watches show for elevation changes. For my measurement of +/- 300m, the Apple watch was in the range of +300m, -150m.

    Given the good elevation results, it appears that the atmospheric conditions are fairly stable over a period of couple of hours. If the weather conditions are changing rapidly, things will probably be not so good.

  • @BillM can we test your running app?

  • Yes. I can provide my app for testing. I don't think it's ready for prime time yet, since there are things that need to be cleaned up (unused code, variables). I will need to do short write-up, but that can be done quickly.

    What's a good way to make it available for testing?

  • If I remember correctly there is something in the official documentation.

  • What's a good way to make it available for testing?

    Maybe­oader - so just create your own fork of the app loader but with your app added - then anyone can go to the link and install it like from the normal app loader.

    And yes, a different distance rounding could be good. There was some discussion about updating the locale module to include different roundings and I'm pretty sure someone said they were going to contribute something, but that hasn't happened yet

  • Just to add, issue with number accuracy was­ssues/1523 - I've just pushed a fix to the development app loader now so if you update locale and the run app you should get much more sensible distance rounding

  • @Fteacher FYI, Gordon got the the box settings problem is fixed in 0.13.

    Also, I have a Polar H10 arriving today and after getting used to it for a couple of runs I can start looking at the HRM alarm configuration we discussed the other day.

  • Thanks @GrandVizierOlaf . Glad you have your bthrm. If you don't know about it, check what are Karvonen zones, you might be interested. As I mentionned before, having most of my training in zone2 was a game changer, and if you add hrm alarm in the notifications, well that's great.

  • @Fteacher, I haven't forgotten about this but have been working through some quirks with the Polar H10 and BTHRM app. Do you mind doing a test with your OH1 if you get a chance? We're trying to determine if the Bluetooth address is changing on a common device that is powered on and off.

    @Gordon will you make sure I'm not crazy here based on our BTHRM discussions?

    1. Open the web IDE and connect to your watch
    2. With the HRM off, execute this command:

      NRF.findDevices(function(d) {
      }, { timeout: 4000, active: true, filters: [{ services: [0x180D], }] });
    3. Turn the HRM on

    4. Make sure your HRM is set to be discoverable, likely from the Polar app

    5. Run the same command as above (you might need to give it a minute to start broadcasting)

    6. Power off the HRM, wait a few minutes, and run the same command as above

    7. Turn the HRM back on and run the same command as above

    8. Paste the results of the test here or at least let us know if the discovered BluetoothDevice had a different id after power cycling

    I'm also curious what Espruino firmware you're on and if the BluetoothDevice has a name, but that is more a curiosity around the original issue I had with my H10 which has since been fixed.

  • Did the experiment. ( [], [data], [], [data])
    Id stayed the same (even though having the word "random" at the end.

  • Fantastic, thanks @Mi!

  • What does this mean? (don't know what "our BTHRM discussions" was about)
    What problems did you have before?

    Actually in a python app here I did include the id hardcoded to make sure to not get the H10 of my wife. So very sure id stays the same also over long time.

  • Here's the quick answer with too much information:­ull/1655

    Basically, trying to make connection improvements to the BTHRM app without breaking backwards compatibility.

    I'm happy to talk more about it after getting the kids off to school.

  • Just to make sure there is no misunderstanding:
    I did the test with H10 (we need @Fteacher for the OH1)

  • I should be able to do that within 24 hours @GrandVizierOlaf .
    Btw, maybe we should add infos about the compatibility of the different hrm we're using to the bthrm app, in the "about" section.

  • @GrandVizierOlaf , @Gordon , @Mi I just did the test with a 2 minutes break. The id stayed the same, but "rssi" and manufacturerData" changed (I have no clue what these are but I mention it in case it could be interesting for something else)
    ( [], [data1], [], [data2])
    data1 [
    BluetoothDevice: {

    "id": "a0:9e:1a:57:52:2b public",
    "rssi": -54,
    "data": new Uint8Array([19, 9, 80, 111, 108, 97, 114, 32, 79, 72, 49, 32, 53, 55, 53, 50, 50, 66, 50, 69]).buffer,
    "manufacturer": 107,
    "manufacturerData": new Uint8Array([114, 8, 150, 214, 167, 2, 0, 0, 0, 0, 122, 1, 5, 35, 0, 56]).buffer,
    "services": [
    "name": "Polar OH1 57522B2E"

    data2 [
    BluetoothDevice: {

    "id": "a0:9e:1a:57:52:2b public",
    "rssi": -51,
    "data": new Uint8Array([19, 9, 80, 111, 108, 97, 114, 32, 79, 72, 49, 32, 53, 55, 53, 50, 50, 66, 50, 69]).buffer,
    "manufacturer": 107,
    "manufacturerData": new Uint8Array([114, 8, 150, 214, 167, 2, 0, 0, 0, 0, 122, 1, 5, 39, 0, 59]).buffer,
    "services": [
    "name": "Polar OH1 57522B2E"


  • Thats interesting. Do we know who gets public and who random addresses?
    Is that device type dependent (so do all H10 have random?) or configured when cloud connected?

    [rssi = Received Signal Strength Indicator, so change is to be expected here due to distance difference.]

  • Wonderful, thanks! To add to what @Mi said, the manufacturerData is your actual health data. Without looking up the spec I would assume that a large part of it is the PPG data and it ends with your HR, the 59. For the curious, you can also pick out how the name is encoded in the data section;

    19=read 19 bytes with the next byte explaining the section
    9=what follows in the other 18 bytes name of the device

    @Mi, the id scheme is up to the manufacturer, but follows a spec. This is the summary that made the most sense to me. Given that the H10 rerandomizes after pulling the battery I was a little concerned that the OH1 might do the same after a power cycle or be of a type that expects bonding (given that BTHRM was connecting by name before and that wouldn't be changing), but that is not the case given @Fteacher's data. It might have a method to factory reset the device which would cause it to rerandomize, but that is fortunately not our concern.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Review of Run App

Posted by Avatar for HughB @HughB