How to Record Application Metrics with Garmin Connect IQ


This is the third part of a three-part post about creating an app for the active lifestyle using the Garmin Connect IQ app system; part one focused on page layout, while part two focused on page flow and metrics, and part three focuses on recording metrics.


The Flexible and Interoperable Data Transfer (FIT) standard is designed to give a standard format for exchange of fitness and workout data. The goal of the FIT format is to have an agreed upon standard for recording and parsing fitness metrics that is space efficient and widely flexible. Additions to this standard are completed via a standardization process with the FIT. When trying to define a standard for a new metric, the process for FIT standardization should always be followed. There are times, such as in the case of “Quantitative Enlightenment,” when we want to capture a metric but we don’t want to standardize a metric.

FIT 2.0 adds a new concept known as developer fields. These fields allow a developer to flexibly create new FIT field definitions that are local to the recording. Put simply: They offer a standard way to break the standard. Connect IQ allows developers to record information to the FIT file and then allows the user to visualize the data on the Garmin Connect™ platform.

Defining New FIT Fields

In our app FIT, recording is controlled by the NamasteModel:

// Create a new FIT recording session
mSession = ActivityRecording.createSession({:sport=>ActivityRecording.SPORT_GENERIC, :name=>"Yoga"});
// Create the new FIT fields to record to.
mCurrentNamasteField = mSession.createField("Current", 1, FitContributor.DATA_TYPE_UINT8, {:mesgType => FitContributor.MESG_TYPE_RECORD});
mTotalNamasteField = mSession.createField("Total", 2, FitContributor.DATA_TYPE_UINT32, {:mesgType => FitContributor.MESG_TYPE_SESSION});

As mentioned in part two, much of the challenge of yoga comes from holding a position. Our metric will measure the period of time the user is in this state.

   Quantitative Enlightenment (Namastes) = Minutes heart rate is in zone one or above and the body is not moving.

We want to capture quantitative enlightenment in two ways: instantaneous enlightenment and total enlightenment. The instantaneous enlightenment is captured every second, and records if we are currently being enlightened at that moment. Total enlightenment is the sum of all the enlightenment for the entire workout.

The createField method of Session allows us to define a new custom field. In our case, we are defining two custom fields:

  1. The mCurrentNamasteField is where we will record instantaneous enlightenment. We want this associated with the record message so we can have a graph of it across the workout.
  2. The mTotalNamasteField is where we will record total enlightenment. We want this associated with the session message so it will display with the workout summary.

Note we supply a message id with each definition. This must be between 0 and 255. We also supply the type of encoding to use for each field.

 

The Namaste app records the metric in the accelerometer callback:

           // Update the current namaste field
           mCurrentNamasteField.setData( mNamaste );
           // Update the total namastes field
           mTotalNamasteField.setData( mTotalNamastes / 60 );

Setting the value updates the value to be recorded, but does not force a message to be recorded.

Defining Metric Display Information

With custom fields, Connect IQ defines a separation between the model and the view. The model (metric data) is recorded into the FIT recording, but the view (display definitions) are kept in the app store. This allows developers to update their view information with app updates.

We define the view components of our metric in the resource compiler. If you open resources/fitcontributions/fitcontributions.xml you can see the display definitions:

<fitContributions>
 <fitField id="1" displayInChart="true" sortOrder = "0" precision="1"
    chartTitle="@Strings.namaste_graph_label" dataLabel="@Strings.namaste_label"
    unitLabel="@Strings.namaste_units" fillColor="#FF0000" />

 <fitField id="2" displayInActivitySummary="true" sortOrder = "1" precision="-1"
    dataLabel="@Strings.namaste_label" unitLabel="@Strings.namaste_units"  />       
</fitContributions>

Each fitField needs to specify the message id it refers to, and this message id must match the one used when creating the field in the Monkey C code. The fitField block has a number of configurable options, including the following:

id A numeric value from 0 to 255 used to refer to your field No duplicates within an app are allowed
displayInChart Indicates whether or not record level Connect IQ data should be rendered in a chart true if you want this entry to be displayed as a chart, false otherwise; graph fields can only support numeric data.
displayInActivityLaps Indicates whether or not lap level Connect IQ data should be rendered in the Activity Laps section in the Garmin Connect Activity Details page true if you want this entry to be displayed in the activity laps, false otherwise
displayInActivitySummary Indicates whether or not activity (fit session) level Connect IQ data should be rendered in the Activity Summary section in the Garmin Connect Activity Details page true if you want this entry to be displayed in the activity summary data, false otherwise
sortOrder Determines the order in which the Connect IQ data will appear in the Summary or Lap Sections of the Activity Details page and what order charts will be displayed on the Activity Details page No duplicates are allowed
precision Decimal point precision for numeric data 0 for integer, 1 for 1 decimal point, 2 for 2 decimal points; without this attribute, the default is no rounding
chartTitle This is the resources string key to use to render the title of the chart Optional if displayInChart is false; must be a string resource
dataLabel This is the resources string key to use to render the label of the data field in the Activity Summary or Activity Laps section of the Activity Details page (e.g., Cadence or Heart Rate) Must be a string resource
unitLabel This is the key to use to render the unit of the data field in the Activity Summary or Activity Laps section of the Activity Details page (e.g., kph or miles) Must be a string resource
fillColor RRGGBB value of color to use for chart Optional if displayInChart is false

This will communicate the metadata to display our chart to Garmin Connect.

Visualizing Our Recording

Now your app can record information, and you can test the recording in the simulator or on your device. After setting this up, you will want to preview how this will look on Garmin Connect, but Garmin Connect will only show Connect IQ information from apps that have been approved on the Connect IQ store. Thankfully, you can use the Monkeygraph tool to create a preview. In Connect IQ 2.2 you can start Monkeygraph from the Eclipse from Connect IQ | Start Monkeygraph, or you can start it with the following from the command line:

$ monkeygraph

This will bring up the Monkeygraph tool.

The Monkeygraph tool allows us to try out our visual settings against our FIT recording.

  1. Run your app in the simulator. Play back a FIT file using the Simulation | FIT Data | Playback File… while recording in your app. When you are done, use Simulation | FIT Data | Save FIT Session… to save the recording.
    or...
    Put the app onto a Garmin device, and run the app to record a FIT file. Copy the file from GARMIN\ACTIVITIES to your local file system.
  2. In Eclipse, go to Connect IQ | App Export Wizard... and use the tool to create an IQ file.
  3. Open the Monkeygraph tool.
  4. Open both the FIT recording of your workout and your IQ file into the Monkeygraph tool.
  5. You should get a visualization of the graphs, the lap messages and the workout summary.

Adding a New Metric

Until now, we have been recording quantitative enlightenment. This metric is based on quantifying the energetic stillness. However, there is a lot of motion in yoga as well. Sun salutations, Chaturanga Dandasana and other sequences have a lot of motion. We should display a metric of motion to complement our metric of stillness. What we need is a measurement of vigor.

Until now, we have been capturing the magnitude of the accelerometer vector, but we have only used it for purposes of getting the angle from the dot product. We are going to capture the average magnitude of the accelerometer across 1 second, and log that to the FIT file.

Adding the Field

First, we should add the vigor field member variable to the NamasteModel object:

// User's "vigor";
hidden var mVigorField;

Now we need to add the field definition to the constructor alongside the other definitions:

mVigorField = mSession.createField("Vigor", 3, FitContributor.DATA_TYPE_FLOAT, {:mesgType=>FitContributor.MESG_TYPE_RECORD });

Computing Vigor

Vigor is simply the average of the magnitude of the vectors. Let’s add that computation to our accelerometer callback. We can do this by adding a new variable to the enlightenment processing that adds the magnitudes of the vectors together and divides by four.

Once we’ve computed the vigor metric, we need to write it to the field:

// Update the vigor field
mVigorField.setData( averageVigor / 4 );

Adding the Display Definitions

We need to add strings to the strings.xml file.

<string id="vigor_label">Vigor</string>
<string id="vigor_units">V(s)</string>

Connect IQ allows for string translations to be embedded in the app. By using the resource system, we can embed string translations for our labels and units.

Now we need to add an entry into the fitcontributions.xml file. This time, let’s make the graph green:

<fitField id="3" displayInChart="true" sortOrder = "2" precision="1"
 chartTitle="@Strings.vigor_label" dataLabel="@Strings.vigor_label"
 unitLabel="@Strings.vigor_units" fillColor="#00FF00" />

We have to adjust the id to use the same message id we used in our code. We also adjust the sort order to have it display below our enlightenment graph.

Testing

The accelerometer currently doesn’t have a simulation, so we need to test this on the device. Once we have a recording, we can view it in Monkeygraph:

Displaying on Garmin Connect

Your app has to have been uploaded to the Connect IQ store before recording information will appear on Garmin Connect. Once the app is on the store, Garmin Connect will be able to reference the graph definitions.

To get started with Connect IQ and see where your innovation takes you, go to the developer site and download the free SDK.

About Connect IQ:
Connect IQ launched in early 2015 with the goal of making Garmin devices open to the developer ecosystem and subsequently to consumers for personalizing their devices. Since the launch of Connect IQ last year, Garmin has launched many more Connect IQ-enabled wearables in addition to the first compatible bike computer and handheld GPS unit. The new SDK just launched last month as well. Check it out here! For more information on Connect IQ, please see this overview page.

About Garmin:
For decades, Garmin has pioneered new GPS navigation and wireless devices and applications that are designed for people who live an active lifestyle.  Garmin serves 5 primary business units, including automotive, aviation, fitness, marine and outdoor recreation. For more information about Garmin, visit our virtual pressroom at garmin.com/newsroom, contact the Media Relations department at 913-397-8200, or follow us at facebook.com/garmin, twitter.com/garmin, or youtube.com/garmin.

 

Nicolas Kral

Comments