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();
    }

Get Enabling Programmable Self with HealthVault now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.