About Connected Health

Connected health is a new model for health management that leverages technology to deliver care outside of traditional health care settings. While the demands on health and social care services are increasing, notably because of a growing and ageing population, cost of medical treatments are rising whereas health and social budgets are more and more constrained.

Technology can provide interesting and cost-effective solutions to the aforementioned concerns, by:

  • Improving the education of patients who have easy access to quality information, which helps in offloading health professionals,
  • Enabling remote and near real-time monitoring and processing of patient generated data (PGD), allowing for earlier detection of problems, better control of treatments and therefore reducing the need to move patients to expensive settings such as clinical laboratories or hospitals,
  • Aggregating and sharing data and information among healthcare professionals, increasing its quality and the quality of derived analytics, and consequently, knowledge and decision making,
  • Improving the collaboration and workflow among the different stakeholders (patients, healthcare professionals, hospitals, etc.)

Despite some obstacles that yet need to be overcome (shared medical records, privacy, implementation of smart applications, etc.) the progress of Connected Health is facilitated by the proliferation of mobile devices in the population, and the increasing number of wearable devices that track biological data such as blood pressure, oximetry, spent calories, etc.

About Withings

Withings is a company that designs smart wearable devices such as activity trackers with bio-sensors, smart scales and sleep monitors. It is actively involved in the Connected Health endeavor and has notably founded the Health institute that conducts surveys and scientific studies to “accelerate the connected health revolution”.

Have a hand in the connected health market share with scriptr.io

BCC research predicts that the market will reach $21.5 billions in 2018, with a five years (2013-2018) compound annual growth rate of 54.9%, making it one of the most attractive sectors of the IoT. In line with what we wrote in our July post related to our fibit connector, we believe that connected health apps will heavily require back-end capabilities such as integration, orchestration, persistence and messaging, which are provided to you by scriptr.io.

If connected health makes sense to you – as it does to us – then you will probably think of – or already are – using Withings devices to implement your app. You now can also leverage our Withings connector, that wraps all Withings APIs and expose them – with some additional features – as methods of JavaScript objects that you can seamlessly add to your own scriptr.io scripts.

A sample connected health application


In order to illustrate how to use the scriptr.io connector for Withings to implement connected health applications, we will implement a simple app that exposes the following features:

  • Subscribe to notifications sent by Withings whenever the end user synchronizes his devices with his Withings account
  • Upon notification, check the user’s latest blood pressure data. If the blood pressure is high, try to determine a possible cause (overweight, lack of sleep)
  • Send an email to the end user to inform him about the high blood pressure measures and possible causes

Get the complete source code of the sample application

Components of the application

Our application will be composed of the following elements:

  • The subscriptionManager script that is used to subscribe to, or unsubscribe from Withings notifications
  • The healtMonitor script that is the callback invoked by Withings for Blood Pressure notifications, which implements the last two features of our application
  • In addition to the aforementioned scripts, note that you need to checkout the Withings connector from Github into your scriptr.io Workspace.

Let us now start with the implementation of the subscriptionManager

subscribtionManager

This script is called by front-end clients in order to subscribe a user to or unsubscribe him from the Blood Pressure notification sent by Withings. Clients should invoke this script passing the “action” (subscribe/unsubscribe) and “userid” (the user’s Withings id) parameters.

First, let us require the withings/user module of our connector, since it is the one we mainly use to interact with Withings’ APIs. We also require the withings/common module of the connector that contains some useful constants.

var userClient = require("modules/withings/user.js");
var common = require("modules/withings/common.js");

Now let us retrieve the “action” and “userid” from the request that triggered our script using the native “request” object:

var action = request.parameters.action;
var userid = request.parameters.userid;

In order to interact with Withings, we now need to create an instance of the “User” class (from the “user” module) using the userid, then ask for an instance of “NotificationManager” in order to handle subscriptions:

var user = new userClient.User({userid:userid});
var notificationManager = user.getNotificationManager();

Last step is to test the value of the “action” variable in order to invoke the adequate method of the “NotificationManager” (“instancesubsribeToNotification” respectively “deleteSubscription”), specifying the notification type.

if (action == "subscribe") {
  return notificationManager.subscribeToNotification({notificationType: common.notificationTypes.HEART_AND_BP});
}
  
if (action == "unsubscribe") {
  return notificationManager.deleteSubscription({notificationType: common.notificationTypes.HEART_AND_BP});
}

// return an error if   
return {
  "errorCode": "Invalid_Action"
}

That’s all. We now can subscribe to / unsubscribe from Withings notifications.

healthMonitor

The “healthMonitor” script contains the main logic of our app, as described earlier. It is the callback that is invoked by Withings upon notification. Note that a notification is sent by Withings to the callback whenever the user’s device is synchronized with his Withings account. It is up to the callback to retrieve updated data from Withings’ APIs, using the “startdate”, “enddate” and “userid” parameters sent by Withings.

First things first, we require the “user” module:

var userModule = require("modules/withings/user.js");

Now, we retrieve the “startdate”, “enddate” and “userid” parameters using the native “request” object:

var startDate = new Date(request.parameters.startdate);
var endDate = new Date(request.parameters.enddate);
var userId = request.parameters.userid;

Using the above values, we create an instance of User then ask for the latest Blood Pressure values for that user:

var user = new userModule.User({userid:userId});
var timePeriod = {from:startDate, to: endDate};
var systolicBP = user.listSystolicBloodPressureMeasures(timePeriod); // this is a list of values
var diastolicBP = user.listDiastolicBloodPressureMeasures(timePeriod); // this is a list of values
var lastDiasotlicBP = diastolicBP.measuregrps[0].measures[0].realValue; // we just consider the latest diastolic measure
var lastSystolicBP = systolicBP.measuregrps[0].measures[0].realValue; // we just consider the latest systolic measure

High blood pressure can result from different causes such as: overweight – and notably important fat mass – or lack of sleep. We will now implement two different functions, one that gets the fat mass ratio in the user’s body and the other that checks how well he slept for the past 7 days:

function hasFatMassRatioAboveThreshold(user, endDate) {
  
  // Get the last measure of the fat ratio
  var fatRatioMeasures = user.listFatRatioMeasures({to:endDate});
  var lastFatRatioMeasure = fatRatioMeasures.measuregrps[0].measures[0].realValue;
  
  // to simplify we consider that fat ratio is the same for men and women
  return lastFatRatioMeasure >= 0.27;
}

function isNotSleepingWell(user, endDate) {
  
  var startDate = getDate(7); // this is a utility function. you can find it in the app's source code.
  var sleepMeasures = user.getAverageSleepSummaryMeasures({from:startDate, to:endDate});
  return avgDeepsleepduration <  avgLightsleepduration + avgRemsleepduration;
}

Since fat mass can result from lack of activity, we also implement a function that checks the user's activity for the past seven days. This helps us in better identifying the reason behind the high blood pressure.

function hasLowPhysicalActivity(user, endDate) {
  
  var startDate = JSON.stringify(getDate(7)); // we need to transform the date into a "yyyy-mm-dd" string
  startDate = startDate.substring(1, startDate.indexOf("T"));
  var lEndDate =  JSON.stringify(endDate); // we need to transform the date into a "yyyy-mm-dd" string
  lEndDate = lEndDate.substring(1, lEndDate.indexOf("T"));
  var averageActivityMeasures = user.getAverageActivityMeasures({from:startDate, to:lEndDate}); 
  var moderateEffortDuration = averageActivityMeasures.avgModerateActivityDuration; // in seconds
  var intenseEffortDuration = averageActivityMeasures.avgIntenseActivityDuration; // in seconds
  
  // we consider that 75min/week of intense effort or 150min/week of moderate effort are required
  return Math.round(moderateEffortDuration / 60) < 150 && Math.round(intenseEffortDuration / 60) < 75;
}

Our next step is to implement a function that sends an email to the end user, in order to keep him informed. We use the native "sendMail" function for that:

function sendMessage(message) {
  
  var emailConfig = {
    
  	"to": "someuser@mail.com", // replace with some email
  	"fromName": "Your health monitor",
  	"subject": "High Blood Pressure notification",
  	"bodyHtml": message
  };
  
  return sendMail(emailConfig.to, emailConfig.fromName, emailConfig.subject, emailConfig.bodyHtml);   	
}

Let us orchestrate all of the above in a main function that tries to determine the reason behind the high blood pressure:

function determineHighBloodPressurePossibleCause(user, params) {
  
  var message = "Your blood pressure is high (" + params.systolic + "/" + params.diastolic + "). Possible reason is: ";
  var importantFatMass = hasFatMassRatioAboveThreshold(user, params.to);

  // reason might be extra-weight and important fat mass
  if (importantFatMass) {
    
    message += "Your fat mass ratio is above threshold. ";
    
    // verify if the end user is working-out or not
    if (hasLowPhysicalActivity(user, params.to)) {
      message += "Consider having more intense physical activities."
    }else {
      message += "Consider starting a diet.";
    }
    
    return sendMessage(message);
  }
  
  // reason might be lack of good sleep
  if (isNotSleepingWell(user, endDate)) {
    
    message += "You have a low quality of sleep. ";
    
     // verify if the end user is working-out or not
    if (hasLowPhysicalActivity(user, params.to)) {
      message = "Consider having more physical activities."
    }else {
      message += "Try to relax.";
    }
    
    return sendMessage(message);
  }
  
  message += "unknow. Consider contacting a healthcare professional";
  return sendMessage(message);
}

We now only have to update our script in order to invoke the above functions:

if (lastSystolicBP >= 140 && lastDiasotlicBP >= 90) {
  var params = {systolic:lastSystolicBP, diastolic: lastDiasotlicBP, to:  timePeriod.to, from: timePeriod.from};
  return determineHighBloodPressurePossibleCause(user, params);  	
}

Last but not least, we need to instruct the connector to use the "healthMonitor" script as a callback
for heart and blood pressure notifications. This is simply done by modifying the
/withings/common file of the connector as follows:

handlers[notificationTypes.HEART_AND_BP] = "your_path/healthMonitor"; // replace the initial value with this one

Get the complete source code of the sample application
Get the Withings connector