diff --git a/lib/client/careportal.js b/lib/client/careportal.js index a5c86232d8e..c4b661e8e6e 100644 --- a/lib/client/careportal.js +++ b/lib/client/careportal.js @@ -52,7 +52,7 @@ function init (client, $) { submitHooks = {}; _.forEach(careportal.allEventTypes, function each (event) { - inputMatrix[event.val] = _.pick(event, ['bg', 'insulin', 'carbs', 'protein', 'fat', 'prebolus', 'duration', 'percent', 'absolute', 'profile', 'split', 'reasons', 'targets']); + inputMatrix[event.val] = _.pick(event, ['otp','remoteCarbs', 'remoteAbsorption', 'remoteBolus', 'bg', 'insulin', 'carbs', 'protein', 'fat', 'prebolus', 'duration', 'percent', 'absolute', 'profile', 'split', 'reasons', 'targets']); submitHooks[event.val] = event.submitHook; }); } @@ -80,11 +80,18 @@ function init (client, $) { $('#reasonLabel').css('display', displayType(reasons && reasons.length > 0)); $('#targets').css('display', displayType(inputMatrix[eventType]['targets'])); + $('#otpLabel').css('display', displayType(inputMatrix[eventType]['otp'])); + $('#remoteCarbsLabel').css('display', displayType(inputMatrix[eventType]['remoteCarbs'])); + $('#remoteAbsorptionLabel').css('display', displayType(inputMatrix[eventType]['remoteAbsorption'])); + $('#remoteBolusLabel').css('display', displayType(inputMatrix[eventType]['remoteBolus'])); + $('#bg').css('display', displayType(inputMatrix[eventType]['bg'])); $('#insulinGivenLabel').css('display', displayType(inputMatrix[eventType]['insulin'])); + $('#carbsGivenLabel').css('display', displayType(inputMatrix[eventType]['carbs'])); $('#proteinGivenLabel').css('display', displayType(inputMatrix[eventType]['protein'])); $('#fatGivenLabel').css('display', displayType(inputMatrix[eventType]['fat'])); + $('#durationLabel').css('display', displayType(inputMatrix[eventType]['duration'])); $('#percentLabel').css('display', displayType(inputMatrix[eventType]['percent'] && $('#absolute').val() === '')); $('#absoluteLabel').css('display', displayType(inputMatrix[eventType]['absolute'] && $('#percent').val() === '')); @@ -99,6 +106,11 @@ function init (client, $) { careportal.reasonable(); + resetIfHidden(inputMatrix[eventType]['otp'], '#otp'); + resetIfHidden(inputMatrix[eventType]['remoteCarbs'], '#remoteCarbs'); + resetIfHidden(inputMatrix[eventType]['remoteAbsorption'], '#remoteAbsorption'); + resetIfHidden(inputMatrix[eventType]['remoteBolus'], '#remoteBolus'); + resetIfHidden(inputMatrix[eventType]['insulin'], '#insulinGiven'); resetIfHidden(inputMatrix[eventType]['carbs'], '#carbsGiven'); resetIfHidden(inputMatrix[eventType]['protein'], '#proteinGiven'); @@ -192,6 +204,12 @@ function init (client, $) { $('#eventType').val(''); $('#glucoseValue').val('').attr('placeholder', translate('Value in') + ' ' + client.settings.units); $('#meter').prop('checked', true); + + $('#otp').val(''); + $('#remoteCarbs').val(''); + $('#remoteAbsorption').val(''); + $('#remoteBolus').val(''); + $('#carbsGiven').val(''); $('#proteinGiven').val(''); $('#fatGiven').val(''); @@ -214,6 +232,10 @@ function init (client, $) { var data = { enteredBy: $('#enteredBy').val() , eventType: eventType + , otp: $('#otp').val() + , remoteCarbs: $('#remoteCarbs').val() + , remoteAbsorption: $('#remoteAbsorption').val() + , remoteBolus: $('#remoteBolus').val() , glucose: $('#glucoseValue').val().replace(',', '.') , reason: selectedReason , targetTop: $('#targetTop').val().replace(',', '.') @@ -327,6 +349,8 @@ function init (client, $) { } } + // TODO: add check for remote (Bolus, Carbs, Absorption) + return { allOk , messages @@ -350,6 +374,11 @@ function init (client, $) { text[text.length - 1] += ' ' + translate('Cancel'); } + pushIf(data.remoteCarbs, translate('Remote Carbs') + ': ' + data.remoteCarbs); + pushIf(data.remoteAbsorption, translate('Remote Absorption') + ': ' + data.remoteAbsorption); + pushIf(data.remoteBolus, translate('Remote Bolus') + ': ' + data.remoteBolus); + pushIf(data.otp, translate('One Time Pascode') + ': ' + data.otp); + pushIf(data.glucose, translate('Blood Glucose') + ': ' + data.glucose); pushIf(data.glucose, translate('Measurement Method') + ': ' + translate(data.glucoseType)); diff --git a/lib/plugins/loop.js b/lib/plugins/loop.js index 9b099dd188c..46d16738787 100644 --- a/lib/plugins/loop.js +++ b/lib/plugins/loop.js @@ -214,6 +214,8 @@ function init (ctx) { }); } + // TODO: add OTP entry + return [ { val: 'Temporary Override' @@ -229,6 +231,7 @@ function init (ctx) { , split: false , targets: false , reasons: reasonconf + , otp: true , submitHook: postLoopNotification }, { @@ -245,10 +248,28 @@ function init (ctx) { , split: false , targets: false , submitHook: postLoopNotification + }, + { + val: 'Remote Carbs Entry' + , name: 'Remote Carbs Entry' + , remoteCarbs: true + , remoteAbsorption: true + , otp: true + , submitHook: postLoopNotification + }, + { + val: 'Remote Bolus Entry' + , name: 'Remote Bolus Entry' + , remoteBolus: true + , otp: true + , submitHook: postLoopNotification } ]; }; + // TODO: Add event listener to customize labels + + loop.updateVisualisation = function updateVisualisation (sbx) { var prop = sbx.properties.loop; diff --git a/lib/server/loop.js b/lib/server/loop.js index a5e3aec5d8e..ca87892bba6 100644 --- a/lib/server/loop.js +++ b/lib/server/loop.js @@ -1,4 +1,4 @@ -'use strict'; +//'use strict'; const apn = require('apn'); @@ -9,6 +9,10 @@ function init (env, ctx) { } loop.sendNotification = function sendNotification (data, remoteAddress, completion) { + + // console.info("JAP"); + // console.info(data); + if (env.extendedSettings.loop.apnsKey === undefined || env.extendedSettings.loop.apnsKey.length == 0) { completion("Loop notification failed: LOOP_APNS_KEY not set."); return; @@ -63,7 +67,38 @@ function init (env, ctx) { alert = "Cancel Temporary Override"; } else if (data.eventType === 'Temporary Override') { payload["override-name"] = data.reason; + if (data.duration !== undefined && parseInt(data.duration) > 0) { + payload["override-duration-minutes"] = parseInt(data.duration); + } alert = data.reasonDisplay + " Temporary Override"; + } else if (data.eventType === 'Remote Carbs Entry') { + payload["carbs-entry"] = parseFloat(data.remoteCarbs); + if(payload["carbs-entry"] > 0.0 ) { + payload["absorption-time"] = 3.0; + if (data.remoteAbsorption !== undefined && parseFloat(data.remoteAbsorption) > 0.0) { + payload["absorption-time"] = parseFloat(data.remoteAbsorption); + } + if (data.otp !== undefined && data.otp.length > 0) { + payload["otp"] = ""+data.otp + } + alert = "Remote Carbs Entry: "+payload["carbs-entry"]+" grams\n"; + alert += "Absorption Time: "+payload["absorption-time"]+" hours"; + } else { + completion("Loop remote carbs failed. Incorrect carbs entry: ", data.remoteCarbs); + return; + } + + } else if (data.eventType === 'Remote Bolus Entry') { + payload["bolus-entry"] = parseFloat(data.remoteBolus); + if(payload["bolus-entry"] > 0.0 ) { + alert = "Remote Bolus Entry: "+payload["bolus-entry"]+" U\n"; + if (data.otp !== undefined && data.otp.length > 0) { + payload["otp"] = ""+data.otp + } + } else { + completion("Loop remote bolus failed. Incorrect bolus entry: ", data.remoteBolus); + return; + } } else { completion("Loop notification failed: Unhandled event type:", data.eventType); return; @@ -84,10 +119,6 @@ function init (env, ctx) { notification.expiry = Math.round((Date.now() / 1000)) + 60 * 5; // Allow this to enact within 5 minutes. notification.payload = payload; - if (data.duration && parseInt(data.duration) > 0) { - notification.payload["override-duration-minutes"] = parseInt(data.duration); - } - provider.send(notification, [loopSettings.deviceToken]).then( (response) => { if (response.sent && response.sent.length > 0) { completion(); diff --git a/test b/test new file mode 100644 index 00000000000..e69de29bb2d diff --git a/views/index.html b/views/index.html index 156aa331325..f7ac2420253 100644 --- a/views/index.html +++ b/views/index.html @@ -327,7 +327,24 @@ Sensor
-
+ + + + + +
+