From 80fb0545830547e9b806efc716969b2a5d2aee3c Mon Sep 17 00:00:00 2001 From: Justin Hutchings Date: Mon, 13 Mar 2017 10:12:32 -0700 Subject: [PATCH] Merged changes for HealthVault S61. Ported hvclientsample to Git --- README.md | 7 + .../HealthVaultProxy/HealthVaultProxy.csproj | 29 +- .../C#/HealthVaultProxy/packages.config | 2 +- .../HealthVaultProviderManagementPortal.sln | 14 +- .../Controllers/ActionPlanController.cs | 137 ++++++-- .../Controllers/OnboardingController.cs | 6 +- ...HealthVaultProviderManagementPortal.csproj | 9 + .../Models/Onboarding/OnboardingRequest.cs | 2 + .../Views/ActionPlan/Plan.cshtml | 1 + .../ActionPlan/TrackingValidationEntry.cshtml | 48 +++ .../Views/ActionPlan/UserInfo.cshtml | 4 +- .../Views/ActionPlan/ValidateTracking.cshtml | 65 ++++ .../Views/HealthData/Index.cshtml | 2 +- .../Views/Home/Index.cshtml | 4 +- .../Views/Onboarding/Index.cshtml | 3 +- .../Views/Onboarding/InviteSuccess.cshtml | 2 + .../Web.config | 5 +- .../buildInfo.xml | 1 + .../ActionPlanTaskOccurrenceMetrics.cs | 2 +- .../ActionPlans/ActionPlanTaskTracking.cs | 87 ++++++ .../ActionPlanTaskTrackingEvidence.cs | 31 ++ .../ActionPlans/ActionPlanTrackingPolicy.cs | 2 +- .../ActionPlans/TrackingValidation.cs | 26 ++ .../Enums/ActionPlanOutcomeType.cs | 5 + .../Enums/ActionPlanTaskType.cs | 5 + .../Enums/TaskTrackingStatus.cs | 18 ++ .../Enums/TrackingType.cs | 17 + ...crosoft.Health.Platform.Entities.V3.csproj | 6 + .../ActionPlanTaskTrackingResponse.cs | 25 ++ .../README.md | 26 +- .../Update-WebConfig.ps1 | 59 ++++ dotNET/hvclientsample/HVClient.cs | 294 ++++++++++++++++++ dotNET/hvclientsample/HVClientSample.csproj | 119 +++++++ dotNET/hvclientsample/HVClientSample.sln | 20 ++ dotNET/hvclientsample/MainForm.Designer.cs | 172 ++++++++++ dotNET/hvclientsample/MainForm.cs | 84 +++++ dotNET/hvclientsample/MainForm.resx | 120 +++++++ dotNET/hvclientsample/Program.cs | 29 ++ .../hvclientsample/Properties/AssemblyInfo.cs | 36 +++ .../Properties/Resources.Designer.cs | 63 ++++ .../hvclientsample/Properties/Resources.resx | 117 +++++++ .../Properties/Settings.Designer.cs | 86 +++++ .../Properties/Settings.settings | 21 ++ dotNET/hvclientsample/Readme.md | 37 +++ dotNET/hvclientsample/app.config | 38 +++ dotNET/hvclientsample/packages.config | 4 + 46 files changed, 1829 insertions(+), 61 deletions(-) create mode 100644 dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/TrackingValidationEntry.cshtml create mode 100644 dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/ValidateTracking.cshtml create mode 100644 dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/buildInfo.xml create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTracking.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTrackingEvidence.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/TrackingValidation.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TaskTrackingStatus.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TrackingType.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Responses/ActionPlanTaskTrackingResponse.cs create mode 100644 dotNET/HealthVaultProviderManagementPortal/Update-WebConfig.ps1 create mode 100644 dotNET/hvclientsample/HVClient.cs create mode 100644 dotNET/hvclientsample/HVClientSample.csproj create mode 100644 dotNET/hvclientsample/HVClientSample.sln create mode 100644 dotNET/hvclientsample/MainForm.Designer.cs create mode 100644 dotNET/hvclientsample/MainForm.cs create mode 100644 dotNET/hvclientsample/MainForm.resx create mode 100644 dotNET/hvclientsample/Program.cs create mode 100644 dotNET/hvclientsample/Properties/AssemblyInfo.cs create mode 100644 dotNET/hvclientsample/Properties/Resources.Designer.cs create mode 100644 dotNET/hvclientsample/Properties/Resources.resx create mode 100644 dotNET/hvclientsample/Properties/Settings.Designer.cs create mode 100644 dotNET/hvclientsample/Properties/Settings.settings create mode 100644 dotNET/hvclientsample/Readme.md create mode 100644 dotNET/hvclientsample/app.config create mode 100644 dotNET/hvclientsample/packages.config diff --git a/README.md b/README.md index 1f3a014..916d28c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,13 @@ HealthVault offers SDKs for many platforms. * [Python](https://github.com/orcasgit/python-healthvault) - An open-source library for developing HealthVault-enabled applications in Python. * [Ruby](http://healthvaultrubylib.codeplex.com/) - An open-source library for developing HealthVault-enabled applications in Ruby. +## Samples +* .NET + * **HealthVault - Your Web Service - Your Client apps** - The HealthVault Proxy Service exposes three primary service-interfaces for client apps. These interfaces correspond to HealthVault feature areas. Specifically, Patient Connect, Get/Put Things, and DOPU. Learn more about HealthVault solution architectures at the Health Team Blog. + * **HealthVault Meaningful Use Reporting** - This sample serves as a demonstration of HealthVault capabilities in support of Meaningful Use Stage 2 (2014 Edition) patient engagement objectives. Refer to Meaningful Use with HealthVault for an overview and technical description of the HealthVault capabilities that support Meaningful Use 2. + * **HealthVaultProviderManagementPortal** - This sample demonstrates how a provider could invite patients and manage ActionPlans. + * **HVClientSample** - This sample demonstrates how to use SODA authentication to access data on HealthVault. + ## Registering your applications All applications must be registered with the [HealthVault Application Configuration Center](https://go.microsoft.com/fwlink/?linkid=838954) before they can connect to the service. During registration, the ACC will request that you upload an appropriate certificate which will be used subsequently to secure communications between your app and the service. For more information on how to obtain an appropriate certificate, please see [MSDN](https://msdn.microsoft.com/en-us/healthvault/dn781357). diff --git a/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/HealthVaultProxy.csproj b/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/HealthVaultProxy.csproj index d044fd6..88ad32d 100644 --- a/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/HealthVaultProxy.csproj +++ b/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/HealthVaultProxy.csproj @@ -44,21 +44,23 @@ - - ..\packages\HealthVault.NET.2.1.0.4\lib\net40\Microsoft.Health.dll - True + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.dll - - ..\packages\HealthVault.NET.2.1.0.4\lib\net40\Microsoft.Health.ItemTypes.dll - True + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Directory.dll - - ..\packages\HealthVault.NET.2.1.0.4\lib\net40\Microsoft.Health.ItemTypes.Old.dll - True + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.ItemTypes.dll - - ..\packages\HealthVault.NET.2.1.0.4\lib\net40\Microsoft.Health.Web.dll - True + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.ItemTypes.Old.dll + + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Web.dll + + + ..\packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Web.Mvc.dll @@ -122,9 +124,6 @@ PreserveNewest - - PreserveNewest - diff --git a/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/packages.config b/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/packages.config index 088064a..93dbf7d 100644 --- a/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/packages.config +++ b/dotNET/HealthVault - Your Web Service - Your Client Apps/C#/HealthVaultProxy/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.sln b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.sln index dd5e45b..bf2f80c 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.sln +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.sln @@ -1,13 +1,17 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.26020.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HealthVaultProviderManagementPortal", "HealthVaultProviderManagementPortal\HealthVaultProviderManagementPortal.csproj", "{35B616C2-F334-4B37-A554-5CC4CDF9390F}" EndProject -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Health.Platform.Entities.V3", "Microsoft.Health.Platform.Entities.V3\Microsoft.Health.Platform.Entities.V3.csproj", "{E5B30C57-260A-4C08-B289-711DF646ADC9}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{4F1D893B-F763-4A54-A561-2A4DFB5FB4C8}" + ProjectSection(SolutionItems) = preProject + README.md = README.md + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -18,10 +22,6 @@ Global {35B616C2-F334-4B37-A554-5CC4CDF9390F}.Debug|Any CPU.Build.0 = Debug|Any CPU {35B616C2-F334-4B37-A554-5CC4CDF9390F}.Release|Any CPU.ActiveCfg = Release|Any CPU {35B616C2-F334-4B37-A554-5CC4CDF9390F}.Release|Any CPU.Build.0 = Release|Any CPU - {3584DABB-F276-43BA-BEB8-52F271E1862B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3584DABB-F276-43BA-BEB8-52F271E1862B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3584DABB-F276-43BA-BEB8-52F271E1862B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3584DABB-F276-43BA-BEB8-52F271E1862B}.Release|Any CPU.Build.0 = Release|Any CPU {E5B30C57-260A-4C08-B289-711DF646ADC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E5B30C57-260A-4C08-B289-711DF646ADC9}.Debug|Any CPU.Build.0 = Debug|Any CPU {E5B30C57-260A-4C08-B289-711DF646ADC9}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/ActionPlanController.cs b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/ActionPlanController.cs index c15add0..225f608 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/ActionPlanController.cs +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/ActionPlanController.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; +using System.Configuration; using System.Globalization; using System.Linq; using System.Net; @@ -64,7 +65,7 @@ public ActionResult CreatePlan(Guid? personId = null, Guid? recordId = null) /// Get a plan for a user. /// [HttpGet] - public ActionResult Plan(string id, Guid? personId = null, Guid? recordId = null) + public ActionResult Plan(Guid id, Guid? personId = null, Guid? recordId = null) { var response = GetPlan(id, personId, recordId); return HandleRestResponse(response, HttpStatusCode.OK); @@ -75,7 +76,7 @@ public ActionResult Plan(string id, Guid? personId = null, Guid? recordId = null /// [HttpPost] [ValidateAntiForgeryToken] - public ActionResult Plan(string id, ActionPlanInstance plan, Guid? personId = null, Guid? recordId = null) + public ActionResult Plan(Guid id, ActionPlanInstance plan, Guid? personId = null, Guid? recordId = null) { var response = PatchPlan(plan, personId, recordId); return HandleRestResponse(response, HttpStatusCode.OK, personId, recordId); @@ -86,7 +87,7 @@ public ActionResult Plan(string id, ActionPlanInstance plan, Guid? personId = nu /// [HttpPost] [ValidateAntiForgeryToken] - public ActionResult RemovePlan(string id, Guid? personId = null, Guid? recordId = null) + public ActionResult RemovePlan(Guid id, Guid? personId = null, Guid? recordId = null) { var response = DeletePlan(id, personId, recordId); return HandleRestResponse(response, HttpStatusCode.NoContent, personId, recordId); @@ -97,7 +98,7 @@ public ActionResult RemovePlan(string id, Guid? personId = null, Guid? recordId /// [HttpPost] [ValidateAntiForgeryToken] - public ActionResult RemoveObjective(string planId, string id, Guid? personId = null, Guid? recordId = null) + public ActionResult RemoveObjective(Guid planId, Guid id, Guid? personId = null, Guid? recordId = null) { var response = DeleteObjective(planId, id, personId, recordId); return HandleRestResponse(response, HttpStatusCode.NoContent, personId, recordId, "Plan", new RouteValueDictionary { { "id", planId } }); @@ -131,7 +132,7 @@ public ActionResult CreateFrequencyTask(Guid planId, Guid objectiveId, Guid? per /// Get a task for a user. /// [HttpGet] - public ActionResult Task(string id, Guid? personId = null, Guid? recordId = null) + public ActionResult Task(Guid id, Guid? personId = null, Guid? recordId = null) { var response = GetTask(id, personId, recordId); return HandleRestResponse(response, HttpStatusCode.OK); @@ -142,7 +143,7 @@ public ActionResult Task(string id, Guid? personId = null, Guid? recordId = null /// [HttpPost] [ValidateAntiForgeryToken] - public ActionResult Task(string id, ActionPlanTaskInstance task, Guid? personId = null, Guid? recordId = null) + public ActionResult Task(Guid id, ActionPlanTaskInstance task, Guid? personId = null, Guid? recordId = null) { var response = PatchTask(task, personId, recordId); return HandleRestResponse(response, HttpStatusCode.OK, personId, recordId, "Plan", new RouteValueDictionary { { "id", task.AssociatedPlanId } }); @@ -153,7 +154,7 @@ public ActionResult Task(string id, ActionPlanTaskInstance task, Guid? personId /// [HttpPost] [ValidateAntiForgeryToken] - public ActionResult RemoveTask(string planId, string id, Guid? personId = null, Guid? recordId = null) + public ActionResult RemoveTask(Guid planId, Guid id, Guid? personId = null, Guid? recordId = null) { var response = DeleteTask(id, personId, recordId); return HandleRestResponse(response, HttpStatusCode.NoContent, personId, recordId, "Plan", new RouteValueDictionary { { "id", planId } }); @@ -163,13 +164,52 @@ public ActionResult RemoveTask(string planId, string id, Guid? personId = null, /// Get plan adherence for a user. /// [HttpGet] - public ActionResult Adherence(string id, Guid? personId = null, Guid? recordId = null) + public ActionResult Adherence(Guid id, Guid? personId = null, Guid? recordId = null) { var now = DateTimeOffset.UtcNow; var response = GetPlanAdherence(id, now.AddDays(-14), now, personId, recordId); return HandleRestResponse(response, HttpStatusCode.OK); } + /// + /// Get a task for a user. + /// + [HttpGet] + public ActionResult ValidateTracking(Guid id, Guid planId, Guid? personId = null, Guid? recordId = null) + { + return View("TrackingValidationEntry", new ActionPlanTaskInstance() + { + Id = id, + AssociatedPlanId = planId + }); + } + + /// + /// Edit a task for a user. + /// + [HttpPost] + [ValidateInput(false)] + [ValidateAntiForgeryToken] + public ActionResult ValidateTracking(Guid id, string thing, Guid? personId = null, Guid? recordId = null) + { + var taskResponse = GetTask(id, personId, recordId); + if (taskResponse.StatusCode != HttpStatusCode.OK) + { + return View("RestError", taskResponse); + } + + var task = JsonConvert.DeserializeObject(taskResponse.ResponseBody); + + var trackingValidation = new TrackingValidation + { + ActionPlanTask = task, + XmlThingDocument = thing + }; + + var response = ValidateTaskAutoTracking(trackingValidation); + return HandleRestResponse>(response, HttpStatusCode.OK); + } + /// /// Get users that have authorized this application /// @@ -287,11 +327,14 @@ private ActionPlanTask CreateDefaultScheduledActionPlanTask(Guid objectiveId, Gu ThumbnailImageUrl = new Uri("https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1s2KS?ver=0ad8"), OrganizationId = "CONTOSO", OrganizationName = "Contoso", - TaskType = ActionPlanTaskType.Unknown, + TaskType = ActionPlanTaskType.Other, SignupName = "Set a consistent wake time", AssociatedObjectiveIds = new Collection { objectiveId }, AssociatedPlanId = planId, // Only needs to be set if adding as task after the plan - TrackingPolicy = new ActionPlanTrackingPolicy(), + TrackingPolicy = new ActionPlanTrackingPolicy + { + IsAutoTrackable = false + }, CompletionType = ActionPlanTaskCompletionType.Scheduled, ScheduledTaskCompletionMetrics = new ActionPlanScheduledTaskCompletionMetrics { @@ -315,18 +358,32 @@ private ActionPlanTask CreateDefaultFrequencyActionPlanTask(Guid objectiveId, Gu { var task = new ActionPlanTask { - Name = "Start my pre-sleep ritual", - ShortDescription = "Develop a short pre-sleep ritual to break the connection between the day's stress and bedtime.", - LongDescription = "Develop a 10-minute pre-sleep ritual to break the connection between the day's stress and bedtime.", + Name = "Measure your blood pressure", + ShortDescription = "Measure your blood pressure - the goal is to have your systolic between 80-120 and diastolic between 60-80 mmHg", + LongDescription = "Measure your blood pressure - the goal is to have your systolic between 80-120 and diastolic between 60-80 mmHg", ImageUrl = new Uri("https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1rXx2?ver=d68e"), ThumbnailImageUrl = new Uri("https://img-prod-cms-rt-microsoft-com.akamaized.net/cms/api/am/imageFileData/RE1s2KS?ver=0ad8"), OrganizationId = "CONTOSO", OrganizationName = "Contoso", - TaskType = ActionPlanTaskType.Unknown, - SignupName = "Establish a relaxing bedtime ritual", + TaskType = ActionPlanTaskType.BloodPressure, + SignupName = "Measure your blood pressure", AssociatedObjectiveIds = new Collection { objectiveId }, AssociatedPlanId = planId, // Only needs to be set if adding as task after the plan - TrackingPolicy = new ActionPlanTrackingPolicy(), + TrackingPolicy = new ActionPlanTrackingPolicy + { + IsAutoTrackable = true, + OccurrenceMetrics = new ActionPlanTaskOccurrenceMetrics + { + EvaluateTargets = false + }, + TargetEvents = new Collection + { + new ActionPlanTaskTargetEvent + { + ElementXPath = "thing/data-xml/blood-pressure" + } + } + }, CompletionType = ActionPlanTaskCompletionType.Frequency, FrequencyTaskCompletionMetrics = new ActionPlanFrequencyTaskCompletionMetrics() { @@ -395,7 +452,7 @@ private HealthServiceRestResponseData GetPlans(Guid? personId, Guid? recordId) /// Otherwise, this gets an action plan of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData GetPlan(string id, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData GetPlan(Guid id, Guid? personId, Guid? recordId) { return CallHeathServiceRest( personId, @@ -410,7 +467,7 @@ private HealthServiceRestResponseData GetPlan(string id, Guid? personId, Guid? r /// Otherwise, this deletes an action plan of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData DeletePlan(string id, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData DeletePlan(Guid id, Guid? personId, Guid? recordId) { return CallHeathServiceRest( personId, @@ -425,7 +482,7 @@ private HealthServiceRestResponseData DeletePlan(string id, Guid? personId, Guid /// Otherwise, this deletes an action plan objective of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData DeleteObjective(string planId, string id, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData DeleteObjective(Guid planId, Guid id, Guid? personId, Guid? recordId) { return CallHeathServiceRest( personId, @@ -457,7 +514,7 @@ private HealthServiceRestResponseData CreateTask(ActionPlanTask task, Guid? pers /// Otherwise, this gets an action plan task of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData GetTask(string id, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData GetTask(Guid id, Guid? personId, Guid? recordId) { return CallHeathServiceRest( personId, @@ -489,7 +546,7 @@ private HealthServiceRestResponseData PatchTask(ActionPlanTaskInstance task, Gui /// Otherwise, this deletes an action plan task of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData DeleteTask(string id, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData DeleteTask(Guid id, Guid? personId, Guid? recordId) { return CallHeathServiceRest( personId, @@ -498,8 +555,25 @@ private HealthServiceRestResponseData DeleteTask(string id, Guid? personId, Guid "v3/actionplantasks/" + id); } + /// + /// Call the HV REST API to check how auto tracking matches a task against a HealthVault XML thing. + /// As this API doesn't actually access HealthVault (all data is being passed in), we've only done this in an online manner. + /// + private HealthServiceRestResponseData ValidateTaskAutoTracking(TrackingValidation trackingValidation) + { + return CallHeathServiceRest( + null, + null, + "POST", + "v3/actionplantasks/ValidateTracking", + null, + JsonConvert.SerializeObject(trackingValidation)); + } + private List GetAuthorizedPeople() { + CheckOfflineAuthorization(); + var connection = new OfflineWebApplicationConnection( HealthWebApplicationConfiguration.Current.ApplicationId, HealthWebApplicationConfiguration.Current.HealthVaultMethodUrl, @@ -520,7 +594,7 @@ private List GetAuthorizedPeople() /// Otherwise, this gets action plan adherence of the user who is actively signed into the application ("online" scenario). /// See Getting Started doc for more information on offline scenarios. /// - private HealthServiceRestResponseData GetPlanAdherence(string id, DateTimeOffset startTime, DateTimeOffset endTime, Guid? personId, Guid? recordId) + private HealthServiceRestResponseData GetPlanAdherence(Guid id, DateTimeOffset startTime, DateTimeOffset endTime, Guid? personId, Guid? recordId) { var queryParameters = new NameValueCollection { @@ -555,7 +629,7 @@ private HealthServiceRestResponseData CallHeathServiceRestOnline(string httpVerb // Person and record ID identify the patient for whom to retrieve the plan. RecordId = User.PersonInfo().SelectedRecord.Id }; - + request.Execute(); return request.Response; @@ -563,6 +637,8 @@ private HealthServiceRestResponseData CallHeathServiceRestOnline(string httpVerb private HealthServiceRestResponseData CallHeathServiceRestOffline(Guid personId, Guid recordId, string httpVerb, string path, NameValueCollection queryStringParameters = null, string requestBody = null) { + CheckOfflineAuthorization(); + // Person and record ID identify the patient for whom to retrieve the plans. var connection = new OfflineWebApplicationConnection( HealthWebApplicationConfiguration.Current.ApplicationId, @@ -584,10 +660,23 @@ private HealthServiceRestResponseData CallHeathServiceRestOffline(Guid personId, // Person and record ID identify the patient for whom to retrieve the plans. RecordId = recordId }; - + request.Execute(); return request.Response; } + + private void CheckOfflineAuthorization() + { + var authorizedPersonIds = ConfigurationManager.AppSettings["OfflineAuthorizedPersonIDs"]; + if (!string.IsNullOrWhiteSpace(authorizedPersonIds)) + { + var personIds = authorizedPersonIds.Split(','); + if (!personIds.Contains(User?.PersonInfo()?.PersonId.ToString())) + { + throw new UnauthorizedAccessException(); + } + } + } } } \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/OnboardingController.cs b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/OnboardingController.cs index ab23dda..6d9e4fa 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/OnboardingController.cs +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Controllers/OnboardingController.cs @@ -67,7 +67,11 @@ private OnboardingRequest CreateDefaultOnboardingRequest() onboardingRequest.FriendlyName = "John"; onboardingRequest.ApplicationPatientId = "johndoe-" + Guid.NewGuid(); // Must be unique onboardingRequest.Email = "john@contoso.com"; - onboardingRequest.Birthday = new DateTime(1989, 8, 11); + onboardingRequest.Birthday = new DateTime(1955, 10, 28); + + // This is a workaround for bug#48405. TODO: Remove once S61 is available. + onboardingRequest.Height = 155; //In cm + onboardingRequest.Weight = 50000; //In g // 1a. Specify a patient/provider secret question & answer to validate the identity of the invitee onboardingRequest.SecretQuestion = "What color is the sky?"; diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.csproj b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.csproj index ae7d07c..7d5d75b 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.csproj +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal.csproj @@ -133,6 +133,9 @@ + + Always + @@ -180,6 +183,12 @@ Microsoft.Health.Platform.Entities.V3 + + + + + + 10.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Models/Onboarding/OnboardingRequest.cs b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Models/Onboarding/OnboardingRequest.cs index 273e907..cf429b4 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Models/Onboarding/OnboardingRequest.cs +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Models/Onboarding/OnboardingRequest.cs @@ -8,6 +8,7 @@ using System; using System.Collections.ObjectModel; +using System.ComponentModel.DataAnnotations; namespace HealthVaultProviderManagementPortal.Models.Onboarding { @@ -76,6 +77,7 @@ public OnboardingRequest() /// /// Gets and sets the user's birthday /// + [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")] public DateTime Birthday { get; set; } /// diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/Plan.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/Plan.cshtml index 528994d..7c9af66 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/Plan.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/Plan.cshtml @@ -112,6 +112,7 @@ @task.Name @task.Status @Html.ActionLink("Edit", "Task", new { planId = task.AssociatedPlanId, id = task.Id, personId = Request.Params["personId"], recordId = Request.Params["recordId"] }, new { cssClass = "btn btn-default" }) + @Html.ActionLink("Validate auto tracking", "ValidateTracking", new { planId = task.AssociatedPlanId, id = task.Id, personId = Request.Params["personId"], recordId = Request.Params["recordId"] }, new { cssClass = "btn btn-default" }) } diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/TrackingValidationEntry.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/TrackingValidationEntry.cshtml new file mode 100644 index 0000000..ad26256 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/TrackingValidationEntry.cshtml @@ -0,0 +1,48 @@ +@* + Copyright (c) Microsoft Corporation. All rights reserved. + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*@ +@model Microsoft.Health.Platform.Entities.V3.ActionPlans.ActionPlanTaskInstance + +@{ + ViewBag.Title = "Validate Task Auto Tracking"; +} +@Html.Partial("UserInfo") + +

@Html.ActionLink("<< Back to plan", "Plan", new { id = Model.AssociatedPlanId, personId = Request.Params["personId"], recordId = Request.Params["recordId"] }, new { cssClass = "btn btn-default" })

+ +

Validate Task Auto Tracking

+ +@using (Html.BeginForm("ValidateTracking", "ActionPlan")) +{ + @Html.AntiForgeryToken() + @Html.Hidden("personID", Request.Params["personId"]) + @Html.Hidden("recordId", Request.Params["recordId"]) + +
+
+ @Html.LabelFor(model => model.Id, htmlAttributes: new { @class = "control-label col-md-2" }) +
+ @Html.EditorFor(model => model.Id, new { htmlAttributes = new { @class = "form-control", @readonly = true }}) +
+
+ +
+ @Html.Label("HealthVault thing", htmlAttributes: new {@class = "control-label col-md-2"}) +
+ @Html.TextArea("thing", htmlAttributes: new {@class = "form-control", rows = 30}) +
+
+ +
+
+ +
+
+
+} diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/UserInfo.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/UserInfo.cshtml index d52a84a..13b1d6b 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/UserInfo.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/UserInfo.cshtml @@ -1,10 +1,10 @@  \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/ValidateTracking.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/ValidateTracking.cshtml new file mode 100644 index 0000000..b5a74df --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/ActionPlan/ValidateTracking.cshtml @@ -0,0 +1,65 @@ +@* + Copyright (c) Microsoft Corporation. All rights reserved. + MIT License + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*@ +@model Microsoft.Health.Platform.Entities.V3.Responses.ActionPlanTaskTrackingResponse + +@{ + ViewBag.Title = "Task Auto Tracking Validation Results"; +} +@Html.Partial("UserInfo") + +

Task Auto Tracking Validation Results

+@if (Model.TaskTrackingInstances == null || !Model.TaskTrackingInstances.Any()) +{ +

The entered Thing XML will not auto track against the given task

+} +else +{ + + + + + + + + + + + + @foreach (var instance in Model.TaskTrackingInstances) + { + + + + + + + + } + +
Tracking IDTypeTracking DateTimeStatusEvidence
@instance.Id@instance.TrackingType@instance.TrackingDateTime@instance.TrackingStatus + @if (instance.Evidence != null) + { + if (instance.Evidence.HVThings != null) + { + foreach (var evidence in instance.Evidence.HVThings) + { +

@evidence

+ } + } + if (instance.Evidence.Trackings != null) + { + foreach (var evidence in instance.Evidence.Trackings) + { +

@evidence

+ } + } + } +
+} diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/HealthData/Index.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/HealthData/Index.cshtml index 5fa41dc..a3967f4 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/HealthData/Index.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/HealthData/Index.cshtml @@ -24,7 +24,7 @@ @if (Model == null) {

- You don't have any weight values! Add some! + No weight values found. Confirm that weight values are available in HealthVault. Note: This operation requires that the app has been authorized for Online access to the weight data type.

} else diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Home/Index.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Home/Index.cshtml index 6f60700..ee96954 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Home/Index.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Home/Index.cshtml @@ -12,7 +12,7 @@ }
-

HealthVault sample app

+

HealthVault Provider Management Portal

@@ -25,7 +25,7 @@

View and update health measurements

-

Examples of reading and writing patients' health data stored in HealthVault.

+

Examples of reading and writing patients' health data stored in HealthVault.

Go »

diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/Index.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/Index.cshtml index af6f1d2..a65e1d5 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/Index.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/Index.cshtml @@ -14,6 +14,7 @@ }

Create and send an invitation

+

This page can be used to create user-specific invitations for your organization's remote monitoring solution. The next page will provide an invitation URL that you can provide your patient directly.

@using (Html.BeginForm("CreateInvite", "Onboarding")) { @@ -58,7 +59,7 @@
- @Html.LabelFor(model => model.Birthday, htmlAttributes: new { @class = "control-label col-md-2" }) + @Html.LabelFor(model => model.Birthday, "Birthday (" + System.Globalization.DateTimeFormatInfo.CurrentInfo.ShortDatePattern + ")", htmlAttributes: new { @class = "control-label col-md-2" })
@Html.EditorFor(model => model.Birthday, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Birthday, "", new { @class = "text-danger" }) diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/InviteSuccess.cshtml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/InviteSuccess.cshtml index 3fb2589..8d29b2a 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/InviteSuccess.cshtml +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Views/Onboarding/InviteSuccess.cshtml @@ -15,6 +15,8 @@

Success!

+

You've successfully generated an invitation code! Send the Invitation URL to your patients to onboard them onto your app.

+

Invitation code: @Model.InvitationCode

Invitation URL: @Model.InviteUrl

\ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Web.config b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Web.config index aedd53a..839c452 100644 --- a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Web.config +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/Web.config @@ -31,13 +31,16 @@ + + + - + diff --git a/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/buildInfo.xml b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/buildInfo.xml new file mode 100644 index 0000000..7dde50e --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/HealthVaultProviderManagementPortal/buildInfo.xml @@ -0,0 +1 @@ + diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskOccurrenceMetrics.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskOccurrenceMetrics.cs index fde8951..9a55d66 100644 --- a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskOccurrenceMetrics.cs +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskOccurrenceMetrics.cs @@ -18,7 +18,7 @@ public class ActionPlanTaskOccurrenceMetrics /// /// Gets or sets a value indicating whether or not to evaluate the targets /// - public bool EvaluateTargets { get; set; } + public bool? EvaluateTargets { get; set; } /// /// Gets or sets the targets to evaluate diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTracking.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTracking.cs new file mode 100644 index 0000000..cce0765 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTracking.cs @@ -0,0 +1,87 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.ActionPlans +{ + using System; + using Microsoft.Health.Platform.Entities.V3.Enums; + + /// + /// A tracking object for an Action Plan Task + /// + public class ActionPlanTaskTracking + { + /// + /// Gets or sets the Id of the task tracking + /// + public string Id { get; set; } + + /// + /// Gets or sets the task tracking type + /// + public TrackingType TrackingType { get; set; } + + /// + /// Gets or sets the timezone offset of the task tracking, + /// if a task is local time based, it should be set as null + /// + public int? TimeZoneOffset { get; set; } + + /// + /// Gets or sets the task tracking time + /// + public DateTimeOffset TrackingDateTime { get; set; } + + /// + /// Gets or sets the creation time of the task tracking + /// + public DateTimeOffset CreationDateTime { get; set; } + + /// + /// Gets or sets the task tracking status + /// + public TaskTrackingStatus TrackingStatus { get; set; } + + /// + /// Gets or sets the start time of the occurrence window, + /// it is null for Completion and OutOfWindow tracking + /// + public DateTimeOffset? OccurrenceStart { get; set; } + + /// + /// Gets or sets the end time of the occurrence window, + /// it is null for Completion and OutOfWindow tracking + /// + public DateTimeOffset? OccurrenceEnd { get; set; } + + /// + /// Gets or sets the start time of the completion window + /// + public DateTimeOffset CompletionStart { get; set; } + + /// + /// Gets or sets the end time of the completion window + /// + public DateTimeOffset CompletionEnd { get; set; } + + /// + /// Gets or sets task Id + /// + public Guid TaskId { get; set; } + + /// + /// Gets or sets the tracking feedback + /// + public string Feedback { get; set; } + + /// + /// Gets or sets the evidence of the task tracking + /// + public ActionPlanTaskTrackingEvidence Evidence { get; set; } + } +} \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTrackingEvidence.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTrackingEvidence.cs new file mode 100644 index 0000000..f503fa3 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTaskTrackingEvidence.cs @@ -0,0 +1,31 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.ActionPlans +{ + using System.Collections.ObjectModel; + + /// + /// The evidence associated Action Plan Task Tracking + /// + public class ActionPlanTaskTrackingEvidence + { + /// + /// The Tracking IDs as evidence + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Trackings", Justification = "These are tracking objects")] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Set needed for serialization.")] + public Collection Trackings { get; set; } + + /// + /// The HealthVault ThingIDs as evidence + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Set needed for serialization.")] + public Collection HVThings { get; set; } + } +} \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTrackingPolicy.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTrackingPolicy.cs index c7a92bc..00d67ef 100644 --- a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTrackingPolicy.cs +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/ActionPlanTrackingPolicy.cs @@ -19,7 +19,7 @@ public class ActionPlanTrackingPolicy /// /// Gets or sets an indicator as to whether or not the Tracking Policy is AutoTrackable /// - public bool IsAutoTrackable { get; set; } + public bool? IsAutoTrackable { get; set; } /// /// Gets or sets the Occurrence Metrics for the tracking policy diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/TrackingValidation.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/TrackingValidation.cs new file mode 100644 index 0000000..01dac64 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/ActionPlans/TrackingValidation.cs @@ -0,0 +1,26 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.ActionPlans +{ + /// + /// class for Tracking Validation + /// + public class TrackingValidation + { + /// + /// Gets or sets the action plan task. + /// + public ActionPlanTask ActionPlanTask { get; set; } + + /// + /// Gets or sets the XML thing document. + /// + public string XmlThingDocument { get; set; } + } +} diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanOutcomeType.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanOutcomeType.cs index a921bed..dd3008b 100644 --- a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanOutcomeType.cs +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanOutcomeType.cs @@ -42,5 +42,10 @@ public enum ActionPlanOutcomeType /// The outcome type is "minutes to fall asleep per night" /// MinutesToFallAsleepPerNight = 5, + + /// + /// The outcome is some other type + /// + Other = 6, } } \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanTaskType.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanTaskType.cs index f9a914f..63f5bad 100644 --- a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanTaskType.cs +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/ActionPlanTaskType.cs @@ -22,5 +22,10 @@ public enum ActionPlanTaskType /// The task is related to bloodpressure /// BloodPressure = 1, + + /// + /// The task is another type + /// + Other = 2, } } \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TaskTrackingStatus.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TaskTrackingStatus.cs new file mode 100644 index 0000000..9fdb20f --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TaskTrackingStatus.cs @@ -0,0 +1,18 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.Enums +{ + public enum TaskTrackingStatus + { + Unknown, + Occurrence, + Completion, + OutOfWindow + } +} diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TrackingType.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TrackingType.cs new file mode 100644 index 0000000..7e21350 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Enums/TrackingType.cs @@ -0,0 +1,17 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.Enums +{ + public enum TrackingType + { + Unknown, + Manual, + Auto + } +} diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Microsoft.Health.Platform.Entities.V3.csproj b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Microsoft.Health.Platform.Entities.V3.csproj index 2634727..67f8a45 100644 --- a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Microsoft.Health.Platform.Entities.V3.csproj +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Microsoft.Health.Platform.Entities.V3.csproj @@ -51,10 +51,13 @@ + + + @@ -67,9 +70,12 @@ + + + diff --git a/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Responses/ActionPlanTaskTrackingResponse.cs b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Responses/ActionPlanTaskTrackingResponse.cs new file mode 100644 index 0000000..5432eb8 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Microsoft.Health.Platform.Entities.V3/Responses/ActionPlanTaskTrackingResponse.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace Microsoft.Health.Platform.Entities.V3.Responses +{ + using System.Collections.ObjectModel; + + /// + /// The action plans task tracking collection response + /// + /// The type of action plan task occurrence to wrap + public class ActionPlanTaskTrackingResponse : ResponseBase + { + /// + /// The collection of tasks tracking occurrences + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Set needed for deserialization")] + public Collection TaskTrackingInstances { get; set; } + } +} \ No newline at end of file diff --git a/dotNET/HealthVaultProviderManagementPortal/README.md b/dotNET/HealthVaultProviderManagementPortal/README.md index ccf2355..0a1835a 100644 --- a/dotNET/HealthVaultProviderManagementPortal/README.md +++ b/dotNET/HealthVaultProviderManagementPortal/README.md @@ -3,7 +3,25 @@ Please make sure you've reviewed the Getting Started documentation on [Action Plans](http://msdn.microsoft.com/en-us/healthvault/mt778893). To run this sample: -1. In the web.config, update the ApplicationId setting to the ID for the application you created in ACC. -2. Make sure the private key for the application is installed on your machine. (See section 4.2 in the Getting Started document.) -3. Build and run the solution. - -> This should automatically restore the HealthVault.NET NuGet package, and all other NuGet packages required by the project. +1. Make sure you've registered your app in the [Application Config Center](https://config.healthvault-ppe.com/) (ACC). +2. Add the ApplicationId you received in the ACC to the Web.config file. + > Note: From a command prompt, you can run the following script to set your ApplicationId quickly. Please replace the ApplicationId below with the value you received. + > + > ```cmd + > powershell .\Update-WebConfig.ps1 -ApplicationId "00000000-0000-0000-0000-000000000000" + ``` +3. Make sure the private key for the application is installed on your machine. See how to [create or install a certificate on MSDN](https://msdn.microsoft.com/en-us/healthvault/mt778893#_Certificates). +4. Build and run the solution. + * This should automatically restore the HealthVault.NET NuGet package, and all other NuGet packages required by the project. + +> Note: Developers outside the US must update the Web.config with the appropriate URLs for their instance. +> * ShellUrl: "https://account.healthvault-ppe.co.uk/" +> * HealthServiceUrl: "https://platform.healthvault-ppe.co.uk/platform/" +> * RestHealthServiceUrl: "https://platform.healthvault-ppe.co.uk/" +> +> From a command prompt, you may also run the following script to set your market quickly. +> +> ```cmd +> powershell .\Update-WebConfig.ps1 -Instance EU +> ``` + diff --git a/dotNET/HealthVaultProviderManagementPortal/Update-WebConfig.ps1 b/dotNET/HealthVaultProviderManagementPortal/Update-WebConfig.ps1 new file mode 100644 index 0000000..f5ac043 --- /dev/null +++ b/dotNET/HealthVaultProviderManagementPortal/Update-WebConfig.ps1 @@ -0,0 +1,59 @@ +<# + +.SYNOPSIS +This script can be used to quickly edit the Web.config file for your sample. + +.EXAMPLE +./Update-WebConfig.ps1 -ApplicationId "00000000-0000-0000-0000-000000000000" -Instance US + +.PARAMETER Reset +The Reset parameter restores this file back to the state which is required by GitHub to protect your app's ApplicationId. + +.PARAMETER ApplicationId +The ApplicationId parameter allows you to specify the GUID value (without braces) which is registed in HealthVault for your app. + +.PARAMETER Instance +The Instance parameter allows you to specify the appropriate server instances for HealthVault. + +#> + +Param +( + [switch] $Reset, + + [guid] $ApplicationId, + + [ValidateSet('US', 'EU', IgnoreCase = $true)] + [string] $Instance +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +$webConfigPath = $PSScriptRoot + "\HealthVaultProviderManagementPortal\Web.config" +[xml] $webConfigXml = Get-Content -Path $webConfigPath -Raw +$defaultApplicationId = "your application ID here"; + +if ($Reset) { + ($webConfigXml | Select-Xml -XPath "//add[@key='ApplicationId']/@value").Node.InnerText = $defaultApplicationId; +} +elseif ($ApplicationId) { + ($webConfigXml | Select-Xml -XPath "//add[@key='ApplicationId']/@value").Node.InnerText = $ApplicationId +} + +switch ($Instance) { + + 'US' { + ($webConfigXml | Select-xml -XPath "//add[@key='ShellUrl']/@value").Node.InnerText = "https://account.healthvault-ppe.com/" + ($webConfigXml | Select-xml -XPath "//add[@key='HealthServiceUrl']/@value").Node.InnerText = "https://platform.healthvault-ppe.com/platform/" + ($webConfigXml | Select-xml -XPath "//add[@key='RestHealthServiceUrl']/@value").Node.InnerText = "https://data.ppe.microsofthealth.net" + } + + 'EU' { + ($webConfigXml | Select-xml -XPath "//add[@key='ShellUrl']/@value").Node.InnerText = "https://account.healthvault-ppe.co.uk/" + ($webConfigXml | Select-xml -XPath "//add[@key='HealthServiceUrl']/@value").Node.InnerText = "https://platform.healthvault-ppe.co.uk/platform/" + ($webConfigXml | Select-xml -XPath "//add[@key='RestHealthServiceUrl']/@value").Node.InnerText = "https://data.ppe.microsoft.health.co.uk" + } +} + +$webConfigXml.Save($webConfigPath) diff --git a/dotNET/hvclientsample/HVClient.cs b/dotNET/hvclientsample/HVClient.cs new file mode 100644 index 0000000..f28b35a --- /dev/null +++ b/dotNET/hvclientsample/HVClient.cs @@ -0,0 +1,294 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Health; +using Microsoft.Health.ItemTypes; + +namespace HVClientSample +{ + /// + /// HVClient + /// Contains sample code for provisioning a client application, creating + /// a connection and how to retrieve data from HealthVault + /// + class HVClient + { + + #region Constructors and initialization + /// + /// Constructor + /// + public HVClient() + { + Initialize(); + } + + /// + /// Initializes the variables required for HVClient. + /// + private void Initialize() + { + // Read the master application id from config file + // Master application should have been pre-created in HealthVault + // In HealthVault pre-production environment, the master application + // should have been created using Application Configuration Center + _masterApplicationId = new Guid(ConfigurationSettings.AppSettings["ApplicationId"]); + + _isProvisioned = Properties.Settings.Default.IsProvisioned; + + if (_isProvisioned) + { + // Read the app, person, and record ID, along + // with the instance ID if that app has already + // been provisioned + _applicationId = Properties.Settings.Default.ApplicationId; + _personId = Properties.Settings.Default.PersonId; + _recordId = Properties.Settings.Default.RecordGuid; + + string serviceInstanceId = Properties.Settings.Default.ServiceInstanceId; + _serviceInstance = ServiceInfo.Current.ServiceInstances[serviceInstanceId]; + + _healthClientApplication = HealthClientApplication.Create(_applicationId, _masterApplicationId, _serviceInstance); + } + } + #endregion + + #region Public Properties + + public HealthClientApplication HealthClientApplication + { + get + { + return _healthClientApplication; + } + } + + public HealthServiceInstance ServiceInstance + { + get + { + return _serviceInstance; + } + } + + public Guid PersonId + { + get + { + return _personId; + } + } + + public Guid RecordId + { + get + { + return _recordId; + } + } + + public bool IsProvisioned + { + get + { + return _isProvisioned; + } + } + + #endregion + + #region Public Methods + + /// + /// Provisions the application. + /// If application does not exist, it launches the application + /// creation process. + /// + public void ProvisionApplication() + { + // generate a GUID that will be used for the application creation. + _applicationId = Guid.NewGuid(); + + HealthClientApplication client = HealthClientApplication.Create(_applicationId, _masterApplicationId); + client.StartApplicationCreationProcess(); + + // launch dialog box to wait + MessageBox.Show("After completing application setup in browser, click OK"); + + // check if the app is provisioned now + HealthServiceInstance instance = FindProvisionedServiceInstance(); + + if (instance == null) + { + MessageBox.Show("The application setup in your browser did not complete."); + return; + } + + _serviceInstance = instance; + _healthClientApplication = client; + + // the app was provisioned + _healthClientApplication = HealthClientApplication.Create( + _applicationId, + _masterApplicationId, + _serviceInstance); + + // Get list of authorized people + ApplicationConnection connection = HealthClientApplication.ApplicationConnection; + List authorizedPeople = new List(connection.GetAuthorizedPeople()); + + if (authorizedPeople.Count == 0) + { + MessageBox.Show("No records were authorized. Application setup process did not complete."); + return; + } + + // save person ID, record ID, and service instance ID + // assumption is the first person is the current person ID and there is only + // one recordid for the person. For more persons and records, a selection + // UI would need to be shown + PersonInfo personInfo = authorizedPeople[0]; + + _personId = personInfo.PersonId; + _recordId = personInfo.SelectedRecord.Id; + _isProvisioned = true; + + SaveUserSettings(); + + MessageBox.Show("Application + " + _applicationId + " is now provisioned"); + } + + /// + /// Finds the instance of the HealthVault web-service + /// where the child application has been provisioned. + /// + private HealthServiceInstance FindProvisionedServiceInstance() + { + foreach (var instance in ServiceInfo.Current.ServiceInstances.Values) + { + var client = HealthClientApplication.Create( + _applicationId, _masterApplicationId, instance.ShellUrl, instance.HealthServiceUrl); + + ApplicationInfo appInfo = client.GetApplicationInfo(); + + if (appInfo != null) + { + return instance; + } + } + + return null; + } + + public void DeProvision() + { + Guid tempPersonId = _personId; + Guid tempRecordId = _recordId; + + // first reset local state so + // that even if things fail after this + // the next app launch will have fresh state + _isProvisioned = false; + _personId = Guid.Empty; + _recordId = Guid.Empty; + _applicationId = Guid.Empty; + SaveUserSettings(); + + // attempt to remove authorization of application from server + HealthClientAuthorizedConnection connection = + HealthClientApplication.CreateAuthorizedConnection(tempPersonId); + + HealthRecordAccessor accessor = new HealthRecordAccessor(connection, tempRecordId); + accessor.RemoveApplicationAuthorization(); + + // delete the local certificate + _healthClientApplication.DeleteCertificate(); + + _healthClientApplication = null; + } + + /// + /// Creates a connection to HealthVault and obtains weight data + /// + /// + public HealthRecordItemCollection GetWeightFromHealthVault() + { + if (!_isProvisioned) + { + MessageBox.Show("Please provision application first"); + return null; + } + + HealthClientAuthorizedConnection connection = + HealthClientApplication.CreateAuthorizedConnection(PersonId); + + HealthRecordAccessor accessor = new HealthRecordAccessor(connection, RecordId); + + HealthRecordSearcher searcher = accessor.CreateSearcher(); + HealthRecordFilter filter = new HealthRecordFilter(Weight.TypeId); + searcher.Filters.Add(filter); + HealthRecordItemCollection items = searcher.GetMatchingItems()[0]; + return items; + } + + /// + /// Creates a connection to HealthVault and sets weight data + /// + /// + public void SetWeightOnHealthVault(double weightValue) + { + if (!_isProvisioned) + { + MessageBox.Show("Please provision application first"); + return; + } + + HealthClientAuthorizedConnection connection = + HealthClientApplication.CreateAuthorizedConnection(PersonId); + + HealthRecordAccessor accessor = new HealthRecordAccessor(connection, RecordId); + Weight weight = new Weight(); + weight.Value = new WeightValue(weightValue); + accessor.NewItem(weight); + } + + #endregion + + #region Private methods + + private void SaveUserSettings() + { + Properties.Settings.Default.PersonId = _personId; + Properties.Settings.Default.RecordGuid = _recordId; + Properties.Settings.Default.IsProvisioned = _isProvisioned; + Properties.Settings.Default.ApplicationId = _applicationId; + Properties.Settings.Default.ServiceInstanceId = _serviceInstance.Id; + Properties.Settings.Default.Save(); + } + + #endregion + + #region private vars + private Guid _applicationId; + private Guid _masterApplicationId; + private Guid _personId; + private Guid _recordId; + private HealthServiceInstance _serviceInstance; + private bool _isProvisioned; + + HealthClientApplication _healthClientApplication; + + #endregion + } +} \ No newline at end of file diff --git a/dotNET/hvclientsample/HVClientSample.csproj b/dotNET/hvclientsample/HVClientSample.csproj new file mode 100644 index 0000000..dc6d5db --- /dev/null +++ b/dotNET/hvclientsample/HVClientSample.csproj @@ -0,0 +1,119 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {D817A15C-650D-49BE-96F8-C7772EC96DED} + WinExe + Properties + HVClientSample + HVClientSample + v4.6.2 + 512 + true + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.dll + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Directory.dll + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.ItemTypes.dll + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.ItemTypes.Old.dll + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Web.dll + + + packages\HealthVault.NET.2.60.20205.1\lib\net45\Microsoft.Health.Web.Mvc.dll + + + + 4.0 + + + 4.0 + + + 4.0 + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + Designer + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + + + + \ No newline at end of file diff --git a/dotNET/hvclientsample/HVClientSample.sln b/dotNET/hvclientsample/HVClientSample.sln new file mode 100644 index 0000000..b65ec0a --- /dev/null +++ b/dotNET/hvclientsample/HVClientSample.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HVClientSample", "HVClientSample.csproj", "{D817A15C-650D-49BE-96F8-C7772EC96DED}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D817A15C-650D-49BE-96F8-C7772EC96DED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D817A15C-650D-49BE-96F8-C7772EC96DED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D817A15C-650D-49BE-96F8-C7772EC96DED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D817A15C-650D-49BE-96F8-C7772EC96DED}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/dotNET/hvclientsample/MainForm.Designer.cs b/dotNET/hvclientsample/MainForm.Designer.cs new file mode 100644 index 0000000..a825b89 --- /dev/null +++ b/dotNET/hvclientsample/MainForm.Designer.cs @@ -0,0 +1,172 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +namespace HVClientSample +{ + partial class MainForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.buttonProvision = new System.Windows.Forms.Button(); + this.textBoxWeight = new System.Windows.Forms.TextBox(); + this.WeightLabel = new System.Windows.Forms.Label(); + this.buttonGetWeight = new System.Windows.Forms.Button(); + this.buttonPutWeight = new System.Windows.Forms.Button(); + this.listViewWeight = new System.Windows.Forms.ListView(); + this.columnHeaderWeight = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.columnHeaderWhen = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); + this.buttonDeProvision = new System.Windows.Forms.Button(); + this.labelConnectionStatus = new System.Windows.Forms.Label(); + this.SuspendLayout(); + // + // buttonProvision + // + this.buttonProvision.Location = new System.Drawing.Point(13, 38); + this.buttonProvision.Name = "buttonProvision"; + this.buttonProvision.Size = new System.Drawing.Size(75, 23); + this.buttonProvision.TabIndex = 0; + this.buttonProvision.Text = "Provision"; + this.buttonProvision.UseVisualStyleBackColor = true; + this.buttonProvision.Click += new System.EventHandler(this.buttonProvision_Click); + // + // textBoxWeight + // + this.textBoxWeight.Location = new System.Drawing.Point(68, 154); + this.textBoxWeight.Name = "textBoxWeight"; + this.textBoxWeight.Size = new System.Drawing.Size(131, 20); + this.textBoxWeight.TabIndex = 1; + this.textBoxWeight.Text = "150"; + // + // WeightLabel + // + this.WeightLabel.AutoSize = true; + this.WeightLabel.Location = new System.Drawing.Point(12, 154); + this.WeightLabel.Name = "WeightLabel"; + this.WeightLabel.Size = new System.Drawing.Size(41, 13); + this.WeightLabel.TabIndex = 2; + this.WeightLabel.Text = "Weight"; + // + // buttonGetWeight + // + this.buttonGetWeight.Location = new System.Drawing.Point(15, 197); + this.buttonGetWeight.Name = "buttonGetWeight"; + this.buttonGetWeight.Size = new System.Drawing.Size(52, 21); + this.buttonGetWeight.TabIndex = 3; + this.buttonGetWeight.Text = "Get"; + this.buttonGetWeight.UseVisualStyleBackColor = true; + this.buttonGetWeight.Click += new System.EventHandler(this.buttonGetWeight_Click); + // + // buttonPutWeight + // + this.buttonPutWeight.Location = new System.Drawing.Point(87, 197); + this.buttonPutWeight.Name = "buttonPutWeight"; + this.buttonPutWeight.Size = new System.Drawing.Size(52, 21); + this.buttonPutWeight.TabIndex = 4; + this.buttonPutWeight.Text = "Put"; + this.buttonPutWeight.UseVisualStyleBackColor = true; + this.buttonPutWeight.Click += new System.EventHandler(this.buttonPutWeight_Click); + // + // listViewWeight + // + this.listViewWeight.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { + this.columnHeaderWeight, + this.columnHeaderWhen}); + this.listViewWeight.GridLines = true; + this.listViewWeight.Location = new System.Drawing.Point(13, 246); + this.listViewWeight.Name = "listViewWeight"; + this.listViewWeight.Size = new System.Drawing.Size(237, 104); + this.listViewWeight.TabIndex = 5; + this.listViewWeight.UseCompatibleStateImageBehavior = false; + this.listViewWeight.View = System.Windows.Forms.View.Details; + // + // columnHeaderWeight + // + this.columnHeaderWeight.Text = "Weight"; + // + // columnHeaderWhen + // + this.columnHeaderWhen.Text = "When"; + // + // buttonDeProvision + // + this.buttonDeProvision.Location = new System.Drawing.Point(106, 38); + this.buttonDeProvision.Name = "buttonDeProvision"; + this.buttonDeProvision.Size = new System.Drawing.Size(75, 23); + this.buttonDeProvision.TabIndex = 6; + this.buttonDeProvision.Text = "De-Provision"; + this.buttonDeProvision.UseVisualStyleBackColor = true; + this.buttonDeProvision.Click += new System.EventHandler(this.buttonDeProvision_Click); + // + // labelConnectionStatus + // + this.labelConnectionStatus.AutoSize = true; + this.labelConnectionStatus.Location = new System.Drawing.Point(15, 85); + this.labelConnectionStatus.Name = "labelConnectionStatus"; + this.labelConnectionStatus.Size = new System.Drawing.Size(112, 13); + this.labelConnectionStatus.TabIndex = 7; + this.labelConnectionStatus.Text = "Connection status text"; + // + // MainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(284, 383); + this.Controls.Add(this.labelConnectionStatus); + this.Controls.Add(this.buttonDeProvision); + this.Controls.Add(this.listViewWeight); + this.Controls.Add(this.buttonPutWeight); + this.Controls.Add(this.buttonGetWeight); + this.Controls.Add(this.WeightLabel); + this.Controls.Add(this.textBoxWeight); + this.Controls.Add(this.buttonProvision); + this.Name = "MainForm"; + this.Text = "HealthVault Client"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button buttonProvision; + private System.Windows.Forms.TextBox textBoxWeight; + private System.Windows.Forms.Label WeightLabel; + private System.Windows.Forms.Button buttonGetWeight; + private System.Windows.Forms.Button buttonPutWeight; + private System.Windows.Forms.ListView listViewWeight; + private System.Windows.Forms.ColumnHeader columnHeaderWeight; + private System.Windows.Forms.ColumnHeader columnHeaderWhen; + private System.Windows.Forms.Button buttonDeProvision; + private System.Windows.Forms.Label labelConnectionStatus; + } +} + diff --git a/dotNET/hvclientsample/MainForm.cs b/dotNET/hvclientsample/MainForm.cs new file mode 100644 index 0000000..13a541e --- /dev/null +++ b/dotNET/hvclientsample/MainForm.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; +using Microsoft.Health; +using ItemTypes = Microsoft.Health.ItemTypes ; + +namespace HVClientSample +{ + public partial class MainForm : Form + { + public MainForm() + { + InitializeComponent(); + + hvclient = new HVClient(); + UpdateProvisioningState(); + } + + private void buttonProvision_Click(object sender, EventArgs e) + { + hvclient.ProvisionApplication(); + UpdateProvisioningState(); + } + + private void buttonGetWeight_Click(object sender, EventArgs e) + { + listViewWeight.Items.Clear(); + + HealthRecordItemCollection items = hvclient.GetWeightFromHealthVault(); + if (items != null) + { + foreach (HealthRecordItem item in items) + { + ItemTypes.Weight weight = (ItemTypes.Weight)item; + ListViewItem lvi = new ListViewItem(weight.Value.Kilograms.ToString()); + lvi.SubItems.Add(weight.When.ToString()); + + listViewWeight.Items.Add(lvi); + } + } + + } + + private void buttonPutWeight_Click(object sender, EventArgs e) + { + listViewWeight.Items.Clear(); + hvclient.SetWeightOnHealthVault(Convert.ToDouble(textBoxWeight.Text)); + } + + private HVClient hvclient; + + private void buttonDeProvision_Click(object sender, EventArgs e) + { + hvclient.DeProvision(); + UpdateProvisioningState(); + } + + private void UpdateProvisioningState() + { + if (hvclient.IsProvisioned) + { + labelConnectionStatus.Text = string.Format( + "Provisioned in the {0} (ID={1}) instance.", + hvclient.ServiceInstance.Name, + hvclient.ServiceInstance.Id); + + buttonDeProvision.Enabled = true; + buttonProvision.Enabled = false; + } + else + { + labelConnectionStatus.Text = "Not provisioned."; + + buttonDeProvision.Enabled = false; + buttonProvision.Enabled = true; + } + } + } +} diff --git a/dotNET/hvclientsample/MainForm.resx b/dotNET/hvclientsample/MainForm.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/dotNET/hvclientsample/MainForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/dotNET/hvclientsample/Program.cs b/dotNET/hvclientsample/Program.cs new file mode 100644 index 0000000..5951cad --- /dev/null +++ b/dotNET/hvclientsample/Program.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// MIT License +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ""Software""), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace HVClientSample +{ + static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new MainForm()); + } + } +} diff --git a/dotNET/hvclientsample/Properties/AssemblyInfo.cs b/dotNET/hvclientsample/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..d8eef6a --- /dev/null +++ b/dotNET/hvclientsample/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("HVClientSample")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("HVClientSample")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2009")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f3498903-b1d1-47e3-9a7b-7bb879259942")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/dotNET/hvclientsample/Properties/Resources.Designer.cs b/dotNET/hvclientsample/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8edac20 --- /dev/null +++ b/dotNET/hvclientsample/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace HVClientSample.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HVClientSample.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/dotNET/hvclientsample/Properties/Resources.resx b/dotNET/hvclientsample/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/dotNET/hvclientsample/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/dotNET/hvclientsample/Properties/Settings.Designer.cs b/dotNET/hvclientsample/Properties/Settings.Designer.cs new file mode 100644 index 0000000..96d2f04 --- /dev/null +++ b/dotNET/hvclientsample/Properties/Settings.Designer.cs @@ -0,0 +1,86 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace HVClientSample.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("00000000-0000-0000-0000-000000000000")] + public global::System.Guid ApplicationId { + get { + return ((global::System.Guid)(this["ApplicationId"])); + } + set { + this["ApplicationId"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("00000000-0000-0000-0000-000000000000")] + public global::System.Guid PersonId { + get { + return ((global::System.Guid)(this["PersonId"])); + } + set { + this["PersonId"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("00000000-0000-0000-0000-000000000000")] + public global::System.Guid RecordGuid { + get { + return ((global::System.Guid)(this["RecordGuid"])); + } + set { + this["RecordGuid"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("1")] + public string ServiceInstanceId { + get { + return ((string)(this["ServiceInstanceId"])); + } + set { + this["ServiceInstanceId"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("False")] + public bool IsProvisioned { + get { + return ((bool)(this["IsProvisioned"])); + } + set { + this["IsProvisioned"] = value; + } + } + } +} diff --git a/dotNET/hvclientsample/Properties/Settings.settings b/dotNET/hvclientsample/Properties/Settings.settings new file mode 100644 index 0000000..6830925 --- /dev/null +++ b/dotNET/hvclientsample/Properties/Settings.settings @@ -0,0 +1,21 @@ + + + + + + 00000000-0000-0000-0000-000000000000 + + + 00000000-0000-0000-0000-000000000000 + + + 00000000-0000-0000-0000-000000000000 + + + 1 + + + False + + + diff --git a/dotNET/hvclientsample/Readme.md b/dotNET/hvclientsample/Readme.md new file mode 100644 index 0000000..ffa92e1 --- /dev/null +++ b/dotNET/hvclientsample/Readme.md @@ -0,0 +1,37 @@ +# HealthVault Client Application Sample + +This sample application demonstrates creating a client application that works +with HealthVault. + +It demonstrates the following functionality +- How to setup/provision an application using the SODA authentication pattern. +- How to make a connection to HealthVault and get/set data. + +## Details of the sample: + +### Files +**HVClient.cs**: This is of most interest as it contains the majority +of the code to setup the application and retrieve data. + +**MainForm.cs**: Code for the form that does user interface. This calls into +HVClient to do most of the application setup and retrieval. + +**Program.cs**: Default Visual Studio generated code to launch application + + +### HVClient +The public methods such as ProvisionApplication(), DeProvision(), GetWeightFromHealthVault() +and SetWeightOnHealthVault(). + +ProvisionApplication illustrates application setup steps. An application would +provision itself on first use or at setup time. Once the application is +provisioned, subsequent connections to HealthVault need only the creation +of SDK objects for HealthClientApplication and HealthClientAuthorizedConnection. + +DeProvision illustrates how an application can clean up if removed from the user's machine. +It deauthorizes the application from HealthVault. It also deletes the local +certificate that is used for making a client connection to HealthVault. + +GetWeightFromHealthVault() and SetWeightOnHealthVault(): These methods show how +a HealthClientAuthorizedConnection can be created and used for working with +items on HealthVault. \ No newline at end of file diff --git a/dotNET/hvclientsample/app.config b/dotNET/hvclientsample/app.config new file mode 100644 index 0000000..0ecea5a --- /dev/null +++ b/dotNET/hvclientsample/app.config @@ -0,0 +1,38 @@ + + + + +
+ + + + + + 00000000-0000-0000-0000-000000000000 + + + 00000000-0000-0000-0000-000000000000 + + + 00000000-0000-0000-0000-000000000000 + + + False + + + + 1 + + + + + + + + + + + diff --git a/dotNET/hvclientsample/packages.config b/dotNET/hvclientsample/packages.config new file mode 100644 index 0000000..7cc2f4f --- /dev/null +++ b/dotNET/hvclientsample/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file