Authors: Pau Herrero (Imperial College London) and Dan Brown (Oxford Brookes University)
The purpose of this document is to describe the setup procedure for the PEPPER Safety System API and details on the implementation.
Delivering insulin in type 1 diabetes is a challenging, and potentially risky, activity; hence the importance of including safety measures as part of any insulin dosing or recommender system. This documents presents an application program interface (API) implemented in Java for Android of a modular safety system which is part of an intelligent insulin dose recommender platform developed within the EU-funded PEPPER project.
The PEPPER Safety System comprises four modules: the first module consists of predictive glucose threshold crossing alerts and standard glucose threshold crossing alarms (Module 1). The second module is designed for insulin pump users and automatically suspends basal insulin delivery when predicted glucose levels are low (Module 2). A third module recommends an individualized carbohydrate to harmlessly return glucose to safe levels (Module 3). Finally, the fourth module, referred to as dynamic bolus insulin constraint, restricts the amount of insulin that can be safely recommended to the user (Module 4). Figure 1.1 shows a block diagram of the safety system and its corresponding inputs and outputs. Further details of these four modules are given in the following sections. Finally, in addition the functionalities provided by the aforementioned modules, the Safety System also provides information about the glucose rate of change, insulin-on-board, and carbohydrates-on-board.
The glucose alerts and alarms module consists of two predictive alerts using a glucose forecasting algorithm [1] to notify the user before reaching predefined high and low glucose thresholds. In addition, standard glucose alarms notify the user when thresholds measured by the continuous glucose monitor (CGM) are exceeded. Finally, if the user does not address a hypoglycaemia alarm before a predefined time interval, an SMS message containing the type of alarm (i.e. hypoglycemia or hyperglycemia) and the time it was triggered, is sent to a designated carer. The system keeps sending messages until the alarm is manually snoozed on the handheld unit. Details about the algorithms behind the predictive glucose alerts and alarms can be found in [2].
The predictive low glucose basal insulin suspension module aims at minimising the incidence and severity of hypoglycemia by suspending, or partially suspending, basal insulin delivery when predicted glucose levels are low. Basal insulin delivery is partially suspended if the forecasted glucose value falls below a predefined threshold (Threshold 1). Insulin delivery is fully suspended when glucose falls below a second predefined threshold (Threshold 2). Details about the algorithms behind the predictive low-glucose basal insulin suspend module can be found in [2].
If neither glucose alerts/alarms module nor the predictive low glucose basal insulin suspension module are enough to prevent hypoglycemia, the adaptive carbohydrate recommender module recommends a rescue dose of oral carbohydrates with the aim of reverting hypoglycaemia and minimizing rebound hyperglycemia. Details about the algorithms behind the carbohydrate recommender can be found in [2].
The Dynamic Bolus Insulin Constraint module aims to eliminate potentially dangerous insulin boluses being recommended to the user, which could induce severe hypo- or hyperglycaemia. This is done by computing a lower and upper bound determining the minimum and maximum allowed insulin recommendation. Details about the algorithms behind the dynamic insulin constraint module can be found in [2].
This chapter details the setup of the PEPPER Safety System library.
Setup of the library involves only importing the
PEPPERSafetySystem.jar
into the Android
project. In this section we provide two options: First,
manually edit the application's module build.gradle;
Second, using the Android Studio interface to import a
JAR as a dependency.
PEPPERSafetySystem.jar
in the
libs
folder of the project, or a direction
of your preference.
build.gradle
(example for the
libs
directory):
compile fileTree(include: [’*.jar’], dir: ’libs’)
For example:
dependencies { compile fileTree(include: [’*.jar’], dir: ’libs’)
// other dependencies omitted
}
PEPPERSafetySystem.jar
to the
application module’s build.gradle
(example for the libs
directory):
compile files(’libs/PEPPERSafetySystem.jar’)
For example:
dependencies { compile files(’libs/PEPPERSafetySystem.jar’)
// other dependencies omitted
}
build.gradle
has been sync’d,
the library should not be imported.
PEPPERSafetySystem.jar
in the
libs
folder of the project.
File > Project Structure
Modules
list
in the left side pane of the Project
Structure
interface.
Dependency
tab.
+
symbol) and select
File dependency
.
PEPPERSafetySystem.jar
and click OK
.
OK
to close the Project
Structure
window.
This chapter details the important details on how to use the PEPPER Safety System library.
Initialisation of the Safety System requires the creation
(Section 3.1.1) of the
SafetySystemObject
object and invoking the
initialisation method, as described in Section 3.1.3.
Section 3.1.4 presents a creation and initialisation template for developers to refer to.
SafetySystem
object
Creation of the SafetySystem
object must be
done using the static factory method:
SafetySystem safetySystem = SafetySystemFactory.getInstance(context);
The safety system adopts the singleton pattern to provide a global state accessible from the application without the need to maintain a reference. This design decision can be justified through the fact that there should only ever be one instance of the safety system operating at any one time.
Accessing and creating the SafetySystem object:
SafetySystem safetySystem = SafetySystemFactory.getInstance(context);
As some operations internal the Safety System require
accessing the current system time, it is important that
the SafetySystemTimeManager
's
SystemTimeInvoker
is set to mirror that it
is used by the rest of the application.
The SafetySystemTimeManager
only needs to be
invoked once prior to initialisation of the
SafetySystem
object. This will persist
throughout the life of the application.
SystemTimeInvoker
is a single method
interface which defines the following method:
Date getSystemTime()
By default the SystemTimeInvoker
returns
new Date()
.
To change this behaviour, a different
SystemTimeInvoker
can be created and set in
the Safety System's SafetySystemTimeManager
object.
For example:
/*
* Implement the SystemTimeInvoker interface.
*/
SystemTimeInvoker customTimeInvoker = new
SystemTimeInvoker() {
@Override
public
Date getSystemTime() {
return new
Date(Custom.getCustomSystemTime()); // change me as required
}
}
/*
* Set the SafetySystemTimeManager's SystemTimeInvoker to the custom implementation.
*/
SafetySystemTimeManager.getInstance().setSystemTimeInvoker(customTimeInvoker);
SafetySystem object
It is important that prior to performing any operations
on the Safety System that it has been initialised by
passing it the patient object JSON. If this is not the
case, the SafetySystem
object will throw an
IllegalSafetyStateException
for almost all
operations.
This initialisation process only needs to occur once, ideally when the application is launched.
Note:
As a fail-safe mechanism, the Safety System will store the last patient object JSON in an internal database. Should any interaction with the Safety System occur prior to the initialisation as documented in this section, the Safety System will automatically initialise itself using the most recent patient object stored in this database. This feature was included to allow the system to recover after a crash or system reboot without Internet connectivity.
As a result, if the safety system has been initialised at
some point, then an
IllegalSafetySystemStateException
should
never be raised.
Initialisation of the Safety System occurs by invoking the following method:
void SafetySystem.initSafetySystem(JSONObject patientObj)
This method requires a well-formed patient object JSON.
Explicitly of the type JSONObject
. If a
String
of the JSON is only available, then
the constructor of JSONObject
allows a JSON
String
to be passed for this purpose. If the
JSONObject
is not well-formed a
JSONException
will occur, this is a checked
Exception which must be handled. Additionally, if there
is an issue reading the IcrSafety
,
TimeIcrSafety
, IsfSafety
or
TimeIsfSafety
fields a
IllegalArgumentException
will be thrown,
this is unchecked.
Explicitly, the following attributes are expected in the patient object JSON:
Note: the term 'parsable' is used
below, meaning that the contained value must be parsable
as the expressed type even if the value itself is a
String
. For example, 'parsable
double
' means that the String
value "2.0"
is a valid value.
Id
- Patient Unique Identifier - a
String
GlucoseSetPoint
- Glucose setpoint - a
parsable double
FastingBloodGlucose
- Patint's blood
glucose concentration in fating state - a parsable
double
Weight
- Patient's body weight - a
parsable double
InsulinSensitivity
- Patient's insulin
sensitivity obtained through parameter identification.
Used within the glucose forecasting algorithm - a
parsable double
CarbohydrateAbsorptionTime
- Carbohydrate
peak absorption time obtained through parameter
identification. Used within the glucose forecasting
algorithm - a parsable double
InsulinAbsorptionTime
- Insulin peak
absorption time obtained through parameter
identification. Used within the glucose forecasting
algorithm - a parsable double
IcrSafety
- Insulin to Carbohydrate Ratios
(bolus calculator) - a String
of comma
separated double
values. The minimum
number of items is 1 otherwise an
IllegalArgumentException
will be thrown.
TimeIcrSafety
- Time the Insulin to
Carbohydrate Ratios change (bolus calculator) - a
String
of comma separated
double
values. This should contain the
same number of comma separated values as
IcrSafety
. The minimum number of items is
1 otherwise an IllegalArgumentException
will be thrown.
IsfSafety
- Insulin Sensitivity Factors
(bolus calculator) - a String
of comma
separated double
values. The minimum
number of items is 1 otherwise an
IllegalArgumentException
will be thrown.
TimeIsfSafety
- Time the Insulin
Sensitivity Factors change (bolus calculator) - a
String
of comma separated
double
values. This should contain the
same number of comma separated values as
IsfSafety
. The minimum number of items is
1 otherwise an IllegalArgumentException
will be thrown.
SafetySystemActive
- Flag to activate of
deactivate the Safety System - a parsable
int
value (1 → Active, 0 (or any other
value) → Inactive).
If the Safety System object has been initialised successfully the following method should return true:
boolean SafetySystem.isInitialised()
This section presents a complete template for creating
and initialisation of the SafetySystem
object.
import
android.support.v7.app.AppCompatActivity;
import
android.os.Bundle;
import
android.view.View;
import
com.eu.pepper.safetysystem.*;
public class
ExampleActivity extends
AppCompatActivity {
/**
* Class member field to store the safety system object.
*/
private
SafetySystem mSafetySystem;
@Override
public void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
/*
* Create/access the safety system object using the static factory method in the
* SafetySystemFactory class.
*
* Important: This does not initialise the safety system.
*
* The safety system operates as a singleton, so once created only one instance will
* ever exist and is accessible at any time using the static factory method:
* SafetySystemFactory.getInstance(Context)
*/
mSafetySystem = SafetySystemFactory.getInstance(getApplicationContext());
/*
* By default, the safety system gets the current system time by creating a
* new instance of Java Date. This can be changed by changing the SystemTimeInvoker
* used by the Safety System.
*
* Note: This will persist throughout the life of the application.
*
* Important: This should be done prior to initialisation of the Safety System.
*/
SystemTimeInvoker timeInvoker = new
SystemTimeInvoker() {
@Override
public
Date getSystemTime() {
return
new Date(Custom.getSystemTime()); // change me
}
};
SafetySystemTimeManager.getInstance().setSystemTimeInvoker(timeInvoker);
/*
* The safety system will not be initialised until the initSafetySystem method is invoked.
* Nearly all operations on the Safety System will throw an IllegalSafetySystemStateException
* if this initialisation is not completed or successful.
*
* To initialise the safety system, the Patient JSONObject must be passed to the
* initSafetySystem(JSONObject) method.
*/
JSONObject patientObj = Patient.getPatientObj(); // change me
try
{
mSafetySystem.initSafetySystem(patientObj);
} catch
(JSONException e) {
// The JSONObject is not well formed, likely a missing or misspelt field.
}
/*
* The safety system is now initialised and ready for use.
*/
}
}
This section documents how to interface with the PEPPER Safety System modules 1, 2, and 3.
Note: This process should be undertaken whenever a blood glucose reading is obtained from the CGM.
The following steps and checks should be performed on the
SafetySystem
object to successfully
integrate these features:
void
SafetySystem.update(Date, double)
, where the
Date
object is the system time of the
operation and the double
value is the blood
glucose reading from the CGM in mg/dL
SafetySystem.hasGlucoseAlert()
If there is a predictive Glucose Alert, notify the user.
The Glucose Alert can be retrieved using the method:
SafetyGlucoseAlert SafetySystem.getGlucoseAlert()
Refer to Section 3.2.1 for more information.
SafetySystem.hasGlucoseAlarm()
If there is a Glucose Alarm, notify the user.
The GlucoseAlarm can be retrieved using the method:
SafetyGlucoseAlarm SafetySystem.getGlucoseAlarm()
Refer to Section 3.2.1 for more information.
SafetySystem.hasCarerAlarm()
If there is a Carer Alarm, send the alarm to the web service.
The CarerAlarm can be retrieved using the method:
SafetyCarerAlarm SafetySystem.getCarerAlarm()
SafetyLowGlucoseSuspend SafetySystem.getLowGlucoseSuspend()
SafetyLowGlucoseSuspend.TOTAL_SUSPENSION
then suspend the pump.
SafetyLowGlucoseSuspend.PARTIAL_SUSPENSION
then partially suspend the pump.
SafetyLowGlucoseSuspend.NO_SUSPENSION
then restore / keep the pump in full operation.
SafetySystem.hasCarbRecommendation()
If there is a Carbohydrate Recommendation, notify the user.
The Carbohydrate Recommendation can be retrieved using the methods:
String
SafetySystem.getCarbRecommendationAsString()
- formatted String
double
SafetySystem.getCarbRecommendation()
- raw
double
Refer to Section 3.2.3 for more information.
When any of the following alarms or alerts occur the user should be represented with a notification describing the alert or alarm (all expressed as enumerate types):
Note: CarerAlarm
is
not listed, as this has no user interaction,
instead the CarerAlarm
is reported to the
web service.
For all SafetyGlucoseAlert
and
SafetyGlucoseAlert
the user should be
presented with a notification dialog with a single option
to snooze the alert and alarm.
All of the above are snoozed by invoking the same method:
void snoozeAlarm(Date date)
where the Date
is the system date and time
at the point the alarm or alert was snoozed.
The Safety System has an internal clock, which if a
glucose alarm is not snoozed is not resolved within a
certain time interval (currently 30 minutes) will trigger
a CarerAlarm
. Snoozing the alarm or alert
will reset the internal timer.
This section documents the interactions with the Safety System with regards to insulin pump suspension system.
The safety system supports the ability to override pump suspension, i.e. if the pump is currently suspended in some way (total or partial) the safety system can be told to not suspend for 60 minutes.
To override pump suspension the following method should
be invoked on the SafetySystem
object:
SafetySystem.resumePumpOverride()
There may be occasions when the user chooses to stop the insulin pump. In this event the safety system needs to be informed that such an event has occurred otherwise the internal models (notably insulin on board) will not reflect the current situation correctly.
To notify the safety system that a pump bolus has been
stopped early the following method should be invoked:
SafetySystem.recalculateInsulin(double
insulinAdministered)
where
insulinAdministered
is the actual insulin
administered by the pump prior to stopped.
Should the Safety System trigger a Carbohydrate Recommendation, the user should be presented with the recommendation as a notification.
The carbohydrate recommendation can be retrieved using the following methods:
String
SafetySystem.getCarbRecommendationAsString()
-
returns a formatted String
double SafetySystem.getCarbRecommendation()
- returns a double
value.
The notification dialog should offer the user two options:
SafetySystem.acceptCarbRecommendation(Date)
SafetySystem.declineCarbRecommendation(Date)
Note: This method call currently performs no operation, but this can be changed.
void
cgmUpdate(Date cgmReadingDateTime, double
cgmReadingBgValue) {
/*
* Get the safety object. This must have been initialised.
*/
SafetySystem safetySystem = SafetySystemFactory.getInstance(getApplicationContext());
/*
* Update the Safety System with the CGM reading.
*/
safetySystem.update(cgmReadingDateTime, cgmReadingBgValue);
/*
* Check for alerts / alarms / etc.
*/
/*
* Check if a glucose alert has been flagged by the safety system.
*/
if
(safetySystem.hasGlucoseAlert()) {
SafetyGlucoseAlert glucoseAlert = safetySystem.getGlucoseAlert();
/*
* Display notification to the user.
*/
}
/*
* Check if a glucose alarm has been flagged by the safety system.
*/
if
(safetySystem.hasGlucoseAlarm()) {
SafetyGlucoseAlarm glucoseAlarm = safetySystem.getGlucoseAlarm();
/*
* Display notification to the user.
*/
}
/*
* Check if a carer alarm has been flagged by the safety system.
*/
if
(safetySystem.hasCarerAlarm()) {
SafetyCarerAlarm carerAlarm = safetySystem.getCarerAlarm();
/*
* Send the carerAlarm to the web service.
*/
}
/*
* Get pump suspension state.
* Note: Pump Only
*/
SafetyLowGlucoseSuspend pumpSuspendState = safetySystem.getLowGlucoseSuspend();
/*
* Handle the pump suspension state.
*/
switch
(pumpSuspendState) {
case
TOTAL_SUSPENSION:
/*
* Stop the pump.
* call SafetySystem.resumePumpOverride() to resume pump
*/
break
;
case
PARTIAL_SUSPENSION:
/*
* Partially suspend the pump.
*/
break
;
case
NO_SUSPENSION:
/*
* Do nothing / resume the pump if it was previously suspended.
*/
}
/*
* Check if a carbohydrate recommendation has been flagged by the safety system.
*/
if
(safetySystem.hasCarbRecommendation()) {
String carbRecommendaton = safetySystem.getCarbRecommendationAsString();
/*
* Display the carbohydate recommendation to user with the option to accept/decline.
*/
}
}
This section documents the workflow of the Safety System in conjunction with an insulin recommender system.
The Safety System requires two operations to be perform when a insulin recommendation is obtained:
The full procedure is as follows:
double SafetySystem.constrainBolus(JSONObject)
method. This method manipulates the PEPPER case object
JSON to store the constrained bolus (attribute:
bolussafety
), and also returns the
constrained bolus recommendation.
If the user accepts the recommendation:
bolususer
is populated
with the same value as bolussafety
.
void SafetySystem.addRecommendation(JSONObject)
This will update the state of the safety system.
If the user rejects the recommendation:
bolususer
is populated
with the user's actual bolus input.
void SafetySystem.addRecommendation(JSONObject)
This will update the state of the safety system.
If the user cancels the recommendation:
For item one, constrain the recommend bolus dose, the system must pass the populated PEPPER case object (JSON) to the safety system after a recommendation has been produced.
Note: This must occur before the dose is displayed to the user.
To constrain an insulin bolus recommendation the
following method should be invoked on the
SafetySystem
object:
double SafetySystem.constrainBolus(JSONObject caseJson)
Invoking this method will internally update the PEPPER
case object (JSON), setting the attribute
bolussafety
to the constrained bolus dose.
This value is limited to 4 decimal point precision.
The contrainBolus
method is reliant upon the
following attributes being present and correct in the
PEPPER case (JSON object):
premealbloodglucose
- glucose
concentration at meal time - as a parsable double
datetime
- timestamp at meal time - in the
format yyyy-MM-dd HH:mm:ss
carbohydrates
- estimation of ingested
carbohydrates - as a parsable double
userpastphysicalactivityintensity
-
estimation of past physical activity - as a parsable
String, values: low
, mild
,
intense
(not currently used)
bolusreuse
- insulin proposed by the
recommender - as a parsable double
bolussafety
- insulin constrained by the
Safety System - as an available attribute (parsable
double)
If a insulin recommendation is accepted or rejected by the user, the PEPPER case object (JSON) should be committed to the Safety System to ensure its state is updated.
Prior to committing the PEPPER case object (JSON) to the Safety System, the PEPPER case object (JSON) must be updated as follows:
If the insulin recommendation is accepted:
Update the PEPPER case object (JSON) so that the
attribute bolususer
is set to the same value
as bolussafety
.
For example:
void updateBolusUserWithBolusSafety(JSONObject pepperCase){
JSONObject attributesJSON = pepperCase.getJSONObject("attributes");
String bolusSafety = attributesJSON.getString("bolussafety");
attributesJSON.put("bolususer", bolusSafety);
}
If the insulin recommendation is rejected:
Update the PEPPER case object (JSON) so that the
attribute bolususer
is set to bolus dose
administered, as input by the user from the graphical
user interface.
For example:
void updateBolusUser(JSONObject pepperCase, String userBolusInput){
JSONObject attributesJSON = pepperCase.getJSONObject("attributes");
attributesJSON.put("bolususer", userBolusInput);
If the insulin recommendation is cancelled:
Do nothing with the safety system.
Note:
For consistency with the rest of the system, it may be valid to add manual carbohydrates to the Safety System in case of cancellation. Refer to Section 3.4.
After recommendation is obtained:
void
constrainCbrRecommendation(JSONObject pepperCase) {
/*
* Get the safety object. This must have been initialised.
*/
SafetySystem safetySystem = PEPPERSafetyFactory.getInstance(getApplicationContext());
try
{
/*
* Constrain the bolus recommendation:
*/
double
constrainedBolus = safetySystem.constrainBolus(pepperCase);
/*
* Display the constrained bolus recommendation to the user.
*/
} catch
(JSONException e) {
/*
* The PEPPER case JSON is malformed.
*/
}
}
Handle user accept/reject/cancel response
/*
* If the insulin recommendation is accepted.
*/
void
acceptCbrRecommendation(JSONObject pepperCase) {
/*
* The user accepted the recommendation, so update "bolususer" to the "bolussafety" value.
*/
String bolusSafety = pepperCase.getJSONObject("attributes").getString("bolussafety");
updateBolusUser(pepperCase, caseAttributes.get("bolussafety")); // see below
/*
* Commit the recommendation to the Safety System to update its state.
*/
SafetySystemFactory.getInstance(getApplicationContext()).addRecommendation(pepperCase);
}
/*
* If the insulin recommendation is rejected.
*/
void
rejectCbrRecommendation(JSONObject pepperCase, String userBolus) {
/*
* The user rejects the recommendation, so update "bolususer" to the users input.
*/
String bolusSafety = pepperCase.getJSONObject("attributes").getString("bolussafety");
updateBolusUser(pepperCase, caseAttributes.get("bolussafety")); // see below
/*
* Commit the recommendation to the safety system to update its state.
*/
SafetySystemFactory.getInstance(getApplicationContext()).addRecommendation(pepperCase);
}
/*
* If the insulin recommendation is cancelled.
*/
void
cancelCbrRecommendation() {
/*
* Do nothing to the Safety System or add the carbohydrates manually
* using SafetySystem.addCarbs(Date dateTime, double carbs)
*/
}
/*
* Update the "bolususer" attribute of the PEPPER case (JSON object)
*/
void
updateBolusUser(JSONObject pepperCase, String userBolus) {
try
{
/*
* Update the bolus user attribute in the PEPPER case (JSON object)
*/
pepperCase.getJSONObject("attributes").put("bolususer", userBolus);
} catch
(JSONException e) {
/*
* The PEPPER case JSON is malformed.
*/
}
}
/*
* Commit the insulin recommendation to the Safety System if it is accepted or rejected.
*/
void
commitCbrRecommendationToSafetySystem(JSONObject pepperCase) {
/*
* Commit the insulin recommendation to the Safety System to update its state.
*/
SafetySystemFactory.getInstance(getApplicationContext()).addRecommendation(pepperCase);
}
This section documents the interactions with the Safety System that should occur when a manual carbohydrates input occurs.
The operation requires invocation of the method:
void SafetySystem.addCarbs(Date date, double carbs)
with the date and time of the manual carbohydrates input
as a Java Date
object and the carbohydrates
input as a double
value.
Manual carbohydrates template
void
manualCarbs(Date carbInputDate, double
carbs) {
/*
* Get the Safety System object. Note: this must be initialised.
*/
SafetySystem safetySystem = SafetySystemFactory.getInstance(getApplicationContext());
/*
* Invoke the addCarbs(Date, double) method.
*/
safetySystem.addCarbs(carbInputDate, carbs);
}
This section documents the interactions with the Safety System that should occur when a manual insulin input occurs.
The operation requires invocation of the method:
void SafetySystem.addInsulin(Date date, double insulin)
with the date and time of the manual insulin input as a
Java Date
object and the insulin input as a
double
value.
Manual insulin template
void
manualInsulin(Date insulinInputDate, double
insulin) {
/*
* Get the Safety System object. Note: this must be initialised.
*/
SafetySystem safetySystem = SafetySystemFactory.getInstance(getApplicationContext());
/*
* Invoke the addInsulin(Date, double) method.
*/
safetySystem.addInsulin(insulinInputDate, insulin);
}
This section documents how to access information calculated by the Safety System which can be displayed to the user on the graphical user interface. This information is: Carbohydrates on Board, Insulin on Board, and the Blood Glucose Trend.
The most recent carbohydrates on board calculation can be obtained from the Safety System by invoking the following methods:
To return the raw double
carbohydrates on
board value:
double SafetySystem.getCarbsOnBoard()
To return a formatted carbohydrates on board value as a
String
:
String SafetySystem.getCarbsOnBoardAsString()
Note:
The SafetySystem
must be correctly
initialised otherwise an
IllegalSafetySystemStateException
will be
thrown by these methods.
The most recent insulin on board calculation can be obtained from the Safety System by invoking the following methods:
To return the raw double
insulin on board
value:
double SafetySystem.getInsulinOnBoard()
To return a formatted insulin on board value as a
String
:
String SafetySystem.getInsulinOnBoardAsString()
Note:
The SafetySystem
must be correctly
initialised otherwise an
IllegalSafetySystemStateException
will be
thrown by these methods.
The most recent blood glucose trend (rate of change) calculation can be obtained from the Safety System by invoking the following method:
SafetyGlucoseTrend SafetySystem.getGlucoseTrend()
SafetyGlucoseTrend
is an enumerate type
which is used to indicate the glucose trend arrow to be
presented to the graphical user interface. The enumerate
type to graphical arrow representation is shown in Table
3.1.
Note:
The SafetySystem
must be correctly
initialised otherwise an
IllegalSafetySystemStateException
will be
thrown by this method.
Enumerate constant | Trend arrow |
---|---|
STEADY | → |
SLOW_RISE | ↗ |
RISE | ↑ |
RAPID_RISE | ↑↑ |
SLOW_FALL | ↘ |
FALL | ↓ |
RAPID_FALL | ↓↓ |
The Safety System uses a SQLite database to locally store data in the event of a system crash. However, the Safety Object should be exported and sent to the web services (e.g. every 24 hours).
A JSONObject
for exporting can be created by
invoking the following method:
JSONObject SafetySystem.createJsonExport()
Note:
The SafetySystem
must be correctly
initialised otherwise an
IllegalSafetySystemStateException
will be
thrown by these methods.
The JSON format for this object is given bellow:
{
"PatientId":"", // Unique patient identifier
"DateTime":"", // Date and time the safety object was exported, format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"CGM": // CGM and regularly updated information
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Measurement":"[]", // comma separated list of CGM sample
"Derivative":"[]", // comma separated list of glucose derivative (tred or rate of change) values
"Forecasted":"[]", // comma separated list of forecasted glucose values
"IOB":"[]", // comma separated list of insulin on board values
"COB":"[]" // comma separated list of carbs on board values
},
"GlucoseAlerts": // Glucose alerts (MODULE 1)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Type":"[]", // comma separated list of categorical values (None/Hypoglycaemia/Hyperglycaemia)
"Snooze":"" // comma separated list of categorical values of true/false || VALUES CURRENTLY NOT RECORDED
},
"GlucoseAlarms": // Glucose alarms (MODULE 1)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Type":"[]", // comma separated list of categorical values None/Hypoglycaemia/Hyperglycaemia)
"Snooze":"" // comma separated list of true / false || VALUES CURRENTLY NOT RECORDED
},
"AlarmCarers": // Carer alarms (MODULE 1)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Type":"[]" // comma separated list of type categorical values (hypo,hyper,fault)
}
"SafetyLowGlucoseSuspend": // Low glucose suspension (MODULE 2)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Suspension":"[]", // comma separated list of categorical values 0=non-suspended; 1=partial suspension; 2=total suspension
"Cancel":"" // comma separated list of true / false || VALUES CURRENTLY NOT RECORDED
},
"CarbRecommender": // Recommended CHO rescue doses (MODULE 3)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Dose":"[]", // comma separated list of CHO recommendation dose values
"Time_Accept":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Accept":"[]" // comma separated list of true / false
},
"Constraint": // Bolus constraints (MODULE 4)
{
"Time":"[]", // comma separated list of date values format example: Thu Jun 22 08:53:04 GMT+00:00 2017
"Bolus":"[]" // comma separated list of constrained bolus values
},
This section documents the enumerate types contained within the PEPPERSafetySystem library. The purpose of these enumerate types is to provide meaningful name to values representing as integers within the Safety System JSON object.
Enumerate SafetyGlucoseAlarm
used for safety
system glucose alerts. A SafetyGlucoseAlert
has a lower threshold than
SafetyGlucoseAlarm
.
Enumerate constant | JSON value | Description |
---|---|---|
NO_ALERT | 0 | No alert |
HYPO_ALERT | 1 | Hypo alert |
HYPER_ALERT | 2 | Hyper alert |
Related methods:
SafetyGlucoseAlert
SafetySystem.getGlucoseAlert()
boolean SafetySystem.hasGlucoseAlert()
Enumerate SafetyGlucoseAlarm
used for safety
system glucose alarms. A SafetyGlucoseAlarm
should take precedence over a
SafetyGlucoseAlert
(Sec. 4.1), however neither should occur
simultaneously.
Enumerate constant | JSON value | Description |
---|---|---|
NO_ALARM | 0 | No alarm |
HYPO_ALARM | 1 | Hypo alarm |
HYPER_ALARM | 2 | Hyper alarm |
Related methods:
SafetyGlucoseAlarm
SafetySystem.getGlucoseAlarm()
boolean SafetySystem.hasGlucoseAlarm()
Enumerate SafetyCarerAlarm
used for Safety
System carer alarms.
Enumerate constant | JSON value | Description |
---|---|---|
NO_ALARM | 0 | No alarm |
HYPO_ALARM | 1 | Hypo alarm |
HYPER_ALARM | 2 | Hyper alarm |
FAULT_ALARM | 3 | Fault alarm |
Related methods:
SafetyCarerAlarm
SafetySystem.getCarerAlarm()
boolean SafetySystem.hasCarerAlarm()
Enumerate SafetyLowGlucoseSuspend
is used to
determine pump suspension state.
This is only required in the pump version.
Enumerate constant | JSON value | Description |
---|---|---|
NO_SUSPENSION | 0 | No suspension, operate as normal |
PARTIAL_SUSPENSION | 1 | Partial pump suspension |
TOTAL_SUSPENSION | 2 | Stop the pump |
CANCEL_SUSPENSION | 3 | Indicates the pump has been stopped |
RESUME_PUMP | 4 | Indicates the pump has been resumed |
Note: The two enumerates CANCEL_SUSPENSION and RESUME_PUMP are only ever found in the safety system's exported JSON for analysis and should not be used otherwise.
Related methods:
SafetyLowGlucoseSuspend
SafetySystem.getLowGlucoseSuspend()
Enumerate SafetyExercise
used for Safety
System exercise states. Currently the public interface
does not require use of this enumerate and is purely used
internally at present.
Enumerate constant | JSON value | Description |
---|---|---|
NO_EXERCISE | 0 | No excercises |
EXERCISE | 1 | Moderate exercise |
Related methods: n/a
Enumerate SafetyGlucoseTrend
used to
determine the glucose rate of change for displaying a
corresponding arrow to the user via the graphical user
interface.
Internally the glucose trend is not used, this is purely a public exposure resulting from the glucose derivative.
Enumerate constant | JSON value | Description | Trend arrow |
---|---|---|---|
STEADY | n/a | Steady glucose level | → |
SLOW_RISE | n/a | Slow glucose level increase | ↗ |
RISE | n/a | Moderatie glucose level increase | ↑ |
RAPID_RISE | n/a | Rapid glucose level increase | ↑↑ |
SLOW_FALL | n/a | Slow glucose level decrease | ↘ |
FALL | n/a | Moderate glucose level decrease | ↓ |
RAPID_FALL | n/a | Rapid glucose level decrease | ↓↓ |
Related methods:
SafetyGlucoseTrend
SafetySystem.getGlucoseTrend()
Enumerate SafetyMealType
used for Safety
System meal type states. Currently the public interface
does not require use of this enumerate and is purely used
internally at present.
Enumerate constant | JSON value | Description |
---|---|---|
AVERAGE | 0 | Average (default) meal type |
FAST | 1 | Fast absorption meal type |
MEDIUM | 2 | Medium absorption meal type |
SLOW | 3 | Slow absorption meal type |
NO_MEAL | n/a | No meal type, should not be used |
Related methods: n/a
For all other functionality, the reader should refer to the Javadoc.
The Javadoc for public methods and fields can be found
here:
http://sots.brookes.ac.uk/~p0044538/SafetySystem/javadoc/
Some other notable methods include:
double SafetySystem.getCurrentICR()
returns the ICR for the current time (hour) as used by the Safety System.
double SafetySystem.getCurrentISF()
returns the ISF for the current time (hour) as used by the Safety System.