diff --git a/lib/plugins/cannulaage.js b/lib/plugins/cannulaage.js index 0feff1a7..9d2d664c 100644 --- a/lib/plugins/cannulaage.js +++ b/lib/plugins/cannulaage.js @@ -18,16 +18,12 @@ module.exports = init; cage.getPrefs = function getPrefs (sbx) { // CAGE_INFO = 44 CAGE_WARN=48 CAGE_URGENT=70 - var info = Number(sbx.extendedSettings.info); - var warn = Number(sbx.extendedSettings.warn); - var urgent = Number(sbx.extendedSettings.urgent); - return { - info: !isNaN(info) ? info : 44, - warn: !isNaN(warn) ? warn : 48, - urgent: !isNaN(urgent) ? urgent : 72, - display: sbx.extendedSettings.display ? sbx.extendedSettings.display : 'hours', - enableAlerts: sbx.extendedSettings.enableAlerts + info: sbx.extendedSettings.info || 44 + , warn: sbx.extendedSettings.warn || 48 + , urgent: sbx.extendedSettings.urgent || 72 + , display: sbx.extendedSettings.display ? sbx.extendedSettings.display : 'hours' + , enableAlerts: sbx.extendedSettings.enableAlerts || false }; }; @@ -44,8 +40,7 @@ cage.findLatestTimeChange = function findLatestTimeChange (sbx) { var prefs = cage.getPrefs(sbx); var cannulaInfo = { - message:'' - , found: false + found: false , age: 0 , treatmentDate: null , checkForAlert: false @@ -67,18 +62,13 @@ cage.findLatestTimeChange = function findLatestTimeChange (sbx) { var hours = a.diff(b,'hours') - days * 24; var age = a.diff(b,'hours'); - cannulaInfo.minFractions = a.diff(b,'minutes') - age * 60; - - if (!cannulaInfo.found) { + if (!cannulaInfo.found || (age >= 0 && age < cannulaInfo.age)) { cannulaInfo.found = true; cannulaInfo.age = age; cannulaInfo.days = days; cannulaInfo.hours = hours; - } else if (age >= 0 && age < cannulaInfo.age) { - cannulaInfo.age = age; - cannulaInfo.days = days; - cannulaInfo.hours = hours; cannulaInfo.notes = treatment.notes; + cannulaInfo.minFractions = a.diff(b,'minutes') - age * 60; } } }); @@ -104,7 +94,7 @@ cage.findLatestTimeChange = function findLatestTimeChange (sbx) { cannulaInfo.level = levels.INFO; } - if (sendNotification && cannulaInfo.minFractions <= 30) { + if (prefs.enableAlerts && sendNotification && cannulaInfo.minFractions <= 30) { cannulaInfo.notification = { title: 'Cannula age ' + cannulaInfo.age + ' hours' , message: message diff --git a/lib/plugins/insulinage.js b/lib/plugins/insulinage.js index 930496a5..b78cc7dd 100644 --- a/lib/plugins/insulinage.js +++ b/lib/plugins/insulinage.js @@ -2,6 +2,7 @@ var _ = require('lodash'); var moment = require('moment'); +var levels = require('../levels'); var iage = { name: 'iage' @@ -16,50 +17,30 @@ function init() { module.exports = init; iage.getPrefs = function getPrefs(sbx) { - // IAGE_INFO = 44 IAGE_WARN=48 IAGE_URGENT=70 + // IAGE_INFO=44 IAGE_WARN=48 IAGE_URGENT=70 return { - 'info' : sbx.extendedSettings.info ? sbx.extendedSettings.info : 44, - 'warn' : sbx.extendedSettings.warn ? sbx.extendedSettings.warn : 48, - 'urgent' : sbx.extendedSettings.urgent ? sbx.extendedSettings.urgent : 72, - 'enableAlerts' : sbx.extendedSettings.enableAlerts + info: sbx.extendedSettings.info || 44 + , warn: sbx.extendedSettings.warn || 48 + , urgent: sbx.extendedSettings.urgent || 72 + , enableAlerts: sbx.extendedSettings.enableAlerts || false }; }; iage.checkNotifications = function checkNotifications(sbx) { - var insulinInfo = iage.findLatestTimeChange(sbx); - var prefs = iage.getPrefs(sbx); - if (!prefs.enableAlerts || !insulinInfo.checkForAlert) { return; } - - var sendNotification = false; - var title = 'Insulin reservoir age ' + insulinInfo.age +' hours'; - var sound = 'incoming'; - var msg = ', change due soon'; - var level = 1; - - if (insulinInfo.age === Number(prefs.info)) { sendNotification = true; } - if (insulinInfo.age === Number(prefs.warn)) { sendNotification = true; msg = ', time to change'; } - if (insulinInfo.age === Number(prefs.urgent)) { sendNotification = true; msg = ', change overdue!'; sound = 'persistent'; level = 2;} - - if (sendNotification) { - sbx.notifications.requestNotify({ - level: level - , title: title - , message: title + msg - , pushoverSound: sound - , plugin: iage - , group: 'IAGE' - , debug: { - insulinInfo: insulinInfo - } - }); + if (insulinInfo.notification) { + sbx.notifications.requestNotify(insulinInfo.notification); } }; iage.findLatestTimeChange = function findLatestTimeChange(sbx) { - var returnValue = {'message':'', 'found': false, 'age': 0, 'treatmentDate': null, 'checkForAlert': false}; + var insulinInfo = { + found: false + , age: 0 + , treatmentDate: null + }; var prevDate = 0; @@ -68,39 +49,64 @@ iage.findLatestTimeChange = function findLatestTimeChange(sbx) { if (treatmentDate > prevDate && treatmentDate <= sbx.time) { prevDate = treatmentDate; - returnValue.treatmentDate = treatmentDate; + insulinInfo.treatmentDate = treatmentDate; //allow for 30 minute period after a full hour during which we'll alert the user var a = moment(sbx.time); - var b = moment(returnValue.treatmentDate); + var b = moment(insulinInfo.treatmentDate); var days = a.diff(b,'days'); var hours = a.diff(b,'hours') - days * 24; var age = a.diff(b,'hours'); - var minFractions = a.diff(b,'minutes') - age * 60; - - returnValue.checkForAlert = minFractions <= 30; - if (!returnValue.found) { - returnValue.found = true; - returnValue.age = age; - returnValue.days = days; - returnValue.hours = hours; - } else { - if (age >= 0 && age < returnValue.age) { - returnValue.age = age; - returnValue.days = days; - returnValue.hours = hours; - if (treatment.notes) { - returnValue.message = treatment.notes; - } else { - returnValue.message = ''; - } - } + if (!insulinInfo.found || (age >= 0 && age < insulinInfo.age)) { + insulinInfo.found = true; + insulinInfo.age = age; + insulinInfo.days = days; + insulinInfo.hours = hours; + insulinInfo.notes = treatment.notes; + insulinInfo.minFractions = a.diff(b,'minutes') - age * 60; } } }); - return returnValue; + var prefs = iage.getPrefs(sbx); + + insulinInfo.level = levels.NONE; + + var sound = 'incoming'; + var message; + var sendNotification = false; + + if (insulinInfo.age >= insulinInfo.urgent) { + sendNotification = insulinInfo.age === prefs.urgent; + message = 'Insulin reservoir change overdue!'; + sound = 'persistent'; + insulinInfo.level = levels.URGENT; + } else if (insulinInfo.age >= prefs.warn) { + sendNotification = insulinInfo.age === prefs.warn; + message = 'Time to change insulin reservoir'; + insulinInfo.level = levels.WARN; + } else if (insulinInfo.age > prefs.info) { + sendNotification = insulinInfo.age === prefs.info; + message = 'Change insulin reservoir soon'; + insulinInfo.level = levels.INFO; + } + + if (prefs.enableAlerts && sendNotification && insulinInfo.minFractions <= 30) { + insulinInfo.notification = { + title: 'Insulin reservoir age ' + insulinInfo.age +' hours' + , message: message + , pushoverSound: sound + , level: insulinInfo.level + , plugin: iage + , group: 'IAGE' + , debug: { + age: insulinInfo.age + } + }; + } + + return insulinInfo; }; iage.updateVisualisation = function updateVisualisation (sbx) { @@ -120,9 +126,16 @@ iage.updateVisualisation = function updateVisualisation (sbx) { shownAge = insulinInfo.found ? insulinInfo.age + 'h' : 'n/a '; } + var statusClass = null; + if (insulinInfo.level === levels.URGENT) { + statusClass = 'urgent'; + } else if (insulinInfo.level === levels.WARN) { + statusClass = 'warn'; + } sbx.pluginBase.updatePillText(iage, { value: shownAge , label: 'IAGE' , info: info + , pillClass: statusClass }); }; \ No newline at end of file diff --git a/lib/plugins/sensorage.js b/lib/plugins/sensorage.js index b1c6643d..fbb50e38 100644 --- a/lib/plugins/sensorage.js +++ b/lib/plugins/sensorage.js @@ -3,6 +3,7 @@ var _ = require('lodash'); var moment = require('moment'); var times = require('../times'); +var levels = require('../levels'); var sage = { name: 'sage' @@ -17,12 +18,11 @@ function init() { module.exports = init; sage.getPrefs = function getPrefs(sbx) { - // SAGE_INFO = 6d SAGE_WARN=6d20h SAGE_URGENT=6d22h return { - 'info' : sbx.extendedSettings.info ? sbx.extendedSettings.info : times.days(6).hours, - 'warn' : sbx.extendedSettings.warn ? sbx.extendedSettings.warn : times.days(7).hours - 4, - 'urgent' : sbx.extendedSettings.urgent ? sbx.extendedSettings.urgent : times.days(7).hours - 2, - 'enableAlerts' : sbx.extendedSettings.enableAlerts + info: sbx.extendedSettings.info || times.days(6).hours + , warn: sbx.extendedSettings.warn || (times.days(7).hours - 4) + , urgent: sbx.extendedSettings.urgent || (times.days(7).hours - 2) + , enableAlerts: sbx.extendedSettings.enableAlerts || false }; }; @@ -30,33 +30,11 @@ sage.checkNotifications = function checkNotifications(sbx) { var info = sage.findLatestTimeChange(sbx); var sensorInfo = info[info.min]; - var prefs = sage.getPrefs(sbx); - if (!prefs.enableAlerts || !sensorInfo.checkForAlert) { return; } - - var sendNotification = false; - var title = 'Sensor age ' + sensorInfo.days +' days' + sensorInfo.hours +' hours'; - var sound = 'incoming'; - var msg = ', change due soon'; - var level = 1; - - if (sensorInfo.age === Number(prefs.info)) { sendNotification = true; } - if (sensorInfo.age === Number(prefs.warn)) { sendNotification = true; msg = ', time to change'; } - if (sensorInfo.age === Number(prefs.urgent)) { sendNotification = true; msg = ', sensor will stop!'; sound = 'persistent'; level = 2;} - - if (sendNotification) { - sbx.notifications.requestNotify({ - level: level - , title: title - , message: title + msg - , pushoverSound: sound - , plugin: sage - , group: 'SAGE' - , debug: { - sensorInfo: sensorInfo - } - }); + if (sensorInfo.notification) { + sbx.notifications.requestNotify(sensorInfo.notification); } + }; function minButValid(record) { @@ -78,13 +56,21 @@ function minButValid(record) { sage.findLatestTimeChange = function findLatestTimeChange(sbx) { var returnValue = { - 'Sensor Start': {'message':'', 'found': false, 'age': 0, 'treatmentDate': null, 'checkForAlert': false} - , 'Sensor Change': {'message':'', 'found': false, 'age': 0, 'treatmentDate': null, 'checkForAlert': false} + 'Sensor Start': { + found: false + , age: 0 + , treatmentDate: null + } + , 'Sensor Change': { + found: false + , age: 0 + , treatmentDate: null + } }; var prevDate = { 'Sensor Start': 0 - ,'Sensor Change': 0 + , 'Sensor Change': 0 }; _.each(sbx.data.sensorTreatments, function eachTreatment (treatment) { @@ -101,26 +87,14 @@ sage.findLatestTimeChange = function findLatestTimeChange(sbx) { var days = a.diff(b,'days'); var hours = a.diff(b,'hours') - days * 24; var age = a.diff(b,'hours'); - var minFractions = a.diff(b,'minutes') - age * 60; - - returnValue[event].checkForAlert = minFractions <= 30; - if (!returnValue[event].found) { + if (!returnValue[event].found || (age >= 0 && age < returnValue[event].age)) { returnValue[event].found = true; returnValue[event].age = age; returnValue[event].days = days; returnValue[event].hours = hours; - } else { - if (age >= 0 && age < returnValue[event].age) { - returnValue[event].age = age; - returnValue[event].days = days; - returnValue[event].hours = hours; - if (treatment.notes) { - returnValue[event].message = treatment.notes; - } else { - returnValue[event].message = ''; - } - } + returnValue[event].notes = treatment.notes; + returnValue[event].minFractions = a.diff(b,'minutes') - age * 60; } } }); @@ -130,44 +104,92 @@ sage.findLatestTimeChange = function findLatestTimeChange(sbx) { if (returnValue['Sensor Change'].found && returnValue['Sensor Start'].found && returnValue['Sensor Start'].treatmentDate < returnValue['Sensor Change'].treatmentDate) { returnValue['Sensor Start'] = {'message':'', 'found': false, 'age': 0, 'treatmentDate': null, 'checkForAlert': false}; } + returnValue.min = minButValid(returnValue); + var sensorInfo = returnValue[returnValue.min]; + var prefs = sage.getPrefs(sbx); + + var sendNotification = false; + var sound = 'incoming'; + var message; + + sensorInfo.level = levels.NONE; + + if (sensorInfo.age > prefs.urgent) { + sendNotification = sensorInfo.age === prefs.urgent; + message = 'Sensor change/restart overdue!'; + sound = 'persistent'; + sensorInfo.level = levels.URGENT; + } else if (sensorInfo.age > prefs.warn) { + sendNotification = sensorInfo.age === prefs.warn; + message = 'Time to change/restart sensor'; + sensorInfo.level = levels.WARN; + } else if (sensorInfo.age >= prefs.info) { + sendNotification = sensorInfo.age === prefs.info; + message = 'Change/restart sensor soon'; + sensorInfo.level = levels.INFO; + } + + if (prefs.enableAlerts && sendNotification && sensorInfo.minFractions <= 30) { + sensorInfo.notification = { + title: 'Sensor age ' + sensorInfo.days + ' days' + sensorInfo.hours +' hours' + , message: message + , pushoverSound: sound + , level: sensorInfo.level + , plugin: sage + , group: 'SAGE' + , debug: { + age: sensorInfo.age + } + }; + } + return returnValue; }; sage.updateVisualisation = function updateVisualisation (sbx) { - var sensorInfo = sage.findLatestTimeChange(sbx); + var latest = sage.findLatestTimeChange(sbx); + var sensorInfo = latest[latest.min]; var info = []; var shownAge; ['Sensor Change', 'Sensor Start'].forEach( function eachEvent(event) { - if (sensorInfo[event].found) { - info.push( { label: event, value: new Date(sensorInfo[event].treatmentDate).toLocaleString() } ); + if (latest[event].found) { + info.push( { label: event, value: new Date(latest[event].treatmentDate).toLocaleString() } ); shownAge = ''; - if (sensorInfo[event].age > 24) { - shownAge += sensorInfo[event].days + ' days '; + if (latest[event].age > 24) { + shownAge += latest[event].days + ' days '; } - shownAge += sensorInfo[event].hours + ' hours'; + shownAge += latest[event].hours + ' hours'; info.push( { label: 'Duration', value: shownAge } ); - if (sensorInfo[event].message !== '') { - info.push({label: 'Notes:', value: sensorInfo[event].message}); + if (!_.isEmpty(latest[event].notes)) { + info.push({label: 'Notes:', value: latest[event].notes}); } } }); shownAge = ''; - if (sensorInfo[sensorInfo.min].found) { - if (sensorInfo[sensorInfo.min].age >= 24) { - shownAge += sensorInfo[sensorInfo.min].days + 'd'; + if (sensorInfo.found) { + if (sensorInfo.age >= 24) { + shownAge += latest[latest.min].days + 'd'; } - shownAge += sensorInfo[sensorInfo.min].hours + 'h'; + shownAge += latest[latest.min].hours + 'h'; } else { shownAge = 'n/a '; } + var statusClass = null; + if (sensorInfo.level === levels.URGENT) { + statusClass = 'urgent'; + } else if (sensorInfo.level === levels.WARN) { + statusClass = 'warn'; + } + sbx.pluginBase.updatePillText(sage, { value: shownAge , label: 'SAGE' , info: info + , pillClass: statusClass }); }; \ No newline at end of file diff --git a/lib/times.js b/lib/times.js index 2b112cdd..900155a8 100644 --- a/lib/times.js +++ b/lib/times.js @@ -8,7 +8,7 @@ var factories = { } , days: function days(value) { return { - mins: value * 24 * 60, secs: value * 24 * 60 * 60, msecs: value * 24 * 60 * 60 * 1000 + hours: value * 24, mins: value * 24 * 60, secs: value * 24 * 60 * 60, msecs: value * 24 * 60 * 60 * 1000 }; } , hours: function hours(value) {