O'Reilly logo

Enabling Programmable Self with HealthVault by Vaibhav Bhandari

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 4. Using the HealthVault Data Ecosystem for Self-Tracking

“Data is a precious thing and will last longer than the systems themselves.”

Tim Bernes-Lee

The Quantified Self (http://quantifiedself.com/about/) community enables self-knowledge through self-tracking. Self-tracking, when powered by appropriate data analysis, has been proven to trigger behavioral change. The act of self-tracking creates awareness and feedback. The hunger for, and success of, self-knowledge is evident from the growing number of self-quantifiers (currently 6,000+ in 41 cities and 14 countries).

Self-knowledge is possible only with a substantial collection of data about oneself. HealthVault provides more than 80 granular data types that enable tracking data regarding everything from daily exercise to genome sequences. In this chapter, we will build upon the understanding of the HealthVault API covered in Chapter 3 and extend it to develop a data-intensive self-quantifying application. Through the Quantified Self application, we will gain an understanding of HealthVault data types and application development.

A Self-Experimentation Application

In Chapter 1 we analyzed weight data, and in Chapter 2 we worked with sleep information and correlated it with exercise. HealthVault offers a data type for tracking emotional state and daily dietary intake as well. Let’s consider building a simple Quantified Self utility that helps a user keep track of his emotional state, daily dietary intake, weight, sleep, and exercise. Tracking these types of data and their relation to each other would allow our user to form and prove interesting hypotheses such as: “I’m happier if I sleep well, and I sleep well if I drink less alcohol and exercise sufficiently.”

Self-tracking fosters awareness and a feedback loop; numerous participants in the Quantified Self movement have attributed improvement to insights generated by the data and the act of data collection. Our Quantified Self application will aim to emulate this pattern. Figure 4-1 summarizes the data pattern we wish to capture.

Data dashboard for Quantified Self application

Figure 4-1. Data dashboard for Quantified Self application

Setting Up a New HealthVault Application

Let’s start by making a Quantified Self application with a unique application identifier. In this chapter we will use the HealthVault .NET SDK in order to focus on understanding the HealthVault data types. However, as HealthVault SDK and Open Source Libraries outlines, you can use other languages and HealthVault libraries as well.

The first step in creating the application is to download and install the HealthVault SDK from MSDN (http://msdn.microsoft.com/en-us/healthvault). After installing the SDK, you will notice a utility called Application Manager. From the Windows Start button, this utility can be accessed through All ProgramsMicrosoft HealthVaultSDKHealthVault Application Manager.

Using Application Manager to create a new HealthVault application

Figure 4-2. Using Application Manager to create a new HealthVault application

Once you open the Application Manager, you will notice the Create New Application button, which you should use now to create a new application. As Figure 4-2 shows, the new application creation process asks you for an application name and other details, and creates a Visual Studio solution with the application starting point.

The second step in the process is to register your application. Application Manager automatically opens a new browser window that signs you into the HealthVault Application Configuration utility (https://config.healthvault.com) and creates the appropriate application in the HealthVault Development environment. The development environment is frequently referred to as PPE, which stands for preproduction environment. In the next chapter we will learn how the Application Configuration Center can be used to create a development application without using the Application Manager.

On the dashboard of the HealthVault Application Configuration Center, you will see the application you just created, as depicted in Figure 4-3.

HealthVault Application Configuration Center showing the application that was created

Figure 4-3. HealthVault Application Configuration Center showing the application that was created

Adding Data Types

HealthVault offers more than 80 granular items to which a user can authorize access. They fall into categories such as fitness, condition, medications, health history, measurements, personal profile, files, and custom data. A developer can obtain access for particular health data items by configuring an application’s authorization rule set. For our application, we need access to weight, sleep, and exercise data, which come directly from various devices. We also want the user to be able to track emotional state and daily dietary intake, which is information that she will enter manually.

To start the necessary configuration, click on the application ID in the HealthVault Application Configuration Center. Figure 4-4 illustrates the view of our Quantified Self application after clicking on the “Online rules” tab. In this menu, select the appropriate data types for the application (weight measurement, sleep, exercise, etc.), select all permissions (read, write, update, delete), provide a reason why the application needs access to these types, and name the rule. A rule can also be configured as optional and can have display settings. Why String, Is Optional, and Display Flags items are currently not active for most HealthVault applications.

Configuring online rules for an application

Figure 4-4. Configuring online rules for an application

We are using HealthVault as the user authentication provider for our application, so we choose to operate in the online mode and create an authorization rule for such access. If we wanted our application to work through a backend system provided by one of the other types of architecture discussed in Chapter 3, we would configure the offline rules for access to appropriate data types.

We are finished selecting the appropriate data types for our application, and can now try accessing them through the application.

Accessing the Data Types

The application manager utility creates a template application. Figure 4-5 shows the initial solution created by this utility.

Solution created by the application manager

Figure 4-5. Solution created by the application manager

The solution makes sure that your application is configured properly with an appropriate application ID, points it to the appropriate HealthVault platform and shell development environments, and configures the application’s redirect URL; all of these configurations live in the Web.Config file. The Default.aspx page is derived from the HealthServicePage and handles authorization with the HealthVault Platform, whereas the Redirect.aspx page is derived from the HealthServiceActionPage and handles authentication and interaction with HealthVault Shell. The bin folder contains HealthVault SDK libraries: Microsoft.Health.dll, which encapsulates the core HealthVault functionality; Microsoft.Health.Web.dll, which broadly encapsulates browser interaction; and Microsoft.Health.Itemtypes, which encapsulates an object model for all HealthVault data types.

The main solution doesn’t add a master page. In order to make it easy to extend functionality, we create a MasterPage named QuantifiedSelf.master, create a fresh Default.aspx page after deleting the old one, and ensure this page is derived from HealthServicePage.

As discussed in Chapter 3, we can use the HealthVault GetThings API to access health items in a user’s health record. The code shown in Example 4-1 accesses Emotion, DietaryDailyIntake, Weight, Sleep, and Exercise from HealthVault. As shown in the two lines at 1, we make sure to fetch these elements for the last seven days only.

Example 4-1. GetThings call to access multiple things

    protected void Page_Load(object sender, EventArgs e)
    {
        Lbl_UserName.Text = this.PersonInfo.SelectedRecord.DisplayName;

        HealthRecordSearcher searcher = PersonInfo.SelectedRecord.CreateSearcher();
        HealthRecordFilter filter = new HealthRecordFilter(
            ApplicationSpecific.TypeId,
            Emotion.TypeId,
            DietaryDailyIntake.TypeId,           
            Weight.TypeId,
            SleepJournalAM.TypeId,
            Exercise.TypeId);

        filter.EffectiveDateMin = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)); 1
        searcher.Filters.Add(filter);
        
        HealthRecordItemCollection items = searcher.GetMatchingItems()[0];

Before we display these types, let’s dig deeper to understand a HealthVault data type.

Understanding HealthVault Data Types

A comprehensive list of all HealthVault data types is available from the HealthVault developer center at http://developer.healthvault.com/types/types.aspx. Each type has properties that determine to a great extent how items are created and used. To understand a type better, let’s take a deeper look at the example of the Weight Measurement type.

Type Properties

Figure 4-6 shows the properties of the Weight Measurement data type that are common to every data type from the HealthVault developer center (http://developer.healthvault.com/types/type.aspx?id=3d34d87e-7fc1-4153-800f-f56592cb0d17). Each HealthVault type has a unique identifier; this id is used by the HealthVault APIs to identify the type. In the case of Weight, it is 3d34d87e-7fc1-4153-800f-f56592cb0d17. A type sets the uncreateable property to true if no application can create such a type in a user’s HealthVault record; a good example of this is the Basic type. The immutable property is true if no application can modify or update an instance of that type in the user’s HealthVault record; a good example of this is the CCR type. The property singleton is true if only one instance of that type can exist in a user’s HealthVault record; a good example of this is the Basic Demographic type.

Properties of the Weight Measurement type

Figure 4-6. Properties of the Weight Measurement type

Type transforms

Additionally, the list of transforms is a property associated with the type. Transforms are built-in XSLT transformations available for a particular thing type. These transforms let you convert the XML associated with a particular type to various formats, such as HTML, to a representation compatible with various popular health care standards, or to an older or newer version of the same type.

Form, STT, and MTT transforms

Common among all the types are the form, stt, and mtt transforms. form provides an HTML table representation of an instance of the entire thing. stt, which stands for “single type transform,” provides a row- based representation of the type so that it can be viewed as a list of instances of the same type. mtt, or “multiple type transform,” provides a row-based representation of the type so that it can be combined and viewed with multiple HealthVault types. Each row in mtt has a summary attribute representing the details of the type. The main difference between stt and mtt is that stt has an XML attribute for each meaningful data element of the type, whereas mtt summarizes all the meaningful data elements in one string in the summary attribute.

One can use the HealthVault PowerShell plug-in to view each source of the transforms. Example 4-2 shows how to save the form transform for the Weight thing type.

Example 4-2. Saving the form XSLT transformation for Weight thing types to a file

PS \> (Get-ThingType 3d34d87e-7fc1-4153-800f-f56592cb0d17).TransformSource["form"] |
out-file Weight.xsl

The columns on the type definition page in the HealthVault Type Explorer define the column header, .NET data type, and width for each column. It’s handy to view this information about the type in a data grid.

Example 4-3 shows the multitype table transformation XML returned by the HealthVault platform for the Weight type. We can see the columns ranging from wc-id (type identification) to summary (summary information of the type).

Example 4-3. Weight mtt XML for the Weight type

<data-xml transform="mtt">
  <row wc-id="34655fb4-a6c8-4d47-85f1-dbc6e09b952a" 
   wc-version="0f57073a-0795-4867-9c9f-bcb99d2fa681" wc-note="" wc-tags="" 
   wc-date="2011-12-23 11:17:47" wc-type="Weight Measurement" 
   wc-typeid="3d34d87e-7fc1-4153-800f-f56592cb0d17" wc-source="" wc-brands=""
   wc-issigned="false" wc-flags="" wc-ispersonal="false" wc-isdownversioned="false" 
   wc-isupversioned="false" wc-relatedthings="" wc-state="Active" summary="173 lbs" />
</data-xml>

In our Quantified Self application, we can use the mtt transform to easily display multiple types in the same table for self-analysis. In Example 4-4, Lines 13 construct and fetch our query from HealthVault; note that in Line 2 we ask the HealthVault platform to apply the mtt transform on the returned items. In Line 4, we select the row for each data-xml mtt transform. We then display the wc-date, wc-type, and summary columns (Lines 56). Different applications can choose to show different columns. Individual type columns, such as weight for Weight, are available in single type transform (stt), whereas a summary column summarizes this information in mtt. The HealthDataItemGrid control is also available from the HealthVault .NET SDK to show this information automatically.

Example 4-4. Viewing multiple HealthVault types in a data grid

    protected void Btn_ShowWeeklyReadingsTextSummary_Click
        (object sender, System.EventArgs e)
    {
        HealthRecordSearcher searcher = PersonInfo.SelectedRecord.CreateSearcher(); 1
        HealthRecordFilter filter = new HealthRecordFilter(
            Emotion.TypeId,
            DietaryDailyIntake.TypeId,
            Weight.TypeId,
            SleepJournalAM.TypeId,
            Exercise.TypeId);

        filter.EffectiveDateMin = DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0));
        searcher.Filters.Add(filter);
        filter.View.TransformsToApply.Add("mtt"); 2

        HealthRecordItemCollection items = searcher.GetMatchingItems()[0]; 3

        DataTable dataTable = new DataTable();
        dataTable.Columns.Add(new DataColumn("Date", typeof(string)));
        dataTable.Columns.Add(new DataColumn("Type", typeof(string)));
        dataTable.Columns.Add(new DataColumn("Summary", typeof(string)));
        foreach (HealthRecordItem item in items)
        {
            XmlNode mttDocument = item.TransformedXmlData["mtt"] 4
                .SelectSingleNode("data-xml/row");
            DataRow row = dataTable.NewRow();
            row["Date"] = mttDocument.Attributes["wc-date"].Value; 5
            row["Type"] = mttDocument.Attributes["wc-type"].Value;
            row["Summary"] = mttDocument.Attributes["summary"].Value;
            dataTable.Rows.Add(row); 6
        }

        Grid_ReadingsTextSummary.DataSource = dataTable;
        Grid_ReadingsTextSummary.DataBind();
        Grid_ReadingsTextSummary.Visible = true;
    }

Once we have the data grid configured, we can view the summary of all types in the same column structure. Figure 4-7 shows how this information is displayed in our Quantified Self application.

Quantified Self application showing multiple types in a data grid

Figure 4-7. Quantified Self application showing multiple types in a data grid

Note

The CCR HealthVault type (1e1ccbfc-a55d-4d91-8940-fa2fbf73c195) has a tohv transform that converts the data in that type to individual HealthVault elements.

In addition to the use of transforms to convert types to different representations, the HealthVault method schema provides a <final-xsl> element in each method header. final-xsl converts the data returned by the method call to built-in transforms, such as converting to CCR (toccr), CCD (toccd), CSV (tocsv), or RSS (torss). final-xsl also allows the caller to specify a custom-built XSLT transform that the HealthVault platform runs on the output before sending it to the requester.

The final-xsl element is specified between the <country> and <msg-time> elements in the header of a method. In the HealthVault .NET SDK, one can call this functionality by using the GetTransformedItems method. In the Java .NET Open Source library, this functionality can be used through a call to request.setFinalXsl("transform name or transform source").

Versioning transforms

HealthVault data types can have multiple versions. As the HealthVault ecosystem matures, existing types need to be updated or modified to match new use cases. Medications, Basic Demographic Information, and Family History are good examples of types that have multiple versions. You will notice that the older Medication datatype (which is available at http://developer.healthvault.com/pages/types/type.aspx?id=5c5f1223-f63c-4464-870c-3e36ba471def) has an up-version transform, and the newer Medication datatype (http://developer.healthvault.com/pages/types/type.aspx?id=30cafccc-047d-4288-94ef-643571f7919d) has a down-version transform. Through these transforms, HealthVault provides an easy way to move data between an older and newer version of a data type.

Note

Versioning of data types is unique to HealthVault among personal health data platforms. Personal health records are meant to exist over a lifetime, and this feature makes moves seamless from older health items to newer health items.

Other transforms

Transform names containing wpd and hvcc enable the HealthVault Connection Center to convert Windows Portable Device Data to and from HealthVault XML.

Type Schemas

Now that we understand the high-level properties associated with a type and have used the MTT display transform to show the summary of all data types in our application, let’s take a closer look at what is entailed in a type’s schema, with the specific goal of displaying appropriate values for the Weight type.

Weight is a simple type that scales, and applications can write to or read from it. The XML schema and associated sample representation for this type are shown in Example 4-5.

Example 4-5. XML and schema representation of the HealthVault Weight type

Column1:
<schema xmlns:weight="urn:com.microsoft.wc.thing.weight" 
    xmlns:t="urn:com.microsoft.wc.thing.types" xmlns:d="urn:com.microsoft.wc.dates"
    xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="urn:com.microsoft.wc.thing.weight">
  <import namespace="urn:com.microsoft.wc.thing.types" schemaLocation="base.xsd" />
  <import namespace="urn:com.microsoft.wc.dates" schemaLocation="dates.xsd" />
  <element name="weight">
    <complexType>
      <sequence>
        <element name="when" minOccurs="1" maxOccurs="1" type="d:date-time">
        </element>
        <element name="value" minOccurs="1" maxOccurs="1" type="t:weight-value">
        </element>
      </sequence>
    </complexType>
  </element>
</schema>

Column2:
<data-xml>
  <weight>
    <when>
      <date>
        <y>1990</y>
        <m>1</m>
        <d>1</d>
      </date>      <time>
        <h>1</h>
        <m>0</m>
        <s>0</s>
        <f>0</f>
      </time>
    </when>
    <value>
      <kg>60</kg>
      <display units="lb">132</display>
    </value>
  </weight>
  <common/>
</data-xml>

The Weight type consists of a sequence of date/time and weight values. The use of date/time in HealthVault is defined in the dates.xsd schema file (https://platform.healthvault-ppe.com/platform/XSD/dates.xsd), and the weight values are defined in the types.xsd schema file (https://platform.healthvault-ppe.com/platform/XSD/types.xsd).

The HealthVault .NET Web SDK encapsulates a nice object model on top of this XML and gives a user access to Value and When fields, as shown in Figure 4-8.

Properties in the HealthVault .NET SDK for the Weight class

Figure 4-8. Properties in the HealthVault .NET SDK for the Weight class

Units and measurements

Note that the Value field of this type contains display and units data. HealthVault stores the underlying measurement in kilograms, but the application can show it to the user in the same form in which it was entered. In our example Quantified Self application, we ask the user to input values in pounds. Example 4-6 shows how we convert this value to kilograms for storage while displaying it to the user as pounds (lbs).

Example 4-6. Creating a new Weight value

    protected void Btn_SubmitWeight_Click(object sender, EventArgs e)
    {
        double weight = double.Parse(Txt_Weight.Text);
        Weight w = new Weight(
                new HealthServiceDateTime(DateTime.Now), 1
                new WeightValue(
                    weight * 1.6, new DisplayValue(weight, "lbs", "lbs")));
        w.CommonData.Source = _appName; 2
        PersonInfo.SelectedRecord.NewItem(w);
    }

Dates

The When field or date is a special type called HealthServiceDateTime. As Line 1 in Example 4-6 shows, an instance of this date can be created by using the System DateTime. HealthVault enables a user to enter varying degrees of date precisions, hence it has a custom date/time.

In fact, the HealthVault approximate datetime construct allows you to create a date as flexible as “when I was a kid” or “Jan 2011” or “Dec”. All the different kinds of HealthVault dates are defined in dates.xsd, available at https://platform.healthvault-ppe.com/platform/XSD/dates.xsd.

Note

One of the core HealthVault design tenets is to ingest all kinds of data. Flexible dates enable a user to enter unstructured data. Furthermore, constructs such as approx-date-time allow HealthVault to receive data from standards such as CCR or CCD.

Common data

All types share some common data elements. In Line 2 of Example 4-6, we are writing to the common data element that shows the source of the application.

Other commonly used data elements are notes, tags, and related items.

Terminologies

HealthVault provides an extensible mechanism to specify strings coded for use across various systems through codable-value. The codable-value consists of text associated with the code, which is represented in a structured format called coded-value.

Terminologies are used in a HealthVault data element called codable. This element provides a structured way to represent semantically meaningful text.

Example 4-7 shows a codable-value schema. The family data field of coded-value specifies whether the code belongs to particular code system; for example, wc refers to the HealthVault code system, and HL7 refers to a system adopted by Health Language 7.

Example 4-7. codable-value schema

<complexType name="codable-value">
  <sequence>
    <element name="text" type="string">
    </element>
    <element name="code" type="this:coded-value" minOccurs="0" maxOccurs="unbounded">
    </element>
  </sequence>
</complexType><complexType name="coded-value">
  <sequence>
    <element name="value" type="string">
    </element>
    <element name="family" type="string" minOccurs="0">
    </element>
    <element name="type" type="string">
    </element>
    <element name="version" type="string" minOccurs="0">
    </element>
  </sequence>
</complexType>

HealthVault has more than 150 terminologies. The wiki http://partners.mshealthcommunity.com/hv_eco/w/wiki/preferred-vocabularies.aspx describes how these terminologies are used by the HealthVault user interface, and the book Meaningful Use and Beyond (Fred Trotter and David Uhlman, O’Reilly) describes how meaningful use, as proposed by federal regulations, dictates the use of these terminologies.

Example 4-8 shows how one can read the Exercise data type for showing calories burned. The Exercise data type stores various kinds of attributes in key value pairs. These attributes are listed in the ExerciseDetail terminology. As Example 4-8 shows, one can use the code value of CaloriesBurned from the ExerciseDetail terminology to look up the appropriate value and display it in the user interface.

Example 4-8. Listing calories burned in the DisplayExercise function

    private void DisplayExercise(List<Exercise> exercises)
    {
        DataTable exercise = new DataTable("exercise");
        exercise.Columns.Add(new DataColumn("Date"));
        exercise.Columns.Add(new DataColumn("ExerciseType"));
        exercise.Columns.Add(new DataColumn("CaloriesBurned"));
        foreach (Exercise e in exercises)
        {
            DataRow row = exercise.NewRow();
            row["Date"] = e.EffectiveDate.ToShortDateString().ToString();
            row["ExerciseType"] = e.Activity.Text;
            if (e.Details.ContainsKey(ExerciseDetail.CaloriesBurned_calories))
            {
                row["CaloriesBurned"] = e.Details[ExerciseDetail.CaloriesBurned_calories];
            }
            exercise.Rows.Add(row);
        }
        ExerciseView.DataSource = exercise;
        ExerciseView.DataBind();
    }

Extending HealthVault Data Types

Applications frequently have to represent something that is not encapsulated by the data structure of the HealthVault data types. Out of the box, HealthVault provides a mechanism by which a data type can be extended.

Every application can choose to write XML information in the extension tag within the common data section of a data type. It is recommended that applications distinguish their extension elements by using a unique source attribute on the extension element.

In our example, let’s assume we are extending the daily dietary intake type to add information on alcohol consumption.

Creating a Type Extension

We would like to track the amount of alcohol consumed in a simple element called “alcoholic-drinks”. To simplify things further, we assume this element represents the number of alcoholic drinks including wine, beer, cocktails etc., and is normalized to mean average alcohol per unit.

The first step is to write an alcoholic-drinks XML element within the extension tag using a unique source (_appDailyAlcoholExtensionName) in the extension element. Lines 12 in Example 4-9 show how one can do it in the .NET SDK.

Example 4-9. Creating a type extension

    protected void Submit_Daily_Diet_Click(object sender, System.EventArgs e)
    {
        //Post Diet
        DietaryDailyIntake diet = new DietaryDailyIntake();
        int totalCarbs;
        int.TryParse(Txt_DailyDietCarbs.Text, out totalCarbs);
        diet.TotalCarbohydrates.Kilograms = totalCarbs * 1000;
        diet.CommonData.Note = Txt_DailyDietNote.Text;

        //Adding extension data
        string drinks = Txt_DailyDietAlcohol.Text;
        HealthRecordItemExtension extension =
            new HealthRecordItemExtension(_appDailyAlcoholExtensionName);
        diet.CommonData.Extensions.Add(extension);
        XPathNavigator navigator = extension.ExtensionData.CreateNavigator(); 1
        navigator.InnerXml = @"<extension source=""" + _appDailyAlcoholExtensionName + @""">
                <alcoholic-drinks>" + drinks + "</alcoholic-drinks>"; 2

        PersonInfo.SelectedRecord.NewItem(diet);
    }

Consuming a Type Extension

The second step is to read information from the extension. In our application, the user enters alcoholic drink information through a text box associated with the Daily Dietary intake section, as shown in Figure 4-9.

Input section for Daily Dietary Intake

Figure 4-9. Input section for Daily Dietary Intake

Lines 13 in Example 4-10 show how one can read <alcoholic-drinks> XML. To parse this information we use XPath, and in the data type document, the element of interest resides at extension/alcoholic-drinks. Using the .NET XPathNavigator class, we select a single note signifying this value (Lines 12). Line 4 fetches the note associated with this instance of daily dietary intake. The user can potentially input clarifying information—for example, “drank 3 tequila shots”—in this element.

Example 4-10. Consuming a type extension

    private void DisplayDailyDiet(List<DietaryDailyIntake> dailydiets)
    {
        DataTable dailydiet = new DataTable("DailyDiets");
        dailydiet.Columns.Add(new DataColumn("Date"));
        dailydiet.Columns.Add(new DataColumn("Carbs (in gm)"));
        dailydiet.Columns.Add(new DataColumn("Alcohol (#drinks)"));
        dailydiet.Columns.Add(new DataColumn("Note"));
        foreach (DietaryDailyIntake e in dailydiets)
        {
            DataRow row = dailydiet.NewRow();
            row["Date"] = e.EffectiveDate.ToShortDateString().ToString();
            row["Carbs (in gm)"] = e.ToString();
            foreach(HealthRecordItemExtension extension in e.CommonData.Extensions)
            {
                if (extension.Source == _appDailyAlcoholExtensionName)
                {
                    XPathNavigator navigator = extension.ExtensionData.CreateNavigator();
                    XPathNavigator alcoholicDrinksNavigator = 1
                        navigator.SelectSingleNode("extension/alcoholic-drinks"); 2
                    if (alcoholicDrinksNavigator != null) 3
                    {
                        row["Alcohol (#drinks)"] = alcoholicDrinksNavigator.Value;
                    }
                }
            }
            row["Note"] = e.CommonData.Note; 4
            dailydiet.Rows.Add(row);
        }
        DailyDietView.DataSource = dailydiet;
        DailyDietView.DataBind();
    }

Applications may choose to combine and formalize the two steps just shown and create an extension class, which then could be registered with HealthVault SDK so that every time the extend type is accessed by the application, the appropriate extension properties are available.

Creating Custom Types

Extending a HealthVault data type might not always solve your data needs. Many times there are legitimate use cases for which the application needs a unique data repository. For example, in our Quantified Self application, we need a repository to store all of the user’s self-experiments.

HealthVault provides a mechanism called an application-specific type for this purpose. This type is not shareable with other applications. Once application developers find a broader use for their data, they can work with Microsoft to create a first-class data type for their needs.

Example 4-11 shows how one can use an application-specific type to store self-experiment hypotheses for the Quantified Self application. In our application we are asking a user to create a hypothesis using a simple text box. The value of this text box is read as the hypothesis string in Line 1. In Lines 34, we create an XML document with the data for this specific type and then add it to the document using ApplicationSpecificXml in Line 5. Each application-specific type requires a SubtypeTag and Description (Lines 67). We also specify the application creating this type in Line 2. Additionally, we use the common note element to capture the status of the type in Line 8, and the When element captures the date.

Example 4-11. Writing an application-specific custom type

    protected void Btn_Submit_Hypothesis_Click(object sender, System.EventArgs e)
    {
        ApplicationSpecific appSpecific = new ApplicationSpecific();
        string hypothesis = Txt_Hypothesis.Text; 1
        appSpecific.ApplicationId = this.ApplicationConnection.ApplicationId.ToString(); 2
        XmlDocument xml = new XmlDocument(); 3
        xml.LoadXml(
            string.Format("<self-experiment><hypothesis>{0}</hypothesis>
                </self-experiment>", 
            hypothesis)); 4
        appSpecific.ApplicationSpecificXml.Add(xml); 5
        appSpecific.SubtypeTag = "self-experiment"; 6
        appSpecific.Description = hypothesis; 7
        // Default the status note to active when the hypothesis is created
        appSpecific.CommonData.Note = "Active"; 8
        appSpecific.When = new HealthServiceDateTime(DateTime.Now);
        PersonInfo.SelectedRecord.NewItem(appSpecific); 
    }

On the other hand, we can show the list of self-experiments by reading the ApplicationSpecificXml using an XPath navigator. In Example 4-12, note that in Lines 12, we assume that the document for this type contains only one element and that the first node is the hypothesis.

Example 4-12. Reading an application-specific type

    private void DisplaySelfExperiments(List<ApplicationSpecific> selfExperiments)
    {
        DataTable selfExperiment = new DataTable("SelfExperiments");
        selfExperiment.Columns.Add(new DataColumn("Date"));
        selfExperiment.Columns.Add(new DataColumn("Hypothesis"));
        selfExperiment.Columns.Add(new DataColumn("Status"));
        foreach (ApplicationSpecific s in selfExperiments)
        {
            
            DataRow row = selfExperiment.NewRow();
            row["Date"] = s.EffectiveDate.ToShortDateString().ToString();
            row["Hypothesis"] = s.ApplicationSpecificXml[0].CreateNavigator(). 1
                                SelectSingleNode("hypothesis").Value; 2
            row["Status"] = s.CommonData.Note;
            selfExperiment.Rows.Add(row);
        }
        SelfExperimentsView.DataSource = selfExperiment;
        SelfExperimentsView.DataBind();
    }

Trusting Data in HealthVault Data Types

Knowing the origin of data is often critical for an application that is using it for sensitive purposes. Some use cases warrant working with only trusted data, some warrant knowing whether the data is from a device or self-entered by the users, and in some cases the application might just want to work with known data providers.

HealthVault provides several ways to look at data provenance. Applications can look at the created_by and updated_by fields of a data type and see whether they were updated by devices or known applications. Additionally, HealthVault provides digital signing of data, which can create a very secure ecosystem of trust.

In our example, we look at the Source attribute of Weight items to see whether they were uploaded by a Withings scale or added manually by the user.

Relating HealthVault Data Types

HealthVault data types are intended to be self-contained units of health information. The data types have distinct health items, such as medications, immunizations, and weight readings. This approach is characteristically different from relational data modeling in which the data is normalized and stored in distinct tables that have explicit relationships with each other. For example, in a relational model, medications may be expressed as separate medication name and medication dosage tables.

Often there is a need to represent relationships between individual health items. For example, a Medication is inherently related to Medication Fill. Medications are associated with a person’s profile as prescribed by a physician, and Medication Fill is used by a pharmacy to prescribe units of medications to a consumer as she consumes the prescribed medications.

The relationship between Medication and Medication Fill is expressed by related items. HealthVault offers related items as an inherent mechanism to link and associate data types. A related item is a special chunk of XML that resides in the common data of a health item. Relationships are usually described in the dependent item and link to the more independent one. For instance, to express the relationship between Medication Fill and Medication, one places related items in the Medication Fill type and points to the Medication type.

Another interesting use of related items is to link together a set of readings that are uploaded from a single device. For example, a device calculating body fat percentage and cholesterol can associate them through related items while uploading them. Because this association is done before uploading to HealthVault, a special unique identifier called a client ID can be used. Client IDs are usually unique identifiers associated to instances of HealthVault data types and are created by the client uploading the data.

One can take relationships even further and associate a set of medical images, medications, and conditions as a result of a particular health incident, maybe an accident. The Mayo Clinic Health Manager application provides a way to create a web of related HealthVault items.

Related items lie beyond the scope of this book, but the reader is encouraged to explore them and contribute interesting uses and examples at http://enablingprogrammableself.com.

Exploring HealthVault Data Types

In our example, we picked some HealthVault types to be used in the application based on our device, data availability, and purpose. Every application programmer needs to go through this data exploration based on your needs and goals. This section gives an overview of all HealthVault types so that the reader can have a good understanding of what is available in the system.

Categorizing HealthVault Data Types

HealthVault stores personal health information ranging from fitness data to medical images. Table 4-1 shows the categorization of the data as displayed to the end user.

Table 4-1. End user categorization of HealthVault data

Category

HealthVault types

Fitness

Aerobic Exercise Session, Aerobic Profile, Aerobic Weekly Goal, Calorie Guideline, Daily Dietary Intake, Exercise, Exercise Samples, Weight Goal

Conditions

Allergy, Concern, Condition, Contraindication, Emotional State, Pregnancy, Problem, Respiratory Profile

Medications

Asthma Inhaler, Asthma Inhaler Use, Daily Medication Usage, Insulin Injection, Insulin Injection Use, Medication, Medication Fill

Health History

Allergic Episode, Annotation, Cardiac Profile, Diabetic Profile, Discharge Summary, Encounter, Explanation of Benefits, Family History, Family History Condition, Family History Person, Health Assessment, Immunization, Procedure, Question Answer

Measurements

Blood Glucose, Blood Oxygen Saturation, Blood Pressure, Body Composition, Body Dimension, Cholesterol Profile, Device, Genetic SNP Results, HbA1C, Heart Rate, Height, Lab Test Results, Microbiology Lab Results, PAP Session, Peak Flow, Radiology Lab Results, Sleep Journal AM, Sleep Journal PM, Spirometer, Vital Signs, Weight

Personal Profile

Advance Directive, Appointment, Basic, Contact, Healthcare Proxy, Life Goal, Payer, Person (emergency or provider contact), Personal Demographic Information, Personal Image

Files

Clinical Document Architecture (CDA), Continuity of Care Document (CCD), Continuity of Care Record (CCR), File, Medical Image Study, Password-Protected Package

Custom Data

Application Data Reference, Application Specific, Group Membership, Group Membership Activity, Link, Status

Fitness

HealthVault offers a range of fitness types. The most commonly used fitness data type is Exercise. Exercise provides a terminology-based categorization of kinds of exercise, e.g., walking or running. Each activity can also be associated with terminology-driven units: Count, Mile, etc.

Devices such as FitBit and Withings work with this type. The exercise activities terminology lists a range of exercise values, including running, walking, swimming, etc. Devices that fetch detailed information on exercise can write individual samples to the Exercise Sample type. For instance, exercise watches developed by Polar write to exercise samples in addition to summarizing the workout in the Exercise type.

This category of types is implemented in a fairly generic way so that various industry formats, such as the one used by Garmin’s Connect website (http://connect.garmin.com/), can translate easily to these types. ISO units can also be translated easily to HealthVault units.

Conditions

Health problems, allergies, contra-indications, and mental health (emotional state) are categorized in the Condition set of types. Conditions are sensitive health problems that usually have an onset date and a status associated with them.

The HealthVault Shell uses the Condition type to record conditions. Conditions entered through the user interface are mapped to SNOMED-CT terminology.

Medication

Medications are the center of modern medicine. HealthVault offers a number of granular types to capture the essence of medications.

A number of pharmacies, including CVS and Walgreens, offer applications for importing prescription data into HealthVault, but the user interface and integration for these applications is a bit challenging.

The most frequently used data types in this category are Medication and Medication Fill. Each prescription could be broken into Medication and Medication Fill. Medication Fill is the recurring part of one’s prescription. As you may recall from Relating HealthVault Data Types, the Medication Fill type is usually related to Medication using the related-item semantics when entered through the HealthVault Shell.

Medications are mapped or coded to the RxNorm Active Medicines terminology.

Health History

Immunizations, procedures, family history, health events, etc. form the basis of the Health History category.

The most notable application using types in this category is the Surgeon General’s Family History application (https://familyhistory.hhs.gov/fhh-web). This powerful application enables individuals to easily create a family health history tree.

Measurements

Measurements are the most extensive category of HealthVault data types. Measurements range from the output of various fitness devices to lab results. For instance, the Withings weighing scale writes to the weight measures, and FitBit writes to sleep measures. The measures are granular records of daily activity and consequently are traceable.

On the other hand, the Lab Test Results type, one of the most complicated HealthVault types, represents results from labs. It can be used in conjunction with industry-standard terminologies.

Personal Profile

The Personal Profile category of HealthVault types contains data pertaining to health care proxies, personal images, and demographics. Almost every HealthVault application that shows a user’s picture or looks at ages or other demographic information uses types in this category.

Files

HealthVault, unlike most personal health records, allows you to upload a number of types of files, and therefore supports data types for these files. Example 4-14 shows the file extensions supported, displayed through a GetServiceDefinition call in PowerShell. This information can also be viewed online in the HealthVault Developer Center’s service definition section (http://developer.healthvault.com/pages/methods/methods.aspx).

Example 4-14. List of file extensions supported by HealthVault

PS C:\Windows\system32> $a = Get-ServiceDefinition
PS C:\Windows\system32> $a.ConfigurationValues

Key                                   Value
---                                   -----
allowedDocumentExtensions             .avi,.bluebutton,.bmp,.ccd,.ccr,.cda,.doc,.docm,...
autoReconcilableTypes                 1e1ccbfc-a55d-4d91-8940-fa2fbf73c195,9c48a2b8-...
blobHashBlockSizeBytes                2097152
blobHashDefaultAlgorithm              SHA256Block
blobStreamWriteTokenTtlMs             172800000
defaultCulture                        en
defaultPersonInfosPerRetrieval        200
emailValidationExp                    ^([\w-+\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]...
liveIdAuthPolicy                      HBI
liveIdEnvironment                     PROD
<... clipped for brevity..>

The Medical Image study type used by the HealthVault Connection Center uploads DICOM medical images in this type. The CCD/CCR types are industry-standard ways by which various hospital information systems send care records to HealthVault. Google Health users, for instance, migrated to HealthVault using the CCR type. The Message file type is the backbone of HealthVault’s Direct integration. Any email message received by the user is stored in the Message type.

Custom Data

The Application Specific type, already covered in the section Creating Custom Types with regard to adding a repository in which to store self-experiments, is the most important custom data type. This type is used by various applications to store information in HealthVault for which no other type or extension to a type is appropriate. For instance, the Vivacity’s Spending Scout application (http://www.spendingscout.com/) stored explanation of benefit information in this type until the HealthVault team created an Explanation of Benefits (EOB) type to support it more directly.

Contributing to the Self-Experimentation Application

In next chapter we will see how we can augment the self-experimentation web application by creating mobile applications. The source for the application is available at http://enablingprogrammableself.com, and we are inviting you, dear reader, to extend this application and make it your own. Perhaps fork the Git repository and contribute your code back, or create Java, Ruby, or Python versions of it!

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required