Inconsistent sensor API urgently needs a rewrite

Former Member
Former Member
It's probably for historical reasons, but why is it that not all sensors are accessed by the same API?

The HR sensor and a few others are controlled by setEnabledSensors(). The accellerometer is controlled by registerSensorDataListener, unregisterSensorDataListener(). Both seem to have no intersection. While there is an option :enableAccelerometer, there is none for the other sensors, e.g. :enableHeartRate, :enablePressure, :enableTemperature. Even worst, how would one go about if multiple sensors shall be captured, if there is only one registerSensorDataListener() allowed at a time?

This is a totally arbitrary hack and an unbearable situation that probably discourages serious developers from embracing this platform (I'm close to that point). Please consider a complete rewrite of this API for 2.5 that will treat all sensors equal!
  • Replacing this would impact many existing apps done by serious developers. :)
    There's quite a few folks doing CIQ apps that have been coding for a number of years (decades in my case), but also have been doing CIQ for up to 3 years (it's only about 3 years old)

    Understand that there's really not much app memory on watches. So for example, if you consider GPS a sensor, why pull in the positioning bit if I just want to get the Temperature from a Tempe? Same with listening for Accel data? (and raw Accel data is available in Sensors, along with raw mag compass data, on watches with a mag compass BTW). No need to use even a small amount of memory for things apps may not need. And not all sensors are equal. And in the case of Sensors, that can be used in a background process, while Position can't)

    Consider a typical recording app. When it starts, it enables GPS, and enables the sensors it can use (typically ANT/BT sensors, but also includes the oHRM on devices with that). This causes the FW to start searching for those and connecting, and if a HRM belt is available, it will use that and override the oHRM. (The "best source" thing I'll mention later)

    in onPosition, what I do there is look for a "GPS fix" (accuracy ok to start). At that point, recording the session can start (well, that's how I do it in my apps). Then, Activity.Info gets valid data, and much of the sensor data is there, like hr, location, speed, distance, cadence, etc. The one exception (and this has been requested many times in the past) is the temperature, and that you need to pull from Sensor.Info. And then, on devices with the exception of the Edge family, is only available with a Tempe, so you can't see the value from the internal temperature sensor that way (on devices that have one).

    But consider a similar indoor app that doesn't use GPS - no sense using Position at all in that app.

    There's also a "best source" thing that comes into play. Consider a footpod. If you have one paired and it connects, you'll see cadence data from it, but if it can't connect, it falls back to the cadence data from the watch itself. Heading is also a bit interesting, in that if you are standing still, on a watch with a compass, you'll see it change based on where you have the watch pointed, but once you start moving at a certain speed, GPS is used to detect your heading, as the watch might be in a position where it's not really pointing in the direction you're going.

    As I said in another thread, there is a learning curve with CIQ, but there's also a bunch of people that have been doing it for a long time and are here to help.
  • Former Member
    Former Member
    sorry...off-topic
    that "best source" is interesting in regard to loosing Running Dynamics data stream from a HRM belt
    ">running-dynamics-dropout">running-dynamics-dropout
  • When it comes to "common access for all sensor types", you can always do a class to make things common for you. And with Barrels, you can offer it to other devs who may be interested.
  • oneTwo. I've not been following that (I don't have an RD Pod, etc), but that could be a ANT+ dropout. And there, there seems to only be one source, so it's not like a footpod, where the watch can fall back to it's own cadence data.
  • Former Member
    Former Member
    It's probably for historical reasons, but why is it that not all sensors are accessed by the same API?The HR sensor and a few others are controlled by setEnabledSensors(). The accellerometer is controlled by registerSensorDataListener, unregisterSensorDataListener().

    The sensor events as requested through enableSensorEvents are specifically for "slow" sensors, those that have update rates of 1 Hz, where update rates beyond that are not super useful. This includes things such as, you guessed it, heart rate, cadence, temperature, etc. As mentioned by Jim, you have limited memory and power.
    The data listener is specifically for, as listed in the API, "high-frequency data". This is for sensors where a sample rate greater than 1 Hz is useful, such as the accelerometer. Of course, you can always set up your own events and call Sensor.getInfo(), if you want to grab something like the accelerometer or magnetometer at a different rate from the 1 Hz provided by enableSensorEvents.

    This is a totally arbitrary hack and an unbearable situation that probably discourages serious developers from embracing this platform (I'm close to that point).

    Hardly. Do you normally demand breaking rewrites for slightly unintuitive interfaces in your 3000+ class projects?
  • Former Member
    Former Member
    Yes, there isn't a lot of memory in a watch. Even more so, this calls for a concise and slim API.

    While sensors are certainly very different, a unified API to access and control them would be very helpful. Some are event based, others require polling. That doesn't hinder them from being managed in a unified way (like, for example, almost everything in Unix is found on the file system tree).

    In fact, each of the sensor-specific API fragments in CIQ look already like they were designed to support multiple types of sensors. It's only that ther are way too many unfinished approaches that seem to lead nowhere.

    Do you normally demand breaking rewrites for slightly unintuitive interfaces in your 3000+ class projects?

    Not unusual with xtreme/agile programming. Some languages support global refactoring almost at the speed of thought (Smalltalk). I remember restructuring deep class trees in only a few hours. But of course, if you have an API out there that many developers rely on, it is more difficult. Then again, Apple breaks things almost on a yearly basis ...
  • Former Member
    Former Member
    I can agree with you that the original Sensor API could really use a re-write, but it isn't something that is currently an urgent priority. The Sensor module is one of the original modules we released with, and there are a lot of things I'd like to do differently with it today. It does not provide any reasonable structure to access streaming data directly from a sensor, which is why we had to create a different interface when adding accelerator access to the API. We hope this newer API stands up to future expansion better than Sensor did, but I'm sure there will be things we would have done differently if we take a close look at it again in 3 years.
  • Former Member
    Former Member
    Thanks, Brian. As long as things are still evolving, that's a very good sign.