Sensor list

I'm writing a start screen for my first app and I'm trying to display on connectivity overview which would include GPS status, phone connection status, HR, power meter and Di2 device list with battery statuses, where applicable. AntPlus.Shifting will probably cover the Di2 and AntPlus BikePower the power meter but where I don't see any subclass for the HR. What is that under? FitnessEquiment?

And can you use the AntPlus.DeviceListener onDeviceStateUpdate for detecting when any AntPlus device changes status? 

Thanks in advance,

  Nik

  • Yep, I suspect that most external HR devices have a replaceable battery so it would have to have some external way of measuring the remaining charge (and even then it wouldn't know what the max charge would be to get a percentage from) in contract to rechargeable batteries which probably have built-in electronics/interfaces for the purpose...

  • No, I just think it's not available for some devices.  With Sensors like the tempe, footpod, rd pod, you will get a message when the battery in the sensor is low.  Probably the external HR too, but I change the battery often enough that I don't see that one.

  • HR is one of the oldest ANT+ device profiles.  Based on the ANT+ device profile page battery optional for the HRM.  I have yet to see an HRM offer it.

    www.thisisant.com/.../

  • I have Polar H10 HRM (dual-BLE and ANT+), and it does provide the battery level info. I can see that from sensor details on Garmin devices, and even get prompts for low battery.

  • Hi Nik  - I'm hoping to add a set of alerts to another data field I wrote.... code that'll keep track all the connected sensors (I just use ANT+ for now: speed, cadence, power, HR, VIRB Camera, inREACH Satellite Tracker, headlight, taillight). And pop up an alert if a sensor disconnects or if the battery drops to a LOW level.

    You mention it is easy to do this using the ANTPlus calls for some of those device types. Not HR apparently. So probably just speed, cadence, power and lights.

    I'd love to see an example of working code to check, say, a cadence sensor's battery level. How you set up the listener, detect the sensor, and grab the battery level.

  • Easiest way is to use polling, you don't need listener for that:

    class myDataField extends WatchUi.DataField {
        var myDevice = null;
    
        function initialize() {
            myDevice = new AntPlus.BikeCadence(null);
        }
        
        function compute(info) {
            var battStatus = myDevice.getBatteryStatus(null);
            if (battStatus != null) {
                Sys.println("Battery status: " + batteryStatus.batteryStatus + ", voltage: " + batteryStatus.batteryVoltage);
        }
    }

    For lights, it's a bit more complicated:

    forums.garmin.com/.../how-to-get-the-battery-of-the-bike-light

    So you get null if sensor is not connected or data not available. You can check the connection state using getDeviceState():

    var devState = myDevice.getDeviceState();
    if (devState != null) {
        System.println("Current device state is: " + devState.state);
    }

  • It's not much more difficult to set up listener either, extending the previous example you can have both polling and listener if you want:

    class myDataField extends WatchUi.DataField {
        var myDevice = null;
    
        function initialize() {
            var myCadenceListener = new MyBikeCadenceListener();
            myDevice = new AntPlus.BikeCadence(myCadenceListener);
        }
        
        function compute(info) {
            var battStatus = myDevice.getBatteryStatus(null);
            if (battStatus != null) {
                Sys.println("Battery status: " + batteryStatus.batteryStatus + ", voltage: " + batteryStatus.batteryVoltage);
        }
    }
    
    class MyBikeCadenceListener extends AntPlus.BikeCadenceListener {
    
        function initialize() {
            BikeCadenceListener.initialize();
        }
    
        function onDeviceStateUpdate(data){
            Sys.println("Listener: deviceState: "+ data.state);
        }
    
        function onBatteryStatusUpdate(data){
            Sys.println("Listener: batteryStatus: " + data.batteryStatus);
        }
    }

    Perhaps not the most power-efficient way though, maybe better use polling to get initial state at start, and then wait for listener to update.

  • Finally, for every device type you are interested (power, candence, speed etc.), you need to create own device instance of it's subclass (BikePower, BikeCadence, BikeSpeed).

    Same goes with listeners, you need to make your own listener class for each type too (BikePowerListener, BikeCadenceListener, BikeSpeedListener). 

  • Awesome!! This really helps. I'll be able to get my feature working with that help. Thanks!!

  • Strange. Gotta be a very simple issue. I created a simple DF. My ANT+ cadence sensor is paired and reporting battery status and a valid RPM. But my DF reports NULL for battery status. If I can, I'll include my complete code (simple and short). If you have a pointer in what I'm missing to get this working, I'd really appreciate it Kurev.

    using Toybox.Application;
    using Toybox.System;
    using Toybox.WatchUi;
    using Toybox.Lang;
    using Toybox.System;
    using Toybox.Graphics;
    using Toybox.AntPlus;
    
    ////////////////////////////////////////////////////////////////////////////
    class MyANT extends Application.AppBase {
        function initialize() { AppBase.initialize(); }
    	function onStart(dc) { }
        function getInitialView() { return [ new DeviceView() ]; }
    	function onStop(dc) { }
    }
    
    class MyBikeCadenceListener extends AntPlus.BikeCadenceListener {
        function initialize() { BikeCadenceListener.initialize(); }
        function onDeviceStateUpdate(data) { System.println("Listener: deviceState: "+ data.state); }
        function onBatteryStatusUpdate(data) { System.println("Listener: batteryStatus: " + data.batteryStatus); }
    }
    
    
    ////////////////////////////////////////////////////////////////////////////
    class DeviceView extends Toybox.WatchUi.DataField {
        var myCadenceSensor = null;
        var myCadenceListener = null;
        var CadenceBattStatus = null;
    
        function initialize() {
            DataField.initialize();
            var myCadenceListener = new MyBikeCadenceListener();
            myCadenceSensor = new AntPlus.BikeCadence(myCadenceListener);
        }
    
        function onLayout(dc) { }
    
    	// display status on the device's screen
    	function onUpdate(dc) {
            View.onUpdate(dc);
    
    		dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_TRANSPARENT);
            dc.drawText(10,10,Graphics.FONT_MEDIUM,"CADENCE SENSOR",Graphics.TEXT_JUSTIFY_LEFT);
            if (CadenceBattStatus != null) {
    	        dc.drawText(10,40,Graphics.FONT_TINY,"Battery status: " + CadenceBattStatus.batteryStatus + " (" + CadenceBattStatus.batteryVoltage + "V)",Graphics.TEXT_JUSTIFY_LEFT);
    	    }
    		else {
    	        dc.drawText(10,40,Graphics.FONT_TINY,"Battery status: NULL (--V)",Graphics.TEXT_JUSTIFY_LEFT);
    		}
    
    		return;
    	}
    
    	// print status in console and/or to the device log file
    	function compute(info) {
            CadenceBattStatus = myCadenceSensor.getBatteryStatus(null);
            if (CadenceBattStatus != null) { System.println("Battery status: " + CadenceBattStatus.batteryStatus + ", voltage: " + CadenceBattStatus.batteryVoltage + "\n"); }
            else { System.println("Battery status: NULL (--V)\n"); }
    	}
    }