Using the simulator to test Edge 1030 internal barometer readings?

I am attempting to use the Edge 1030 internal barometer pressure information within my Connect IQ app.

Connect IQ Device Simulator 7.3.0

I set up the test using:

---------------

import Toybox.Sensor;

private var _info = null;

private var _barometer = Lang.Float;

_info = Sensor.Info;

_barometer = _info.pressure;

System.println(_barometer) // this prints 'null'

------------

My problem starts when I want to test the _barometer object with an actual simulated value.  I don't know how to do this.

Running:  Simulation -> Activity Data

doesn't seem to supply the _barometer with an actual value.

If I change the above code to:

System.println(_barometer.toString()) // throws errors

Any direction on this would be appreciated.  Relatively new to Monkey C and Connect IQ

  • Maybe Activity.Info.ambientPressure does the trick:

    var ambientPressure as Lang.Float or Null

    The ambient pressure in Pascals (Pa).

    This returns ambient (local) barometric pressure as measured by the pressure sensor. The data is smoothed by a two-stage filter to reduce noise and instantaneous variation.

  • Hadn't looked at this API yet.  Produces the same results in the simulator though:

    _info = Activity.Info;;

    _barometer = _info.ambientPressure;

    System.println(_barometer); // null value output to debug console

    System.println(_barometer.toString()); // 'Encountered app crash' 

    Other readings have suggested that the internal barometer is unavailable in the simulator (which makes ensuring the object works as expected difficult while testing) and to just assign a dummy float as the barometric value in simulation.  Really hoping this isn't the case and I can get some pressure values within the simulator.

  • If you have a real device, you could try recording an activity and using that as the data source during simulation.

    But for what it's worth, I tried simulating activity data with both fr955 and edge1050, and I was able to get a value from Activity.Info.ambientPressure.

    1) I create a simple data field project

    2) My view's compute() function looks like this:

    function compute(info as Activity.Info) as Numeric or Duration or String or Null {
       return info.ambientPressure;
    }

    3) I run the app in the simulator and press the play button ( ) in Simulator > Activity Data. (Yes, the UI here can be confusing - this has been a problem since the beginning, even though the UI has changed quite a bit.)

    3a) Before pressing play:

    3b) Press play:

    3c) After pressing play:

    _barometer = _info.pressure;
    System.println(_barometer) // this prints 'null'
    System.println(_barometer.toString()) // throws errors
    _barometer = _info.ambientPressure;

    System.println(_barometer); // null value output to debug console

    System.println(_barometer.toString()); // 'Encountered app crash' 

    It's expected that if you call toString() (or any other method) on a null value, your app will crash, since methods can only be called on a valid object.

    Since it's valid for either Sensor.Info.pressure or Activity.Info.ambientPressure to be null (according to the API docs / type info), this is a possibility you have to account for in your code, even when it runs on a real device.

  • The above procedure was successful on both SDK 7.4.3 (the latest) and 7.3.0.

    Since it's valid for either Sensor.Info.pressure or Activity.Info.ambientPressure to be null (according to the API docs / type info), this is a possibility you have to account for in your code, even when it runs on a real device.

    For example, native Garmin data fields will often display "--" when a value is null / unavailable / not applicable.

  • I'll try this a bit more.  I knew how to turn on the 'Activity Data' within the simulator but not about the creation of the compute() function.

    Just need to figure out how to show the return within my existing app.   Using the return from the compute() function still throws errors when I attempt either System.println() or dc.drawText() when passing either _barometer.format("%.2f") or _barometer.toString() as paramters.

  • It's expected that if you call toString() (or any other method) on a null value, your app will crash, since methods can only be called on a valid object.

    As  has mentioned: you have to check for null before using the value in any method:

    if ( _barometer != null ) {
        dc.drawText(x, y, font, _barometer.format(“%.2f“), center);
    } else {
        dc.drawText(x, y, font, “ - - “ , center);
    }

    BTW: „return value“ in function compute() works only in simple datafields, whereas dc.drawText() works in onUpdate() only in complex datafields.

    ps. This is an answer to 

  • The reminder to check for the null value first is appreciated, made testing easier.

    Ran tests on the object using both compute() and dc.drawText() within onLayout().  So far my _barometer object remains null.

    This has been tested using both Activity.Info and Sensor.Info objects.  Activity Data in the simulator UI is running.

    Everyone's tips are appreciated.

    Not sure why simulated pressure data works for the fr955 and Edge1050, and not the Edge1030 I am running.

  • > Not sure why simulated pressure data works for the fr955 and Edge1050, and not the Edge1030 I am running.

    I just tried edge1030 and it works fine.

    > I knew how to turn on the 'Activity Data' within the simulator but not about the creation of the compute() function.

    The compute[] function is only relevant for a simple datafield, as in my example. If you create a simple data field project, the compute[] function will automatically be added for you [with a default return value such as 0.0]. Since your project did not have a compute[] function, I assume it is not a simple datafield.

    It's only a proof of concept but I was able to display barometric pressure in an app as follows:

    1] Create a simple data field project:

    - Open command palette [CTRL-SHIFT-P / CMD-SHIFT-P]

    - Select "Monkey C: New Project"

    - Enter project name

    - Select Data Field

    - Select Simple

    - Select API level [this shouldn't matter, just pick the lowest one]

    - Select the products to support

  • 2] Modify the compute[] function [which should be generated as part of the new project] as follows:

     // The given info object contains all the current workout
    // information. Calculate a value and return it in this method.
    // Note that compute() and onUpdate() are asynchronous, and there is no
    // guarantee that compute() will be called before onUpdate().
    function compute(info as Activity.Info) as Numeric or Duration or String or Null {
       // See Activity.Info in the documentation for available information.
       return info.ambientPressure; // <==== add this line [and remove the existing line starting with "return..."]
    }

    Note that you don't need any special logic to handle null here because a simple data field is allowed to return null [in which case it will display nothing for the value], and because a Numeric value [such as a Float pressure value] will automatically be formatted as shown above.

    Ofc in your real app, you will probably want special null-handling logic as in mcinner1's example, and you will probably want precise control over the formatting.

    But this is just a test, so returning the value itself [Float or null] without any special formatting should be fine.

    3] Run the data field in the simulator

    You should see the same results as I described above [except that the data field label won't be "pressure" unless you also change the part of the code that sets the label, which isn't really necessary for the test]

    Once you have satisfied yourself that pressure data is indeed being simulated and displayed by your app, you can move on to trying to figure out why it isn't being displayed in your real app.

  •  the above mock project works and displays the pressure data.  This worked using the above assumption of 'Data Field' rather than an 'App' for the project.  The above template works for both Activity.Info and Sensor.Info objects.

    Going to figure out why it isn't working in my app.