Smart Bike Lights (Data Field) / Bike Lights Control (Widget)

I've made two open source CIQ applications to control ANT+ lights:

- Smart Bike Lights (data field): https://apps.garmin.com/en-US/apps/0d9fd828-c932-4470-9c37-fd2828881888 

      Configurator: https://maca88.github.io/SmartBikeLights/ 

- Bike Lights Control (widget): https://apps.garmin.com/en-US/apps/fa3c2332-76e3-4ba1-8528-32a0fd617ab1 

     Configurator: https://maca88.github.io/BikeLightsControl/ 

Smart Bike Lights features:
- Automatic light control (Smart mode) based on the configured filters (sunset, sunlight, speed, ...)
- Manual light control (only for Edge devices with a touch screen or devices with CIQ 3.2 and more than 32KB memory)
- Records lights modes that are displayed in Garmin Connect

Bike Lights Control features:
- Manual light control (available to all devices)

Both applications can be installed on the same device, which can be useful for low end devices (e.g. Edge 520) where "Bike Lights Control" can be used to change light modes manually and "Smart Bike Lights" for automatic light control.

Currently registered ANT+ lights:
- Bontrager Ion Pro RT
- Bontrager Ion 200 RT
- Bontrager Flare RT
- Garmin Varia RTL500
- Garmin Varia RTL510
- Garmin Varia RTL515
- Garmin Varia HL500
- Garmin Varia UT800

in case your ANT+ light is not on the list you can help by doing the following:

1. Install Bike Lights Control
2. Pair your bike light with your Garmin device
3. Open the widget:
- Edge with a touch screen: post which numbers are displayed on the buttons and what mode each button represents when pressed
- Other devices: Select the "Light modes" menu and post which numbers are displayed in the menu and what mode each menu item represents when selected

Example for Bontrager Ion Pro RT:


1 -> High steady beam
2 -> Medium steady beam
5 -> Low steady beam
63 -> Day flash
62 -> Night flash

There are some features that could be possible to add in the future, but would require Garmin to add them to the CIQ api. In case you are interested in any of the below features, consider upvoting their feature request thread:

1. Control lights based on the ambient light sensor available on some devices:
https://forums.garmin.com/developer/connect-iq/i/bug-reports/ambient-light-sensor-api-access 

  • version 0.29.0 it is possible to use /n

    Amazing speed, thanks!. Now I can use: \n

    Regarding, "Group name visibility" - it will show which filter group active? (automation)

    Added these two modes to the light configuration

    Now I can add them - thanks!

    Do note that the battery level reported by the light via ANT represents a range, where the range is not documented

    Yeah, I thought you have 5 levels, and can roughly assume each level is about 25%, but I see that each level can have different range.
    But, now I do this calc manually - if I see battery on 3 lvl, and this mode is about 4h runtime, I just -50%, and I know that I will not have more than 2h runtime .
    I was thinking if that calc, can be visualised

    Currently my Di2 with single click - trigger all my lights to go flash, which I like this. Then I double click - and all lights go off, or single press and all lights go to solid mode. So, this works for me when I want quick alert.
    And then I need go to Smart Bike Lights data screen - and set back to Smart.
    What, I'm missing: only some fast way to switch back to smart mode (now I have two pages, 3-4 lights - so need to press on each)

    Also, after new version I found a bug:
    I have two pages #1 (AT1600 & Flare RT)  & #2 (Varia 515).
    Now on page #2 - where I have only Varia 515 (because headlight is on #1) - now I see Headlight (AT1600) values (numbers) - which I don't need, because it's already on page #2. Please can you check this, this is my config:

    ###0,73535488:1,1362494500:1:#7,3!CarD:3:7:5:0Er0,s0H]2I]-1]0!CarN:3:6:5:0Es0,r0H]2I]-1]0!:1:0:0:0D=1##6,5:Varia 515:0:16777215:0!2,:-1,Lights Off:0!1,Solid  \n20lm-6h:4!1,Peloton  \n8lm-8h:5!1,Day Flash  \n65lm-16h:7!1,Night Flash  \n29lm-6h:6#0::#0:0#123!:123!#0#0#B3843##3#0#0

    And other bug: button text is cut at the end, if I have "Night Flash  \n29lm-6h" - it will be missing last "h"

  • "Group name visibility" - it will show which filter group active? (automation)

    Yes, it will show the name of the active filter group.

    Also, after new version I found a bug:

    My bad, I mistakenly introduced a regression with the last version. Now this should be fixed with version 0.29.1.

    And other bug: button text is cut at the end, if I have "Night Flash  \n29lm-6h" - it will be missing last "h"

    Fixed in version 0.29.1.

  • Fixed in version 0.29.1.

    Thank You!  awesome, now it works as expected.

    I recently got Transmitr MicroRemote, I tested - seems working like a charm.
    Seems quite hard to get a lot from one button Slight smile, but with your app logic I can have good functionality. (just I need small pause after each click, speed limitation - but I guess it's hardware limitations. In overall: it's working great)

    Now I have almost perfect config, just missing last bit: Di2 D-Fly button capture:
    - maybe you can capture when Di2 try to change light: onBikeLightUpdate(), for example I would like configure logic similar way like with Transmitr MicroRemote: if Di2 try to set LIGHT_MODE_OFF (Di2 double click), then I would like to switch to 'Smart' - all lights, if 'Smart' mode already enabled then switch 'Off' - all lights.
    I think at least 'LIGHT_MODE_OFF' no one else is sending, it should be remote, or maybe manual press on device  Slight smile (but manual press on device, should be individual, not global)


    P.S> Di2 D-Fly button set global values - apply to all lights connected (change light mode, or set off), not individual lights - so maybe you can detect if that is individual change (press on light), or global change (press Di2 button, or any other remote - Garmin also have remote devices). I think Garmin Light Widget - send the same values as Di2 D-Fly buttons, I guess Di2 just trigger these, like all other Garmin remote devices.

    I guess it use: setHeadlightsMode() & setTaillightsMode() instead of setMode(), not sure if LightNetworkListener can differentiate.

     

  • This is my current draft config (need to fine tune braking values), it allow me save battery and automate scenarios, also if I need I can switch to manual always Slight smile

    Smart Bike Lights #1 data field
    HeadLight: Magene AT1600. Taillight: Trek Flare RT

    Flash Config: (single ride)
    #16384,90382865:1,2147483647:1:#7,4!Speed:2:3:20:0C]6.66667Es0,r0!Night:2:5:60:0Es0,r0H]2!Day:2:0:60:0Er0,s0H]2!:1:0:0:0D=1#6291461,1409482753:0,889104606:1:#11,5!BreakD:3:1:5:0Er0,s0H]2A[-20!BreakN:3:5:5:0Es0,r0H]2A[-20!Day:2:8:60:0Er0,s0H]2!Night:2:63:60:0Es0,r0H]2!:1:0:0:0D=1#11,10:AT 1600:0:16777215:0!2,:-1,Off:0!1,Very High  \n1600lm-1.5h:1!1,High  \n1200lm-2h:2!1,Medium  \n800lm-3h:3!1,Medium-Low  \n600lm-4.5h:4!1,Low  \n400lm-6h:5!1,Very Low \n200lm-12h:59!1,Pulse \n 300/50lm-13.5h:60!1,Slow Flash:6!1,Fast Flash:7#8,7:Flare RT:0:16777215:0!2,:-1,Off:0!1,Day Steady  \n25lm-4.5h:1!1,Night Steady  \n5lm-13.5h:5!1,Day Flash  \n90lm-6h:7!1,All-Day Flash  \n45lm-12h:8!1,Night Flash  \n5lm-15h:63!1,:-2#0::#0:0#123!:123!#0#1|1:MicroRemote!1|1:21356:0!3|1:1:0:3!1,3,5,59,60:0!!|2:2:0:0=:,0=:!N|0!:,0!:|1:2:0:3!0:3!0!#B3843#14#1#0#0

    Steady Config: (group ride)
    #16384,90382865:1,2147483647:1:#7,4!Speed:2:3:20:0C]6.66667Es0,r0!Night:2:5:60:0Es0,r0H]2!Day:2:0:60:0Er0,s0H]2!:1:0:0:0D=1#6291461,1409482753:0,889104606:1:#11,5!BreakD:3:7:5:0Er0,s0H]2A[-20!BreakN:3:63:5:0Es0,r0H]2A[-20!Day:2:5:60:0Er0,s0H]2!Night:2:5:60:0Es0,r0H]2!:1:0:0:0D=1#11,10:AT 1600:0:16777215:0!2,:-1,Off:0!1,Very High  \n1600lm-1.5h:1!1,High  \n1200lm-2h:2!1,Medium  \n800lm-3h:3!1,Medium-Low  \n600lm-4.5h:4!1,Low  \n400lm-6h:5!1,Very Low \n200lm-12h:59!1,Pulse \n 300/50lm-13.5h:60!1,Slow Flash:6!1,Fast Flash:7#8,7:Flare RT:0:16777215:0!2,:-1,Off:0!1,Day Steady  \n25lm-4.5h:1!1,Night Steady  \n5lm-13.5h:5!1,Day Flash  \n90lm-6h:7!1,All-Day Flash  \n45lm-12h:8!1,Night Flash  \n5lm-15h:63!1,:-2#0::#0:0#123!:123!#0#1|1:MicroRemote!1|1:21356:0!3|1:1:0:3!1,3,5,59,60:0!!|2:2:0:0=:,0=:!N|0!:,0!:|1:2:0:3!0:3!0!#B3843#14#1#0#0

     Break Config: (off - except when break)
    #16384,90382865:1,2147483647:1:#1,1!:1:0:0:0D=1#6291461,1409482753:0,889104606:1:#7,3!BreakD:3:1:5:0Er0,s0H]2A[-20!BreakN:3:5:5:0Es0,r0H]2A[-20!:1:0:0:0D=1#11,10:AT 1600:0:16777215:0!2,:-1,Off:0!1,Very High  \n1600lm-1.5h:1!1,High  \n1200lm-2h:2!1,Medium  \n800lm-3h:3!1,Medium-Low  \n600lm-4.5h:4!1,Low  \n400lm-6h:5!1,Very Low \n200lm-12h:59!1,Pulse \n 300/50lm-13.5h:60!1,Slow Flash:6!1,Fast Flash:7#8,7:Flare RT:0:16777215:0!2,:-1,Off:0!1,Day Steady  \n25lm-4.5h:1!1,Night Steady  \n5lm-13.5h:5!1,Day Flash  \n90lm-6h:7!1,All-Day Flash  \n45lm-12h:8!1,Night Flash  \n5lm-15h:63!1,:-2#0::#0:0#123!:123!#0#1|1:MicroRemote!1|1:21356:0!3|1:1:0:3!1,3,5,59,60:0!!|2:2:0:0=:,0=:!N|0!:,0!:|1:2:0:3!0:3!0!#B3843#14#1#0#0

     

    Smart Bike Lights #2 data field
    Varia Radar 515

    Lights Off Config: (flash only when car detected, if I want I can switch back to manual)
    ###0,73535488:1,1362494500:1:#7,3!CarD:3:7:5:0Er0,s0H]2I]-1]0!CarN:3:6:5:0Es0,r0H]2I]-1]0!:1:0:0:0D=1##6,5:Varia 515:0:16777215:0!2,:-1,Lights Off:0!1,Solid  \n20lm-6h:4!1,Peloton  \n8lm-8h:5!1,Day Flash  \n65lm-16h:7!1,Night Flash  \n29lm-6h:6#0::#0:0#123!:123!#0#0#B3843##3#0#0

  • (just I need small pause after each click, speed limitation - but I guess it's hardware limitations.

    Are the buttons from Di2 more responsive? If yes, then I may need to revisit the code in order see whether it can be improved.

    Now I have almost perfect config, just missing last bit: Di2 D-Fly button capture:

    Yes, that’s the next thing I’ll be working on, though it may take some time to implement.

    Di2 D-Fly button set global values - apply to all lights connected (change light mode, or set off), not individual lights - so maybe you can detect if that is individual change (press on light), or global change (press Di2 button, or any other remote - Garmin also have remote devices)

    I am not sure yet, but I think I will make the configuration similar as for the remote controllers. As an example, you will be able specify an action to change to smart mode when headlight and taillight are both off. The only difference is that the configuration will most likely be on the light level and not global as remote controllers.

  • Are the buttons from Di2 more responsive? If yes, then I may need to revisit the code in order see whether it can be improved.

    I will check, but Di2 (or Garmin) have only 3 modes: flash, solid, off
    So, usually I need only one click at a time, because there is not much modes.
    With your app I can use all modes, for example AT1600, I have a lot more options (~10) - so when I need to select specific mode I need cycle through more modes, and I can't press multiple clicks fast forward, need to add delay after each click.

    Yes, that’s the next thing I’ll be working on

    Fantastic!

    The only difference is that the configuration will most likely be on the light level and not global as remote controllers

    Please make option - to select which lights control (single / multiple), similar way like you have with remote controls

    Di2 button examples:
    Single Click: turn On first selected mode from list (e.g. Flash mode), then if next click in 5sec range  -> Cycle through modes, and if next click after 5sec -> again starts from first mode (e.g. Flash mode)
    Double Click: if (mode != 'Smart') { switch 'Smart'} else { switch 'Off'}