Entries Tagged 'MoodTracker' ↓

Graphing for Windows Phone 7– Mood Tracker #6

Wishing every one a happy independence day!

In the last post we enabled Mood Tracker to enter new data in to HealthVault.  Before I start this post in details of adding graphing layer let me motivate it by showing what the graph for Mood Tracker looks like -

image

Fig 1. Graphing Over the 7 days

The interesting aspect here is that we are tracking Mood, Stress and Wellbeing over a period of one week, and looking for patterns in terms of mood, stress and wellbeing correlations. There are better ways to do graphing for this data but this is a simplistic approach.

In order to be able to get data from HealthVault for a specific time period we will have to update the implementation of our GetThings method to allow for a filter for effective date max and min. Notice the interesting formatting we need to do to make DateTime serializable.

private static string EffDateMinXml(DateTime? effDateMin)
{
    if (effDateMin != null)
        return
            string.Format(@"<eff-date-min>{0}</eff-date-min>",
                effDateMin.Value.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ",
                            CultureInfo.InvariantCulture)
                );
    else return "";
}

Once we are powered with a way to selectively get information from HealthVault we can simply make use of the awesome open-source amCharts library. Infact I added it to the project with one-click using NuGet Package manager (note to self: may be post a version of HealthVault Windows Phone library on NuGet). Here is a snippet of how I configured the SerialChart.

<amq:SerialChart x:Name="EmotionsChart" BorderThickness="1" DataSource="{Binding EmotionList}" CategoryValueMemberPath="FormattedWhen" AxisForeground="White" PlotAreaBackground="Black" GridStroke="DarkGray" Height="463" Width="450"> <amq:SerialChart.Graphs> <amq:LineGraph ValueMemberPath="Mood" Title="Mood" Brush="Blue" StrokeThickness="6" BorderBrush="Cornsilk"/> <amq:LineGraph ValueMemberPath="Stress" Title="Stress" Brush="#8000FF00" StrokeThickness="8" /> <amq:LineGraph ValueMemberPath="Wellbeing" Title="Wellbeing" StrokeThickness="2" Brush="#80FF0000"/> </amq:SerialChart.Graphs> </amq:SerialChart>

 

Note that the formatting for the X-Axis is derived by a special property we added to the EmotionalStateModel, it probably is not the right place to add that property.

Over last few days I have implemented an interesting idea to make entering emotional state information easier similar in themes as the original mood tree but more focused on making data entry fun , I call it vMudi.

So next time w’ll look at vMudi.

Entering new data with Mood Tracker #5

In the last post, we discussed how one can display the data retrieved from HealthVault Emotional State data-type.

I showed an interesting LINQ query which sort the HealthVault items returned from a getthings. Well actually turns out that we can do this more efficiently by using the max attribute on group filter in the getthings. The items returned by HealthVault are sorted by eff-date and if we get the first one it should be the latest item!

        public static void GetThings(string typeId, int maxItems,
            EventHandler<HealthVaultResponseEventArgs> responseCallback)
        {
            string thingXml = @"
            <info>
                <group max='{0}'>
                    <filter>
                        <type-id>{1}</type-id>
                        <thing-state>Active</thing-state>
                    </filter>
                    <format>
                        <section>core</section>

Before we get to the topic of this post and discuss how we can put new items in to HealthVault, here a screen shot of how the application looks like once we have enabled the put and prettied up the last reading a little bit –

image

Fig 1. MoodTracker with put enabled!

We can see that for each of the states i.e mood, stress and wellbeing we have a nice slider which lets the user capture their state and we can want this information uploaded with current time stamp once the user hits Save!

        // Save the reading to HealthVault
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            EmotionalStateModel model = new EmotionalStateModel();
            model.Mood = (Mood)c_MoodSlider.Value;
            model.Stress = (Stress)c_StressSlider.Value;
            model.Wellbeing = (Wellbeing)c_WellbeingSlider.Value;
            model.When = DateTime.Now;
            HealthVaultMethods.PutThings(model, PutThingsCompleted);
            SetProgressBarVisibility(true);
        }

Lets get a bit deeper in how the PutThings call works. It fetches the relevant information from the base object and submits that to HealthVault. The design in this case might be a little wary since the put parameters are coming from the emotional state object as well.

        /// <summary>
        /// PutThings Method
        /// </summary>
        /// <param name="item">The health item to upload</param>
        /// <param name="responseCallback">Function to resolve callback</param>
        public static void PutThings(HealthRecordItemModel item,
            EventHandler<HealthVaultResponseEventArgs> responseCallback)
        {
            XElement info = XElement.Parse(item.GetXml());
            HealthVaultRequest request = new HealthVaultRequest("PutThings", "2", info, responseCallback);
            App.HealthVaultService.BeginSendRequest(request);
        }

Voila!! We have an application which can read and update information to HealthVault!

Next Time: We will focus on adding the History or Charting aspects of this application!

Adding A HealthVault DataType to MoodTracker #4

Last time we figured out how to associate our application with HealthVault. In this post we will focus on reading data from HealthVault.

So the data type we settled on was EmotionalState, we can find a sample xml for this type on the HealthVault Developer Center.

Out first goal is to be able to display this type in our application. We need test data for emotional state so we add test information to our developer account from type samples.

image

Fig 1. Adding Emotional State sample to HealthVault record.

Please note: You need to be signed in to developer.healthvault.com to add the above sample.

We can verify that this sample is added to our record by using the HealthExplorer.

image

Fig 2. Emotional State Samples in developer account.

The easiest way to get-things from HealthVault is using the GetThings version 3 method. A Get on things can be performed using various filters for the purposes of this application which just retrieve all the active things of type Emotional State.

                HealthVaultMethods.GetThings(EmotionalStateModel.TypeId, GetThingsCompleted);

To make it easier to work with GetThings I implemented a simple abstraction on the method in HealthVaultMethods class.

Now once we can get thing emotional state things we need to perform two things on the client side.

1. Sort them in the date order and pick the latest one

For this item Linq to XML comes in very handy, just in three lines we can make this query work!

 // using linq to get the latest reading of emotional state
 XElement latestEmotion = (from thingNode in responseNode.Descendants("thing")
         orderby Convert.ToDateTime(thingNode.Element("eff-date").Value) descending
         select thingNode).FirstOrDefault<XElement>();

2. Parse them for the mood, stress and wellbeing data.

We can achieve this my creating a model for Emotional State. Have a good model makes if super easy to parse the XElement to the object we need –

 EmotionalStateModel emotionalState =
     new EmotionalStateModel();
     emotionalState.Parse(latestEmotion.Descendants("data-xml").Descendants("emotion").Single());

XElement and lazy evaluation makes our job super-simple, compared to XPathNavigator -

public void Parse(XElement emotionalState) { this.Mood = (Mood) System.Enum.Parse(typeof(Mood), ((XElement)emotionalState.Element("mood")).Value, true); this.Stress = (Stress) System.Enum.Parse(typeof(Stress), ((XElement)emotionalState.Element("stress")).Value, true); this.Wellbeing = (Wellbeing) System.Enum.Parse(typeof(Wellbeing), ((XElement)emotionalState.Element("wellbeing")).Value, true); }

 

Now we are ready to show the latest emotional state reading!!

 

image

Fig 3. Latest Emotional State Reading in Mood Tracker!

Next Time: We will look at how we can enter new data with Mood Tracker!

Associating Mood Tracker With HealthVault #3

Sorry for the delay in installment #3 in the series of how to write a WP7 app for HealthVault! The code for this application is now hosted on github.

In order for the Mood Tracker application to work with HealthVault we will get appropriate application creation credentials from the HealthVault Service and authorize them through the user with HealthVault Shell.

1. To get the credential from HealthVault Service the application contacts the HealthVault service to get application creation Url.

The code for that is outlined in MyMood.xaml.cs

 void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            App.HealthVaultService.LoadSettings(SettingsFilename);
            App.HealthVaultService.BeginAuthenticationCheck(AuthenticationCompleted, 
                DoShellAuthentication);
            SetProgressBarVisibility(true);
        }

void DoShellAuthentication(object sender, HealthVaultResponseEventArgs e)
        {
            SetProgressBarVisibility(false);

            App.HealthVaultService.SaveSettings(SettingsFilename);

            string url;

            if (_addingRecord)
            {
                url = App.HealthVaultService.GetUserAuthorizationUrl();
            }
...

2. The application creation needs to be validated on behalf of the user.

The best mechanism to achieve this is by having a page with a hosted browser which redirect appropriately to HealthVault and closes the browsers and navigated back to page on a successful authorization.

Following is the code in HostedBrowserPage.xaml :

      void c_webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
        {
            if (e.Uri.OriginalString.Contains("target=AppAuthSuccess"))
            {
                Uri pageUri = new Uri("/MyMood.xaml", UriKind.RelativeOrAbsolute);

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    NavigationService.Navigate(pageUri);
                });
            }
        }

        void HealthVaultWebPage_Loaded(object sender, RoutedEventArgs e)
        {
            string url = App.HealthVaultShellUrl;

            c_webBrowser.Navigate(new Uri(url));
        }

Note that on success the Application is being redirected to MyMood.xaml which is our landing page!

Here is flow of how the above authentication works!

imageimageimage

Step1. Home page      Step2.Sign-in & Auth  Step3. Mood track in action!

Next time: Adding the emotional state data type to Mood Tracker

Previous Post: Getting Started