mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
Bolus settings (#6834)
* Add bolus plugin and restructure rendering settings * Add setting to prevent automated micro boluses from triggering notifications and snoozing alarms * clean up * Small change to the bolus-settings branch so it supports flexible configuration that enables the old behavior * Translations * Fix settings default Co-authored-by: Jason Calabrese <jason@cbrese.com>
This commit is contained in:
co-authored by
Jason Calabrese
parent
84ac8f7e74
commit
d762694b83
@@ -104,6 +104,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
- [`bage` (Battery Age)](#bage-battery-age)
|
||||
- [`treatmentnotify` (Treatment Notifications)](#treatmentnotify-treatment-notifications)
|
||||
- [`basal` (Basal Profile)](#basal-basal-profile)
|
||||
- [`bolus` (Bolus Rendering)](#bolus-bolus-rendering)
|
||||
- [`bridge` (Share2Nightscout bridge)](#bridge-share2nightscout-bridge)
|
||||
- [`mmconnect` (MiniMed Connect bridge)](#mmconnect-minimed-connect-bridge)
|
||||
- [`pump` (Pump Monitoring)](#pump-pump-monitoring)
|
||||
@@ -313,7 +314,6 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs/ or
|
||||
* The `linear` option has equidistant tick marks; the range used is dynamic so that space at the top of chart isn't wasted.
|
||||
* The `log-dynamic` is similar to the default `log` options, but uses the same dynamic range and the `linear` scale.
|
||||
* `EDIT_MODE` (`on`) - possible values `on` or `off`. Enables the icon allowing for editing of treatments in the main view.
|
||||
* `BOLUS_RENDER_OVER` (1) - U value over which the bolus values are rendered on the chart if the 'x U and Over' option is selected. This value can be an integer or a float, e.g. 0.3, 1.5, 2, etc...
|
||||
|
||||
### Predefined values for your server settings (optional)
|
||||
* `INSECURE_USE_HTTP` (`false`) - Redirect unsafe http traffic to https. Possible values `false`, or `true`. Your site redirects to `https` by default. If you don't want that from Nightscout, but want to implement that with a Nginx or Apache proxy, set `INSECURE_USE_HTTP` to `true`. Note: This will allow (unsafe) http traffic to your Nightscout instance and is not recommended.
|
||||
@@ -470,12 +470,20 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs/ or
|
||||
* `BAGE_URGENT` (`360`) - If time since last `Pump Battery Change` matches `BAGE_URGENT` hours, user will be issued a persistent warning of overdue change (default of 360 hours is 15 days).
|
||||
|
||||
##### `treatmentnotify` (Treatment Notifications)
|
||||
Generates notifications when a treatment has been entered and snoozes alarms minutes after a treatment. Default snooze is 10 minutes, and can be set using the `TREATMENTNOTIFY_SNOOZE_MINS` [extended setting](#extended-settings).
|
||||
Generates notifications when a treatment has been entered and snoozes alarms minutes after a treatment.
|
||||
* `TREATMENTNOTIFY_SNOOZE_MINS` (`10`) - Number of minutes to snooze notifications after a treatment is entered
|
||||
* `TREATMENTNOTIFY_INCLUDE_BOLUSES_OVER` (`0`) - U value over which the bolus will trigger a notification and snooze alarms
|
||||
|
||||
##### `basal` (Basal Profile)
|
||||
Adds the Basal pill visualization to display the basal rate for the current time. Also enables the `bwp` plugin to calculate correction temp basal suggestions. Uses the `basal` field from the [treatment profile](#treatment-profile). Also uses the extended setting:
|
||||
* `BASAL_RENDER` (`none`) - Possible values are `none`, `default`, or `icicle` (inverted)
|
||||
|
||||
##### `bolus` (Bolus Rendering)
|
||||
Settings to configure Bolus rendering
|
||||
* `BOLUS_RENDER_OVER` (`0`) - U value over which the bolus labels use the format defined in `BOLUS_RENDER_FORMAT`. This value can be an integer or a float, e.g. 0.3, 1.5, 2, etc.
|
||||
* `BOLUS_RENDER_FORMAT` (`default`) - Possible values are `hidden`, `default` (with leading zero and U), `concise` (with U, without leading zero), and `minimal` (without leading zero and U).
|
||||
* `BOLUS_RENDER_FORMAT_SMALL` (`default`) - Possible values are `hidden`, `default` (with leading zero and U), `concise` (with U, without leading zero), and `minimal` (without leading zero and U).
|
||||
|
||||
##### `bridge` (Share2Nightscout bridge)
|
||||
Glucose reading directly from the Dexcom Share service, uses these extended settings:
|
||||
* `BRIDGE_USER_NAME` - Your username for the Share service.
|
||||
|
||||
@@ -13,6 +13,29 @@ function init (client, serverSettings, $) {
|
||||
var storage = Storages.localStorage;
|
||||
var settings = require('../settings')();
|
||||
|
||||
function updateBolusRender () {
|
||||
var bolusSettings = client.settings.extendedSettings.bolus || {};
|
||||
|
||||
var allRenderOverOptions = [5, 1, 0.5, 0.1];
|
||||
if (_.isNumber(bolusSettings.renderOver) && bolusSettings.renderOver > 0 && bolusSettings.renderOver < Number.MAX_SAFE_INTEGER) {
|
||||
allRenderOverOptions.push(_.toNumber(bolusSettings.renderOver));
|
||||
}
|
||||
var sortedRenderOverOptions = _.chain(allRenderOverOptions).uniq().sort().reverse().value();
|
||||
|
||||
_.forEach(sortedRenderOverOptions, function (optionValue) {
|
||||
$('#bolusRenderOver').append(
|
||||
$('<option></option>')
|
||||
.attr('value', optionValue)
|
||||
.text(client.translate('%1 U and Over', { params: [optionValue] }))
|
||||
);
|
||||
});
|
||||
|
||||
$('#bolusRenderOver').val(String(bolusSettings.renderOver || 0.5));
|
||||
$('#bolusRenderFormat').val(bolusSettings.renderFormat ? bolusSettings.renderFormat : 'default');
|
||||
$('#bolusRenderFormatSmall').val(bolusSettings.renderFormatSmall ? bolusSettings.renderFormatSmall : 'default');
|
||||
|
||||
}
|
||||
|
||||
function loadForm () {
|
||||
var utils = client.utils;
|
||||
var language = client.language;
|
||||
@@ -70,7 +93,7 @@ function init (client, serverSettings, $) {
|
||||
|
||||
$('#basalrender').val(settings.extendedSettings.basal ? settings.extendedSettings.basal.render : 'none');
|
||||
|
||||
$('#bolusrender').val(settings.extendedSettings.bolus ? settings.extendedSettings.bolus.render : 'all');
|
||||
updateBolusRender();
|
||||
|
||||
if (settings.timeFormat === 24) {
|
||||
$('#24-browser').prop('checked', true);
|
||||
@@ -162,7 +185,7 @@ function init (client, serverSettings, $) {
|
||||
storage.remove(name);
|
||||
});
|
||||
storage.remove('basalrender');
|
||||
storage.remove('bolusrender');
|
||||
storage.remove('bolus');
|
||||
event.preventDefault();
|
||||
client.browserUtils.reload();
|
||||
});
|
||||
@@ -215,7 +238,11 @@ function init (client, serverSettings, $) {
|
||||
, language: $('#language').val()
|
||||
, scaleY: $('#scaleY').val()
|
||||
, basalrender: $('#basalrender').val()
|
||||
, bolusrender: $('#bolusrender').val()
|
||||
, bolus: {
|
||||
renderOver: $('#bolusRenderOver').val()
|
||||
, renderFormat: $('#bolusRenderFormat').val()
|
||||
, renderFormatSmall: $('#bolusRenderFormatSmall').val()
|
||||
}
|
||||
, showPlugins: checkedPluginNames()
|
||||
, storageVersion: STORAGE_VERSION
|
||||
});
|
||||
@@ -276,11 +303,17 @@ function init (client, serverSettings, $) {
|
||||
settings.extendedSettings.basal.render = basalStored !== null ? basalStored : settings.extendedSettings.basal.render;
|
||||
|
||||
if (!settings.extendedSettings.bolus) {
|
||||
settings.extendedSettings.bolus = {};
|
||||
settings.extendedSettings.bolus = {
|
||||
renderOver: 0
|
||||
, renderFormat: 'default'
|
||||
, renderFormatSmall: 'default'
|
||||
};
|
||||
}
|
||||
|
||||
var bolusStored = storage.get('bolusrender');
|
||||
settings.extendedSettings.bolus.render = bolusStored !== null ? bolusStored : settings.extendedSettings.bolus.render;
|
||||
var bolusStored = storage.get('bolus');
|
||||
settings.extendedSettings.bolus.renderOver = bolusStored !== null ? _.toNumber(bolusStored.renderOver) : settings.extendedSettings.bolus.renderOver;
|
||||
settings.extendedSettings.bolus.renderFormat = bolusStored !== null ? bolusStored.renderFormat : settings.extendedSettings.bolus.renderFormat;
|
||||
settings.extendedSettings.bolus.renderFormatSmall = bolusStored !== null ? bolusStored.renderFormatSmall : settings.extendedSettings.bolus.renderFormatSmall;
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
@@ -445,11 +445,6 @@ client.load = function load (serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateBolusRenderOver () {
|
||||
var bolusRenderOver = (client.settings.bolusRenderOver || 1) + ' U and Over';
|
||||
$('#bolusRenderOver').text(bolusRenderOver);
|
||||
}
|
||||
|
||||
function alarmingNow () {
|
||||
return container.hasClass('alarming');
|
||||
}
|
||||
@@ -1305,7 +1300,6 @@ client.load = function load (serverSettings, callback) {
|
||||
|
||||
prepareEntries();
|
||||
updateTitle();
|
||||
updateBolusRenderOver();
|
||||
|
||||
// Don't invoke D3 in headless mode
|
||||
|
||||
|
||||
+16
-9
@@ -529,7 +529,7 @@ function init (client, d3) {
|
||||
};
|
||||
}
|
||||
|
||||
function prepareArc (treatment, radius, renderBasal) {
|
||||
function prepareArc (treatment, radius, bolusSettings) {
|
||||
var arc_data = [
|
||||
// white carb half-circle on top
|
||||
{ 'element': '', 'color': 'white', 'start': -1.5708, 'end': 1.5708, 'inner': 0, 'outer': radius.R1 }
|
||||
@@ -566,12 +566,14 @@ function init (client, d3) {
|
||||
|
||||
if (treatment.insulin > 0) {
|
||||
var dosage_units = '' + Math.round(treatment.insulin * 100) / 100;
|
||||
|
||||
var format = treatment.insulin < bolusSettings.renderOver ? bolusSettings.renderFormatSmall : bolusSettings.renderFormat;
|
||||
|
||||
if (renderBasal === 'all-remove-zero-u') {
|
||||
if (_.includes(['concise', 'minimal'], format)) {
|
||||
dosage_units = (dosage_units + "").replace(/^0/, "");
|
||||
}
|
||||
|
||||
var unit_of_measurement = (renderBasal === 'all-remove-zero-u' ? '' : ' U'); // One international unit of insulin (1 IU) is shown as '1 U'
|
||||
var unit_of_measurement = (format === 'minimal' ? '' : ' U'); // One international unit of insulin (1 IU) is shown as '1 U'
|
||||
|
||||
arc_data[3].element = dosage_units + unit_of_measurement;
|
||||
}
|
||||
@@ -992,7 +994,8 @@ function init (client, d3) {
|
||||
renderer.drawTreatments = function drawTreatments (client) {
|
||||
|
||||
var treatmentCount = 0;
|
||||
var renderBasal = client.settings.extendedSettings.bolus.render;
|
||||
var bolusSettings = client.settings.extendedSettings.bolus || {};
|
||||
|
||||
chart().focus.selectAll('.draggable-treatment').remove();
|
||||
|
||||
_.forEach(client.ddata.treatments, function eachTreatment (d) {
|
||||
@@ -1001,17 +1004,21 @@ function init (client, d3) {
|
||||
|
||||
// add treatment bubbles
|
||||
_.forEach(client.ddata.treatments, function eachTreatment (d) {
|
||||
var showLabels = ( !d.carbs && ( ( renderBasal == 'none') || ( renderBasal === 'over' && d.insulin < client.settings.bolusRenderOver) ) ) ? false : true;
|
||||
var showLabels = d.carbs || d.insulin;
|
||||
if (d.insulin && d.insulin < bolusSettings.renderOver && bolusSettings.renderFormatSmall == 'hidden') {
|
||||
showLabels = false;
|
||||
}
|
||||
renderer.drawTreatment(d, {
|
||||
scale: renderer.bubbleScale()
|
||||
, showLabels: showLabels
|
||||
, treatments: treatmentCount
|
||||
}, client.sbx.data.profile.getCarbRatio(new Date()),
|
||||
renderBasal);
|
||||
}
|
||||
, client.sbx.data.profile.getCarbRatio(new Date())
|
||||
, bolusSettings);
|
||||
});
|
||||
};
|
||||
|
||||
renderer.drawTreatment = function drawTreatment (treatment, opts, carbratio, renderBasal) {
|
||||
renderer.drawTreatment = function drawTreatment (treatment, opts, carbratio, bolusSettings) {
|
||||
if (!treatment.carbs && !treatment.protein && !treatment.fat && !treatment.insulin) {
|
||||
return;
|
||||
}
|
||||
@@ -1029,7 +1036,7 @@ function init (client, d3) {
|
||||
return;
|
||||
}
|
||||
|
||||
var arc = prepareArc(treatment, radius, renderBasal);
|
||||
var arc = prepareArc(treatment, radius, bolusSettings);
|
||||
var treatmentDots = appendTreatments(treatment, arc);
|
||||
appendLabels(treatmentDots, arc, opts);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
function init () {
|
||||
|
||||
var bolus = {
|
||||
name: 'bolus'
|
||||
, label: 'Bolus'
|
||||
, pluginType: 'fake'
|
||||
};
|
||||
|
||||
bolus.getPrefs = function getPrefs(sbx) {
|
||||
return {
|
||||
renderFormat: sbx.extendedSettings.renderFormat ? sbx.extendedSettings.renderFormat : 'default'
|
||||
, renderOver: sbx.extendedSettings.renderOver ? sbx.extendedSettings.renderOver : 0
|
||||
, notifyOver: sbx.extendedSettings.notifyOver ? sbx.extendedSettings.notifyOver : 0
|
||||
};
|
||||
};
|
||||
|
||||
return bolus;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
@@ -46,6 +46,7 @@ function init (ctx) {
|
||||
, require('./insulinage')(ctx)
|
||||
, require('./batteryage')(ctx)
|
||||
, require('./basalprofile')(ctx)
|
||||
, require('./bolus')(ctx) // fake plugin to hold extended settings
|
||||
, require('./boluscalc')(ctx) // fake plugin to show/hide
|
||||
, require('./profile')(ctx) // fake plugin to hold extended settings
|
||||
, require('./speech')(ctx)
|
||||
@@ -128,7 +129,7 @@ function init (ctx) {
|
||||
};
|
||||
|
||||
//these plugins are either always on or have custom settings
|
||||
plugins.specialPlugins = 'ar2 bgnow delta direction timeago upbat rawbg errorcodes profile';
|
||||
plugins.specialPlugins = 'ar2 bgnow delta direction timeago upbat rawbg errorcodes profile bolus';
|
||||
|
||||
plugins.shownPlugins = function(sbx) {
|
||||
return _filter(enabledPlugins, function filterPlugins (plugin) {
|
||||
|
||||
@@ -20,12 +20,17 @@ function init(ctx) {
|
||||
function filterTreatments (sbx) {
|
||||
var treatments = sbx.data.treatments;
|
||||
|
||||
var includeBolusesOver = sbx.extendedSettings.includeBolusesOver || 0;
|
||||
|
||||
treatments = _.filter(treatments, function notOpenAPS (treatment) {
|
||||
var ok = true;
|
||||
var enteredBy = treatment.enteredBy;
|
||||
if (enteredBy && (enteredBy.indexOf('openaps://') === 0 || enteredBy.indexOf('loop://') === 0)) {
|
||||
ok = _.indexOf(MANUAL_TREATMENTS, treatment.eventType) >= 0;
|
||||
}
|
||||
if (ok && _.isNumber(treatment.insulin) && _.includes(['Meal Bolus', 'Correction Bolus'], treatment.eventType)) {
|
||||
ok = treatment.insulin >= includeBolusesOver;
|
||||
}
|
||||
return ok;
|
||||
});
|
||||
|
||||
|
||||
+1
-2
@@ -52,7 +52,6 @@ function init () {
|
||||
, deNormalizeDates: false
|
||||
, showClockDelta: false
|
||||
, showClockLastTime: false
|
||||
, bolusRenderOver: 1
|
||||
, frameUrl1: ''
|
||||
, frameUrl2: ''
|
||||
, frameUrl3: ''
|
||||
@@ -170,7 +169,7 @@ function init () {
|
||||
}
|
||||
|
||||
//TODO: getting sent in status.json, shouldn't be
|
||||
settings.DEFAULT_FEATURES = ['bgnow', 'delta', 'direction', 'timeago', 'devicestatus', 'upbat', 'errorcodes', 'profile', 'dbsize', 'runtimestate', 'basal', 'careportal'];
|
||||
settings.DEFAULT_FEATURES = ['bgnow', 'delta', 'direction', 'timeago', 'devicestatus', 'upbat', 'errorcodes', 'profile', 'bolus', 'dbsize', 'runtimestate', 'basal', 'careportal'];
|
||||
|
||||
var wasSet = [];
|
||||
|
||||
|
||||
@@ -694,4 +694,11 @@
|
||||
,"Weekly Distribution":"Weekly Distribution"
|
||||
,"Failed authentication":"Failed authentication"
|
||||
,"A device at IP address %1 attempted authenticating with Nightscout with wrong credentials. Check if you have an uploader setup with wrong API_SECRET or token?": "A device at IP address %1 attempted authenticating with Nightscout with wrong credentials. Check if you have an uploader setup with wrong API_SECRET or token?"
|
||||
,"Default (with leading zero and U)":"Default (with leading zero and U)"
|
||||
,"Concise (with U, without leading zero)":"Concise (with U, without leading zero)"
|
||||
,"Minimal (without leading zero and U)":"Minimal (without leading zero and U)"
|
||||
,"Small Bolus Display":"Small Bolus Display"
|
||||
,"Large Bolus Display":"Large Bolus Display"
|
||||
,"Bolus Display Threshold":"Bolus Display Threshold"
|
||||
,"%1 U and Over":"%1 U and Over"
|
||||
}
|
||||
|
||||
+23
-6
@@ -217,13 +217,30 @@
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="translate">Render Bolus Amount</dt>
|
||||
<dt class="translate">Bolus Display Threshold</dt>
|
||||
<dd>
|
||||
<select id="bolusrender">
|
||||
<option class="translate" value="all">All</option>
|
||||
<option class="translate" value="all-remove-zero-u">All (without leading zero and U)</option>
|
||||
<option class="translate" id="bolusRenderOver" value="over">1 U and Over</option>
|
||||
<option class="translate" value="none">None</option>
|
||||
<select id="bolusRenderOver"></select>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="translate">Small Bolus Display</dt>
|
||||
<dd>
|
||||
<select id="bolusRenderFormatSmall">
|
||||
<option class="translate" value="hidden">Hidden</option>
|
||||
<option class="translate" value="default">Default (with leading zero and U)</option>
|
||||
<option class="translate" value="concise">Concise (with U, without leading zero)</option>
|
||||
<option class="translate" value="minimal">Minimal (without leading zero and U)</option>
|
||||
</select>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl>
|
||||
<dt class="translate">Large Bolus Display</dt>
|
||||
<dd>
|
||||
<select id="bolusRenderFormat">
|
||||
<option class="translate" value="hidden">Hidden</option>
|
||||
<option class="translate" value="default">Default (with leading zero and U)</option>
|
||||
<option class="translate" value="concise">Concise (with U, without leading zero)</option>
|
||||
<option class="translate" value="minimal">Minimal (without leading zero and U)</option>
|
||||
</select>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
Reference in New Issue
Block a user