mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
Fix all issues from ESLint (#4730)
* Cherry picks the ES language changes from #4690 * Fix small issues found in linting * * Fix all but one eslint complaint in the bundled code * Add eslint and js-beautify rc files into the repo
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
module.exports = {
|
||||
"plugins": [ ],
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
],
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es6": true,
|
||||
"node": true,
|
||||
"jquery": true
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"indent_size": 2
|
||||
, "indent_char": " "
|
||||
, "comma_first": true
|
||||
, "keep-array-indentation": true
|
||||
, "space_after_named_function": true
|
||||
, "space_after_anon_function": true
|
||||
, "end_with_newline": true
|
||||
, "brace_style": "collapse,preserve-inline"
|
||||
, "space_in_brace": true
|
||||
, "space-in-paren": false
|
||||
, "break-chained-methods": false
|
||||
, "max-preserve-newlines": 2
|
||||
, "space-after-anon-function": false
|
||||
, "indent-empty-lines": false
|
||||
}
|
||||
@@ -8,7 +8,7 @@ var cleanstatusdb = {
|
||||
, pluginType: 'admin'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return cleanstatusdb;
|
||||
}
|
||||
|
||||
@@ -30,24 +30,24 @@ cleanstatusdb.actions = [
|
||||
}
|
||||
];
|
||||
|
||||
cleanstatusdb.actions[0].init = function init(client, callback) {
|
||||
cleanstatusdb.actions[0].init = function init (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + cleanstatusdb.name + '_0_status');
|
||||
|
||||
$status.hide().text(translate('Loading database ...')).fadeIn('slow');
|
||||
$.ajax('/api/v1/devicestatus.json?count=500', {
|
||||
headers: client.headers()
|
||||
, success: function (records) {
|
||||
, success: function(records) {
|
||||
var recs = (records.length === 500 ? '500+' : records.length);
|
||||
$status.hide().text(translate('Database contains %1 records',{ params: [recs] })).fadeIn('slow');
|
||||
$status.hide().text(translate('Database contains %1 records', { params: [recs] })).fadeIn('slow');
|
||||
}
|
||||
, error: function () {
|
||||
, error: function() {
|
||||
$status.hide().text(translate('Error loading database')).fadeIn('slow');
|
||||
}
|
||||
}).done(function () { if (callback) { callback(); } });
|
||||
}).done(function() { if (callback) { callback(); } });
|
||||
};
|
||||
|
||||
cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
|
||||
cleanstatusdb.actions[0].code = function deleteRecords (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + cleanstatusdb.name + '_0_status');
|
||||
|
||||
@@ -57,7 +57,7 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
$status.hide().text(translate('Deleting records ...')).fadeIn('slow');
|
||||
$.ajax({
|
||||
@@ -69,7 +69,7 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}).fail(function fail() {
|
||||
}).fail(function fail () {
|
||||
$status.hide().text(translate('Error')).fadeIn('slow');
|
||||
if (callback) {
|
||||
callback();
|
||||
@@ -77,24 +77,24 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
|
||||
});
|
||||
};
|
||||
|
||||
cleanstatusdb.actions[1].init = function init(client, callback) {
|
||||
cleanstatusdb.actions[1].init = function init (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + cleanstatusdb.name + '_1_status');
|
||||
|
||||
$status.hide();
|
||||
|
||||
var numDays = '<br/>'
|
||||
+ '<label for="admin_devicestatus_days">'
|
||||
+ translate('Number of Days to Keep:')
|
||||
+ ' <input id="admin_devicestatus_days" value="30" size="3" min="1"/>'
|
||||
+ '</label>';
|
||||
var numDays = '<br/>' +
|
||||
'<label for="admin_devicestatus_days">' +
|
||||
translate('Number of Days to Keep:') +
|
||||
' <input id="admin_devicestatus_days" value="30" size="3" min="1"/>' +
|
||||
'</label>';
|
||||
|
||||
$('#admin_' + cleanstatusdb.name + '_1_html').html(numDays);
|
||||
|
||||
if (callback) { callback(); }
|
||||
};
|
||||
|
||||
cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) {
|
||||
cleanstatusdb.actions[1].code = function deleteOldRecords (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + cleanstatusdb.name + '_1_status');
|
||||
var numDays = Number($('#admin_devicestatus_days').val());
|
||||
@@ -119,15 +119,15 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) {
|
||||
$.ajax('/api/v1/devicestatus/?find[created_at][$lte]=' + dateStr, {
|
||||
method: 'DELETE'
|
||||
, headers: client.headers()
|
||||
, success: function (retVal) {
|
||||
$status.text(translate('%1 records deleted',{ params: [retVal.n] }));
|
||||
, success: function(retVal) {
|
||||
$status.text(translate('%1 records deleted', { params: [retVal.n] }));
|
||||
}
|
||||
, error: function () {
|
||||
, error: function() {
|
||||
$status.hide().text(translate('Error')).fadeIn('slow');
|
||||
}
|
||||
}).done(function success () {
|
||||
if (callback) { callback(); }
|
||||
}).fail(function fail() {
|
||||
}).fail(function fail () {
|
||||
if (callback) { callback(); }
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ var futureitems = {
|
||||
, pluginType: 'admin'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return futureitems;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ futureitems.actions = [
|
||||
, description: 'This task find and remove treatments in the future.'
|
||||
, buttonLabel: 'Remove treatments in the future'
|
||||
}
|
||||
|
||||
, {
|
||||
name: 'Find and remove entries in the future'
|
||||
, description: 'This task find and remove CGM data in the future created by uploader with wrong date/time.'
|
||||
@@ -25,7 +26,7 @@ futureitems.actions = [
|
||||
}
|
||||
];
|
||||
|
||||
futureitems.actions[0].init = function init(client, callback) {
|
||||
futureitems.actions[0].init = function init (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + futureitems.name + '_0_status');
|
||||
|
||||
@@ -34,52 +35,52 @@ futureitems.actions[0].init = function init(client, callback) {
|
||||
}
|
||||
|
||||
function showOneTreatment (tr, table) {
|
||||
table.append($('<tr>').css('background-color','#0f0f0f')
|
||||
.append($('<td>').attr('width','20%').append(new Date(tr.created_at).toLocaleString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3')))
|
||||
.append($('<td>').attr('width','20%').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : ''))
|
||||
.append($('<td>').attr('width','10%').attr('align','center').append(tr.glucose ? tr.glucose + ' ('+translate(tr.glucoseType)+')' : ''))
|
||||
.append($('<td>').attr('width','10%').attr('align','center').append(valueOrEmpty(tr.insulin)))
|
||||
.append($('<td>').attr('width','10%').attr('align','center').append(valueOrEmpty(tr.carbs)))
|
||||
.append($('<td>').attr('width','10%').append(valueOrEmpty(tr.enteredBy)))
|
||||
.append($('<td>').attr('width','20%').append(valueOrEmpty(tr.notes)))
|
||||
table.append($('<tr>').css('background-color', '#0f0f0f')
|
||||
.append($('<td>').attr('width', '20%').append(new Date(tr.created_at).toLocaleString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3')))
|
||||
.append($('<td>').attr('width', '20%').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : ''))
|
||||
.append($('<td>').attr('width', '10%').attr('align', 'center').append(tr.glucose ? tr.glucose + ' (' + translate(tr.glucoseType) + ')' : ''))
|
||||
.append($('<td>').attr('width', '10%').attr('align', 'center').append(valueOrEmpty(tr.insulin)))
|
||||
.append($('<td>').attr('width', '10%').attr('align', 'center').append(valueOrEmpty(tr.carbs)))
|
||||
.append($('<td>').attr('width', '10%').append(valueOrEmpty(tr.enteredBy)))
|
||||
.append($('<td>').attr('width', '20%').append(valueOrEmpty(tr.notes)))
|
||||
);
|
||||
}
|
||||
|
||||
function showTreatments(treatments, table) {
|
||||
table.append($('<tr>').css('background','#040404')
|
||||
.append($('<th>').css('width','80px').attr('align','left').append(translate('Time')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(translate('Event Type')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(translate('Blood Glucose')))
|
||||
.append($('<th>').css('width','50px').attr('align','left').append(translate('Insulin')))
|
||||
.append($('<th>').css('width','50px').attr('align','left').append(translate('Carbs')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(translate('Entered By')))
|
||||
.append($('<th>').css('width','300px').attr('align','left').append(translate('Notes')))
|
||||
function showTreatments (treatments, table) {
|
||||
table.append($('<tr>').css('background', '#040404')
|
||||
.append($('<th>').css('width', '80px').attr('align', 'left').append(translate('Time')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(translate('Event Type')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(translate('Blood Glucose')))
|
||||
.append($('<th>').css('width', '50px').attr('align', 'left').append(translate('Insulin')))
|
||||
.append($('<th>').css('width', '50px').attr('align', 'left').append(translate('Carbs')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(translate('Entered By')))
|
||||
.append($('<th>').css('width', '300px').attr('align', 'left').append(translate('Notes')))
|
||||
);
|
||||
for (var t=0; t<treatments.length; t++) {
|
||||
showOneTreatment (treatments[t], table);
|
||||
for (var t = 0; t < treatments.length; t++) {
|
||||
showOneTreatment(treatments[t], table);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$status.hide().text(translate('Loading database ...')).fadeIn('slow');
|
||||
var nowiso = new Date().toISOString();
|
||||
$.ajax('/api/v1/treatments.json?&find[created_at][$gte]=' + nowiso, {
|
||||
headers: client.headers()
|
||||
, success: function (records) {
|
||||
, success: function(records) {
|
||||
futureitems.treatmentrecords = records;
|
||||
$status.hide().text(translate('Database contains %1 future records',{ params: [records.length] })).fadeIn('slow');
|
||||
var table = $('<table>').css('margin-top','10px');
|
||||
$status.hide().text(translate('Database contains %1 future records', { params: [records.length] })).fadeIn('slow');
|
||||
var table = $('<table>').css('margin-top', '10px');
|
||||
$('#admin_' + futureitems.name + '_0_html').append(table);
|
||||
showTreatments(records, table);
|
||||
futureitems.actions[0].confirmText = translate('Remove %1 selected records?', { params: [records.length] });
|
||||
}
|
||||
, error: function () {
|
||||
, error: function() {
|
||||
$status.hide().text(translate('Error loading database')).fadeIn('slow');
|
||||
futureitems.treatmentrecords = [];
|
||||
}
|
||||
}).done(function () { if (callback) { callback(); } });
|
||||
}).done(function() { if (callback) { callback(); } });
|
||||
};
|
||||
|
||||
futureitems.actions[0].code = function deleteRecords(client, callback) {
|
||||
futureitems.actions[0].code = function deleteRecords (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + futureitems.name + '_0_status');
|
||||
|
||||
@@ -89,7 +90,7 @@ futureitems.actions[0].code = function deleteRecords(client, callback) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
function deleteRecordById (_id) {
|
||||
$.ajax({
|
||||
@@ -98,7 +99,7 @@ futureitems.actions[0].code = function deleteRecords(client, callback) {
|
||||
, headers: client.headers()
|
||||
}).done(function success () {
|
||||
$status.text(translate('Record %1 removed ...', { params: [_id] }));
|
||||
}).fail(function fail() {
|
||||
}).fail(function fail () {
|
||||
$status.text(translate('Error removing record %1', { params: [_id] }));
|
||||
});
|
||||
}
|
||||
@@ -114,7 +115,7 @@ futureitems.actions[0].code = function deleteRecords(client, callback) {
|
||||
}
|
||||
};
|
||||
|
||||
futureitems.actions[1].init = function init(client, callback) {
|
||||
futureitems.actions[1].init = function init (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + futureitems.name + '_1_status');
|
||||
|
||||
@@ -122,19 +123,19 @@ futureitems.actions[1].init = function init(client, callback) {
|
||||
var now = new Date().getTime();
|
||||
$.ajax('/api/v1/entries.json?&find[date][$gte]=' + now + '&count=288', {
|
||||
headers: client.headers()
|
||||
, success: function (records) {
|
||||
, success: function(records) {
|
||||
futureitems.entriesrecords = records;
|
||||
$status.hide().text(translate('Database contains %1 future records',{ params: [records.length] })).fadeIn('slow');
|
||||
$status.hide().text(translate('Database contains %1 future records', { params: [records.length] })).fadeIn('slow');
|
||||
futureitems.actions[1].confirmText = translate('Remove %1 selected records?', { params: [records.length] });
|
||||
}
|
||||
, error: function () {
|
||||
, error: function() {
|
||||
$status.hide().text(translate('Error loading database')).fadeIn('slow');
|
||||
futureitems.entriesrecords = [];
|
||||
}
|
||||
}).done(function () { if (callback) { callback(); } });
|
||||
}).done(function() { if (callback) { callback(); } });
|
||||
};
|
||||
|
||||
futureitems.actions[1].code = function deleteRecords(client, callback) {
|
||||
futureitems.actions[1].code = function deleteRecords (client, callback) {
|
||||
var translate = client.translate;
|
||||
var $status = $('#admin_' + futureitems.name + '_1_status');
|
||||
|
||||
@@ -144,7 +145,7 @@ futureitems.actions[1].code = function deleteRecords(client, callback) {
|
||||
callback();
|
||||
}
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
function deteleteRecordById (_id) {
|
||||
$.ajax({
|
||||
@@ -153,12 +154,11 @@ futureitems.actions[1].code = function deleteRecords(client, callback) {
|
||||
, headers: client.headers()
|
||||
}).done(function success () {
|
||||
$status.text(translate('Record %1 removed ...', { params: [_id] }));
|
||||
}).fail(function fail() {
|
||||
}).fail(function fail () {
|
||||
$status.text(translate('Error removing record %1', { params: [_id] }));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$status.hide().text(translate('Deleting records ...')).fadeIn('slow');
|
||||
for (var i = 0; i < futureitems.entriesrecords.length; i++) {
|
||||
deteleteRecordById(futureitems.entriesrecords[i]._id);
|
||||
|
||||
+48
-45
@@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
var roles = {
|
||||
name: 'roles'
|
||||
, label: 'Roles - Groups of People, Devices, etc'
|
||||
, pluginType: 'admin'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -20,13 +22,13 @@ roles.actions = [{
|
||||
, init: function init (client, callback) {
|
||||
$status = $('#admin_' + roles.name + '_0_status');
|
||||
$status.hide().text(client.translate('Loading database ...')).fadeIn('slow');
|
||||
var table = $('<table id="admin_roles_table">').css('margin-top','10px');
|
||||
var table = $('<table id="admin_roles_table">').css('margin-top', '10px');
|
||||
$('#admin_' + roles.name + '_0_html').append(table).append(genDialog(client));
|
||||
reload(client, callback);
|
||||
}
|
||||
, preventClose: true
|
||||
, code: function createNewRole (client, callback) {
|
||||
var role = { };
|
||||
var role = {};
|
||||
openDialog(role, client, callback);
|
||||
}
|
||||
}];
|
||||
@@ -40,9 +42,9 @@ function createOrSaveRole (role, client, callback) {
|
||||
, url: '/api/v2/authorization/roles/'
|
||||
, headers: client.headers()
|
||||
, data: role
|
||||
}).done(function success() {
|
||||
}).done(function success () {
|
||||
reload(client, callback);
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
console.error('Unable to ' + method + ' Role', err.responseText);
|
||||
window.alert(client.translate('Unable to %1 Role', { params: [method] }));
|
||||
if (callback) {
|
||||
@@ -56,9 +58,9 @@ function deleteRole (role, client, callback) {
|
||||
method: 'DELETE'
|
||||
, url: '/api/v2/authorization/roles/' + role._id
|
||||
, headers: client.headers()
|
||||
}).done(function success() {
|
||||
}).done(function success () {
|
||||
reload(client, callback);
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
console.error('Unable to delete Role', err.responseText);
|
||||
window.alert(client.translate('Unable to delete Role'));
|
||||
if (callback) {
|
||||
@@ -70,16 +72,16 @@ function deleteRole (role, client, callback) {
|
||||
function reload (client, callback) {
|
||||
$.ajax({
|
||||
method: 'GET'
|
||||
, url:'/api/v2/authorization/roles'
|
||||
, url: '/api/v2/authorization/roles'
|
||||
, headers: client.headers()
|
||||
}).done(function success (records) {
|
||||
roles.records = records;
|
||||
$status.hide().text(client.translate('Database contains %1 roles',{ params: [records.length] })).fadeIn('slow');
|
||||
$status.hide().text(client.translate('Database contains %1 roles', { params: [records.length] })).fadeIn('slow');
|
||||
showRoles(records, client);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
$status.hide().text(client.translate('Error loading database')).fadeIn('slow');
|
||||
roles.records = [];
|
||||
if (callback) {
|
||||
@@ -90,31 +92,31 @@ function reload (client, callback) {
|
||||
|
||||
function genDialog (client) {
|
||||
var ret =
|
||||
'<div id="editroledialog" style="display:none" title="' + client.translate('Edit Role') + '">'
|
||||
+ ' <label for="edrole_name">'
|
||||
+ client.translate('Name')
|
||||
+ ' <input id="edrole_name" placeholder="' + client.translate('admin, school, family, etc') + '"/>'
|
||||
+ ' </label>'
|
||||
+ ' <br>'
|
||||
+ ' <label for="edrole_permissions">' + client.translate('Permissions') + '</label>'
|
||||
+ ' <textarea id="edrole_permissions" rows="3" style="width:300px"></textarea><br>'
|
||||
+ ' <br>'
|
||||
+ ' <label for="edrole_notes">' + client.translate('Additional Notes, Comments') + '</label>'
|
||||
+ ' <textarea id="edrole_notes" style="width:300px"></textarea><br>'
|
||||
+ ' </div>'
|
||||
;
|
||||
'<div id="editroledialog" style="display:none" title="' + client.translate('Edit Role') + '">' +
|
||||
' <label for="edrole_name">' +
|
||||
client.translate('Name') +
|
||||
' <input id="edrole_name" placeholder="' + client.translate('admin, school, family, etc') + '"/>' +
|
||||
' </label>' +
|
||||
' <br>' +
|
||||
' <label for="edrole_permissions">' + client.translate('Permissions') + '</label>' +
|
||||
' <textarea id="edrole_permissions" rows="3" style="width:300px"></textarea><br>' +
|
||||
' <br>' +
|
||||
' <label for="edrole_notes">' + client.translate('Additional Notes, Comments') + '</label>' +
|
||||
' <textarea id="edrole_notes" style="width:300px"></textarea><br>' +
|
||||
' </div>';
|
||||
|
||||
return $(ret);
|
||||
}
|
||||
|
||||
function openDialog (role, client) {
|
||||
$( '#editroledialog' ).dialog({
|
||||
$('#editroledialog').dialog({
|
||||
width: 360
|
||||
, height: 360
|
||||
, buttons: [
|
||||
{ text: client.translate('Save'),
|
||||
class: 'leftButton',
|
||||
click: function() {
|
||||
{
|
||||
text: client.translate('Save')
|
||||
, class: 'leftButton'
|
||||
, click: function() {
|
||||
|
||||
role.name = $('#edrole_name').val();
|
||||
role.permissions =
|
||||
@@ -128,18 +130,19 @@ function openDialog (role, client) {
|
||||
var self = this;
|
||||
delete role.autoGenerated;
|
||||
createOrSaveRole(role, client, function callback () {
|
||||
$( self ).dialog('close');
|
||||
$(self).dialog('close');
|
||||
});
|
||||
}
|
||||
},
|
||||
{ text: client.translate('Cancel'),
|
||||
click: function () { $( this ).dialog('close'); }
|
||||
}
|
||||
, {
|
||||
text: client.translate('Cancel')
|
||||
, click: function() { $(this).dialog('close'); }
|
||||
}
|
||||
]
|
||||
, open : function() {
|
||||
, open: function() {
|
||||
$(this).parent().css('box-shadow', '20px 20px 20px 0px black');
|
||||
$(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'});
|
||||
$(this).parent().find('button:contains("'+client.translate('Save')+'")').css({'float':'left'});
|
||||
$(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' });
|
||||
$(this).parent().find('button:contains("' + client.translate('Save') + '")').css({ 'float': 'left' });
|
||||
$('#edrole_name').val(role.name || '').focus();
|
||||
$('#edrole_permissions').val(role.permissions ? role.permissions.join(' ') : '');
|
||||
$('#edrole_notes').val(role.notes || '');
|
||||
@@ -151,14 +154,14 @@ function openDialog (role, client) {
|
||||
|
||||
function showRole (role, table, client) {
|
||||
var editIcon = $('<img title="' + client.translate('Edit this role') + '" style="cursor:pointer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABEUlEQVQ4jZ3MMUsCYQDG8ee8IySQbNCLyyEKG/RLNAXicqvQcAeNLrcFLlE0+xHuNpt8wy04rrYm8Q4HQRE56BSC3lSqU1BwCoxM39dnffj9BWyxXvVeEzvtctBwHyRebNu2Nk2lzMlrgJB+qBEeTByiKYpihl+fIO8jTI9PDJEVF1+K2iw+M6PhDuyag4NkQi/c3FkCK5Z3ZbM76qLltpCbn+vXxq0FABsDy9hzPdBvqvtXvvXzrw1swmsDLPjfACteGeDBfwK8+FdgGwwAIgC0ncsjxGRSH/eiPBgAJADY2z8sJ4JBfNBsDqlADVYMANIzKalv/bHaefKsTH9iPFb8ISsGAJym0+Qinz3jQktbAHcxvx3559eSAAAAAElFTkSuQmCC">');
|
||||
editIcon.click(function clicked ( ) {
|
||||
editIcon.click(function clicked () {
|
||||
openDialog(role, client);
|
||||
});
|
||||
|
||||
var deleteIcon = '';
|
||||
if (role._id) {
|
||||
deleteIcon = $('<img title="Delete this role" class="titletranslate" style="cursor:pointer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACrElEQVQ4T42Ty2sTQRzHv5tmk2yyjRNtpfZhL8V6s2KoUNC2XqwgaCsVQcGiFqpHi0c9iRdR/ANE9KR40FIQX4cueKoPaKFoLdSYNtE0abKT1+5s9iW7aUMiHtzTzO7v85md+c6PA4DrHbsPCKIgOWO1pA7dT6YXnXH949SE/F63pqwZtRrO+SCKgjQ5NUV+azpmHj2krMwaJC4c8Erj+/eRyloMMwWFKgbn1nC3ervlK1evkXBLGBZT8SOewotnTylTNLdgeg/pDgZDC2cPHSR8bB22DVC9hFe0SG/H0xFXcHlykjRHRDBWgJcZSCY38Xx2lhqMnRYE34Px/sN9vlQWeoHBAx2yXsRruVAVuFsIBaSJ8+eJGPaBqQV4NROJjTzez89jLBoFn6FgybQL54wS3uTyVDFQ3cL2IYpBv3RhdJSIIQ80tQyv7gEqJvS8AmUlBs7UXPhtjtZgh3UFNYngk86NHCfNAg9dMwHVBPu+CpsVkTXKeJeVG+AGgTOZ3tt6MSKKjy+NjEBjFrR4ElZmA4pdxstMFsyyJu6tZZ7Ux9vwB6EAL50ZGiRECEPPUOixVTRxHlicgSVWxEdZpuZWfNuS2hk48NjwMIkIYZglBnV5Cbqtws/5IaAJmsfCglrEl2y2QeKmEBJ80tixKmxrFpSVr0gV0viQoxho2YUuPohmeFD22PiklLC4ma5JuBvdrfLJI0dJd0s7bM0ES8aR/BXDXGaTskqlL+D3Lwy0tZEePoAd4EA5YF4tYymdonfjmQh3s6dTPjU4SHYGwjAKecSXFyGlM1TdytntE56T+ts7SC/vhw3gm6njc2Kd3vm5Ub1IwQAvnYhGiZpYw1wiWYPrIw7wnBTt7CLOOwdmut14kQQvqt24tfK/utGR6LaF+iRqMf4N/O/8D28HiiCRYqzAAAAAAElFTkSuQmCC">');
|
||||
deleteIcon.click(function clicked() {
|
||||
deleteIcon.click(function clicked () {
|
||||
var ok = window.confirm(client.translate('Are you sure you want to delete: ') + role.name);
|
||||
if (ok) {
|
||||
deleteRole(role, client);
|
||||
@@ -166,21 +169,21 @@ function showRole (role, table, client) {
|
||||
});
|
||||
}
|
||||
|
||||
table.append($('<tr>').css('background-color','#0f0f0f')
|
||||
.append($('<td>').attr('width','20%').append(editIcon).append(deleteIcon).append(role.name))
|
||||
.append($('<td>').attr('width','20%').append(_.isEmpty(role.permissions) ? '[none]' : role.permissions.join(' ')))
|
||||
.append($('<td>').attr('width','10%').append(role._id ? (role.notes ? role.notes : '') : '[system default]'))
|
||||
table.append($('<tr>').css('background-color', '#0f0f0f')
|
||||
.append($('<td>').attr('width', '20%').append(editIcon).append(deleteIcon).append(role.name))
|
||||
.append($('<td>').attr('width', '20%').append(_.isEmpty(role.permissions) ? '[none]' : role.permissions.join(' ')))
|
||||
.append($('<td>').attr('width', '10%').append(role._id ? (role.notes ? role.notes : '') : '[system default]'))
|
||||
);
|
||||
}
|
||||
|
||||
function showRoles (roles, client) {
|
||||
var table = $('#admin_roles_table');
|
||||
table.empty().append($('<tr>').css('background','#040404')
|
||||
.append($('<th>').css('width','100px').attr('align','left').append(client.translate('Name')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(client.translate('Permissions')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(client.translate('Notes')))
|
||||
table.empty().append($('<tr>').css('background', '#040404')
|
||||
.append($('<th>').css('width', '100px').attr('align', 'left').append(client.translate('Name')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(client.translate('Permissions')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(client.translate('Notes')))
|
||||
);
|
||||
for (var t=0; t<roles.length; t++) {
|
||||
for (var t = 0; t < roles.length; t++) {
|
||||
showRole(roles[t], table, client);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
var subjects = {
|
||||
name: 'subjects'
|
||||
, label: 'Subjects - People, Devices, etc'
|
||||
, pluginType: 'admin'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return subjects;
|
||||
}
|
||||
|
||||
@@ -20,7 +22,7 @@ subjects.actions = [{
|
||||
, init: function init (client, callback) {
|
||||
$status = $('#admin_' + subjects.name + '_0_status');
|
||||
$status.hide().text(client.translate('Loading database ...')).fadeIn('slow');
|
||||
var table = $('<table id="admin_subjects_table">').css('margin-top','10px');
|
||||
var table = $('<table id="admin_subjects_table">').css('margin-top', '10px');
|
||||
$('#admin_' + subjects.name + '_0_html').append(table).append(genDialog(client));
|
||||
reload(client, callback);
|
||||
}
|
||||
@@ -39,9 +41,9 @@ function createOrSaveSubject (subject, client, callback) {
|
||||
, url: '/api/v2/authorization/subjects/'
|
||||
, headers: client.headers()
|
||||
, data: subject
|
||||
}).done(function success() {
|
||||
}).done(function success () {
|
||||
reload(client, callback);
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
console.error('Unable to ' + method + ' Subject', err.responseText);
|
||||
window.alert(client.translate('Unable to ' + method + ' Subject'));
|
||||
if (callback) {
|
||||
@@ -55,9 +57,9 @@ function deleteSubject (subject, client, callback) {
|
||||
method: 'DELETE'
|
||||
, url: '/api/v2/authorization/subjects/' + subject._id
|
||||
, headers: client.headers()
|
||||
}).done(function success() {
|
||||
}).done(function success () {
|
||||
reload(client, callback);
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
console.error('Unable to delete Subject', err.responseText);
|
||||
window.alert(client.translate('Unable to delete Subject'));
|
||||
if (callback) {
|
||||
@@ -69,16 +71,16 @@ function deleteSubject (subject, client, callback) {
|
||||
function reload (client, callback) {
|
||||
$.ajax({
|
||||
method: 'GET'
|
||||
, url:'/api/v2/authorization/subjects'
|
||||
, url: '/api/v2/authorization/subjects'
|
||||
, headers: client.headers()
|
||||
}).done(function success (records) {
|
||||
subjects.records = records;
|
||||
$status.hide().text(client.translate('Database contains %1 subjects',{ params: [records.length] })).fadeIn('slow');
|
||||
$status.hide().text(client.translate('Database contains %1 subjects', { params: [records.length] })).fadeIn('slow');
|
||||
showSubjects(records, client);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
}).fail(function fail(err) {
|
||||
}).fail(function fail (err) {
|
||||
$status.hide().text(client.translate('Error loading database')).fadeIn('slow');
|
||||
subjects.records = [];
|
||||
if (callback) {
|
||||
@@ -89,33 +91,33 @@ function reload (client, callback) {
|
||||
|
||||
function genDialog (client) {
|
||||
var ret =
|
||||
'<div id="editsubjectdialog" style="display:none" title="' + client.translate('Edit Subject') + '">'
|
||||
+ ' <label for="edsub_name">'
|
||||
+ client.translate('Name')
|
||||
+ ' <input id="edsub_name" placeholder="' + client.translate('person, device, etc') + '"/>'
|
||||
+ ' </label>'
|
||||
+ ' <br>'
|
||||
+ ' <label for="edsub_roles">'
|
||||
+ client.translate('Roles')
|
||||
+ ' <input id="edsub_roles" placeholder="' + client.translate('role1, role2') + '"/>'
|
||||
+ ' </label>'
|
||||
+ ' <br>'
|
||||
+ ' <label for="edsub_notes">' + client.translate('Additional Notes, Comments') + '</label>'
|
||||
+ ' <textarea id="edsub_notes" style="width:300px"></textarea><br>'
|
||||
+ ' </div>'
|
||||
;
|
||||
'<div id="editsubjectdialog" style="display:none" title="' + client.translate('Edit Subject') + '">' +
|
||||
' <label for="edsub_name">' +
|
||||
client.translate('Name') +
|
||||
' <input id="edsub_name" placeholder="' + client.translate('person, device, etc') + '"/>' +
|
||||
' </label>' +
|
||||
' <br>' +
|
||||
' <label for="edsub_roles">' +
|
||||
client.translate('Roles') +
|
||||
' <input id="edsub_roles" placeholder="' + client.translate('role1, role2') + '"/>' +
|
||||
' </label>' +
|
||||
' <br>' +
|
||||
' <label for="edsub_notes">' + client.translate('Additional Notes, Comments') + '</label>' +
|
||||
' <textarea id="edsub_notes" style="width:300px"></textarea><br>' +
|
||||
' </div>';
|
||||
|
||||
return $(ret);
|
||||
}
|
||||
|
||||
function openDialog (subject, client) {
|
||||
$( '#editsubjectdialog' ).dialog({
|
||||
$('#editsubjectdialog').dialog({
|
||||
width: 360
|
||||
, height: 300
|
||||
, buttons: [
|
||||
{ text: client.translate('Save'),
|
||||
class: 'leftButton',
|
||||
click: function() {
|
||||
{
|
||||
text: client.translate('Save')
|
||||
, class: 'leftButton'
|
||||
, click: function() {
|
||||
subject.name = $('#edsub_name').val();
|
||||
subject.roles =
|
||||
_.chain($('#edsub_roles').val().toLowerCase().split(/[;, ]/))
|
||||
@@ -126,19 +128,20 @@ function openDialog (subject, client) {
|
||||
subject.notes = $('#edsub_notes').val();
|
||||
|
||||
var self = this;
|
||||
createOrSaveSubject(subject, client, function callback ( ) {
|
||||
$( self ).dialog('close');
|
||||
createOrSaveSubject(subject, client, function callback () {
|
||||
$(self).dialog('close');
|
||||
});
|
||||
}
|
||||
},
|
||||
{ text: client.translate('Cancel'),
|
||||
click: function () { $( this ).dialog('close'); }
|
||||
}
|
||||
, {
|
||||
text: client.translate('Cancel')
|
||||
, click: function() { $(this).dialog('close'); }
|
||||
}
|
||||
]
|
||||
, open : function() {
|
||||
, open: function() {
|
||||
$(this).parent().css('box-shadow', '20px 20px 20px 0px black');
|
||||
$(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'});
|
||||
$(this).parent().find('button:contains("'+client.translate('Save')+'")').css({'float':'left'});
|
||||
$(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' });
|
||||
$(this).parent().find('button:contains("' + client.translate('Save') + '")').css({ 'float': 'left' });
|
||||
$('#edsub_name').val(subject.name || '').focus();
|
||||
$('#edsub_roles').val(subject.roles ? subject.roles.join(', ') : '');
|
||||
$('#edsub_notes').val(subject.notes || '');
|
||||
@@ -150,33 +153,33 @@ function openDialog (subject, client) {
|
||||
|
||||
function showSubject (subject, table, client) {
|
||||
var editIcon = $('<img title="' + client.translate('Edit this subject') + '" style="cursor:pointer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABEUlEQVQ4jZ3MMUsCYQDG8ee8IySQbNCLyyEKG/RLNAXicqvQcAeNLrcFLlE0+xHuNpt8wy04rrYm8Q4HQRE56BSC3lSqU1BwCoxM39dnffj9BWyxXvVeEzvtctBwHyRebNu2Nk2lzMlrgJB+qBEeTByiKYpihl+fIO8jTI9PDJEVF1+K2iw+M6PhDuyag4NkQi/c3FkCK5Z3ZbM76qLltpCbn+vXxq0FABsDy9hzPdBvqvtXvvXzrw1swmsDLPjfACteGeDBfwK8+FdgGwwAIgC0ncsjxGRSH/eiPBgAJADY2z8sJ4JBfNBsDqlADVYMANIzKalv/bHaefKsTH9iPFb8ISsGAJym0+Qinz3jQktbAHcxvx3559eSAAAAAElFTkSuQmCC">');
|
||||
editIcon.click(function clicked ( ) {
|
||||
editIcon.click(function clicked () {
|
||||
openDialog(subject, client);
|
||||
});
|
||||
var deleteIcon = $('<img title="' + client.translate('Delete this subject') + '" style="cursor:pointer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACrElEQVQ4T42Ty2sTQRzHv5tmk2yyjRNtpfZhL8V6s2KoUNC2XqwgaCsVQcGiFqpHi0c9iRdR/ANE9KR40FIQX4cueKoPaKFoLdSYNtE0abKT1+5s9iW7aUMiHtzTzO7v85md+c6PA4DrHbsPCKIgOWO1pA7dT6YXnXH949SE/F63pqwZtRrO+SCKgjQ5NUV+azpmHj2krMwaJC4c8Erj+/eRyloMMwWFKgbn1nC3ervlK1evkXBLGBZT8SOewotnTylTNLdgeg/pDgZDC2cPHSR8bB22DVC9hFe0SG/H0xFXcHlykjRHRDBWgJcZSCY38Xx2lhqMnRYE34Px/sN9vlQWeoHBAx2yXsRruVAVuFsIBaSJ8+eJGPaBqQV4NROJjTzez89jLBoFn6FgybQL54wS3uTyVDFQ3cL2IYpBv3RhdJSIIQ80tQyv7gEqJvS8AmUlBs7UXPhtjtZgh3UFNYngk86NHCfNAg9dMwHVBPu+CpsVkTXKeJeVG+AGgTOZ3tt6MSKKjy+NjEBjFrR4ElZmA4pdxstMFsyyJu6tZZ7Ux9vwB6EAL50ZGiRECEPPUOixVTRxHlicgSVWxEdZpuZWfNuS2hk48NjwMIkIYZglBnV5Cbqtws/5IaAJmsfCglrEl2y2QeKmEBJ80tixKmxrFpSVr0gV0viQoxho2YUuPohmeFD22PiklLC4ma5JuBvdrfLJI0dJd0s7bM0ES8aR/BXDXGaTskqlL+D3Lwy0tZEePoAd4EA5YF4tYymdonfjmQh3s6dTPjU4SHYGwjAKecSXFyGlM1TdytntE56T+ts7SC/vhw3gm6njc2Kd3vm5Ub1IwQAvnYhGiZpYw1wiWYPrIw7wnBTt7CLOOwdmut14kQQvqt24tfK/utGR6LaF+iRqMf4N/O/8D28HiiCRYqzAAAAAAElFTkSuQmCC">');
|
||||
deleteIcon.click(function clicked ( ) {
|
||||
deleteIcon.click(function clicked () {
|
||||
var ok = window.confirm(client.translate('Are you sure you want to delete: ') + subject.name);
|
||||
if (ok) {
|
||||
deleteSubject(subject, client);
|
||||
}
|
||||
});
|
||||
table.append($('<tr>').css('background-color','#0f0f0f')
|
||||
.append($('<td>').attr('width','20%').append(editIcon).append(deleteIcon).append(subject.name))
|
||||
.append($('<td>').attr('width','20%').append(subject.roles ? subject.roles.join(', ') : '[none]'))
|
||||
.append($('<td>').attr('width','20%').append('<a href="/?token=' + subject.accessToken + '" target="_blank">' + subject.accessToken + '</a>'))
|
||||
.append($('<td>').attr('width','10%').append(subject.notes ? subject.notes : ''))
|
||||
table.append($('<tr>').css('background-color', '#0f0f0f')
|
||||
.append($('<td>').attr('width', '20%').append(editIcon).append(deleteIcon).append(subject.name))
|
||||
.append($('<td>').attr('width', '20%').append(subject.roles ? subject.roles.join(', ') : '[none]'))
|
||||
.append($('<td>').attr('width', '20%').append('<a href="/?token=' + subject.accessToken + '" target="_blank">' + subject.accessToken + '</a>'))
|
||||
.append($('<td>').attr('width', '10%').append(subject.notes ? subject.notes : ''))
|
||||
);
|
||||
}
|
||||
|
||||
function showSubjects (subjects, client) {
|
||||
var table = $('#admin_subjects_table');
|
||||
table.empty().append($('<tr>').css('background','#040404')
|
||||
.append($('<th>').css('width','100px').attr('align','left').append(client.translate('Name')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(client.translate('Roles')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(client.translate('Access Token')))
|
||||
.append($('<th>').css('width','150px').attr('align','left').append(client.translate('Notes')))
|
||||
table.empty().append($('<tr>').css('background', '#040404')
|
||||
.append($('<th>').css('width', '100px').attr('align', 'left').append(client.translate('Name')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(client.translate('Roles')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(client.translate('Access Token')))
|
||||
.append($('<th>').css('width', '150px').attr('align', 'left').append(client.translate('Notes')))
|
||||
);
|
||||
for (var t=0; t<subjects.length; t++) {
|
||||
for (var t = 0; t < subjects.length; t++) {
|
||||
showSubject(subjects[t], table, client);
|
||||
}
|
||||
}
|
||||
|
||||
+129
-128
@@ -5,8 +5,8 @@ var moment = require('moment-timezone');
|
||||
var times = require('../times');
|
||||
var Storages = require('js-storage');
|
||||
|
||||
function init(client, $) {
|
||||
var boluscalc = { };
|
||||
function init (client, $) {
|
||||
var boluscalc = {};
|
||||
|
||||
var translate = client.translate;
|
||||
var storage = Storages.localStorage;
|
||||
@@ -34,16 +34,15 @@ function init(client, $) {
|
||||
}
|
||||
}
|
||||
|
||||
function isProfileEnabled(profiles) {
|
||||
return client.settings.enable.indexOf('profile') > -1
|
||||
&& client.settings.extendedSettings.profile
|
||||
&& client.settings.extendedSettings.profile.multiple
|
||||
&& profiles.length > 1;
|
||||
function isProfileEnabled (profiles) {
|
||||
return client.settings.enable.indexOf('profile') > -1 &&
|
||||
client.settings.extendedSettings.profile &&
|
||||
client.settings.extendedSettings.profile.multiple &&
|
||||
profiles.length > 1;
|
||||
}
|
||||
|
||||
function isTouch() {
|
||||
try { document.createEvent('TouchEvent'); return true; }
|
||||
catch (e) { return false; }
|
||||
function isTouch () {
|
||||
try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; }
|
||||
}
|
||||
|
||||
function setDateAndTime (time) {
|
||||
@@ -52,11 +51,11 @@ function init(client, $) {
|
||||
eventDate.val(time.format('YYYY-MM-DD'));
|
||||
}
|
||||
|
||||
function mergeDateAndTime ( ) {
|
||||
function mergeDateAndTime () {
|
||||
return client.utils.mergeInputTime(eventTime.val(), eventDate.val());
|
||||
}
|
||||
|
||||
function updateTime(ele, time) {
|
||||
function updateTime (ele, time) {
|
||||
ele.attr('oldminutes', time.minutes());
|
||||
ele.attr('oldhours', time.hours());
|
||||
}
|
||||
@@ -98,15 +97,15 @@ function init(client, $) {
|
||||
}
|
||||
};
|
||||
|
||||
boluscalc.dateTimeFocus = function dateTimeFocus(event) {
|
||||
boluscalc.dateTimeFocus = function dateTimeFocus (event) {
|
||||
$('#bc_othertime').prop('checked', true);
|
||||
updateTime($(this), mergeDateAndTime());
|
||||
maybePrevent(event);
|
||||
};
|
||||
|
||||
boluscalc.dateTimeChange = function dateTimeChange(event) {
|
||||
boluscalc.dateTimeChange = function dateTimeChange (event) {
|
||||
$('#bc_othertime').prop('checked', true);
|
||||
// client.utils.setYAxisOffset(50); //50% of extend
|
||||
// client.utils.setYAxisOffset(50); //50% of extend
|
||||
var ele = $(this);
|
||||
var merged = mergeDateAndTime();
|
||||
|
||||
@@ -126,29 +125,29 @@ function init(client, $) {
|
||||
|
||||
boluscalc.calculateInsulin();
|
||||
maybePrevent(event);
|
||||
// Nightscout.utils.updateBrushToTime(moment.toDate());
|
||||
// Nightscout.utils.updateBrushToTime(moment.toDate());
|
||||
};
|
||||
|
||||
boluscalc.eventTimeTypeChange = function eventTimeTypeChange(event) {
|
||||
boluscalc.eventTimeTypeChange = function eventTimeTypeChange (event) {
|
||||
if ($('#bc_othertime').is(':checked')) {
|
||||
$('#bc_eventTimeValue').focus();
|
||||
$('#bc_retro').css('display','');
|
||||
if (mergeDateAndTime()<moment()) {
|
||||
$('#bc_retro').css('background-color','red').text(translate('RETRO MODE'));
|
||||
} else if (mergeDateAndTime()>moment()) {
|
||||
$('#bc_retro').css('background-color','blue').text(translate('IN THE FUTURE'));
|
||||
$('#bc_retro').css('display', '');
|
||||
if (mergeDateAndTime() < moment()) {
|
||||
$('#bc_retro').css('background-color', 'red').text(translate('RETRO MODE'));
|
||||
} else if (mergeDateAndTime() > moment()) {
|
||||
$('#bc_retro').css('background-color', 'blue').text(translate('IN THE FUTURE'));
|
||||
} else {
|
||||
$('#bc_retro').css('display','none');
|
||||
$('#bc_retro').css('display', 'none');
|
||||
}
|
||||
} else {
|
||||
$('#bc_retro').css('display','none');
|
||||
$('#bc_retro').css('display', 'none');
|
||||
setDateAndTime();
|
||||
boluscalc.updateVisualisations(client.sbx);
|
||||
if (event) {
|
||||
boluscalc.calculateInsulin();
|
||||
}
|
||||
// Nightscout.utils.setYAxisOffset(50); //50% of extend
|
||||
// Nightscout.utils.updateBrushToTime(Nightscout.utils.mergeInputTime($('#bc_eventTimeValue').val(), $('#bc_eventDateValue').val()).toDate());
|
||||
// Nightscout.utils.setYAxisOffset(50); //50% of extend
|
||||
// Nightscout.utils.updateBrushToTime(Nightscout.utils.mergeInputTime($('#bc_eventTimeValue').val(), $('#bc_eventDateValue').val()).toDate());
|
||||
}
|
||||
maybePrevent(event);
|
||||
};
|
||||
@@ -159,20 +158,20 @@ function init(client, $) {
|
||||
maybePrevent(event);
|
||||
};
|
||||
|
||||
boluscalc.prepare = function prepare( ) {
|
||||
boluscalc.prepare = function prepare () {
|
||||
foods = [];
|
||||
$('#bc_profile').empty();
|
||||
var profiles = client.profilefunctions.listBasalProfiles();
|
||||
profiles.forEach(function (p) {
|
||||
profiles.forEach(function(p) {
|
||||
$('#bc_profile').append('<option val="' + p + '">' + p + '</option>');
|
||||
});
|
||||
$('#bc_profileLabel').toggle(isProfileEnabled(profiles));
|
||||
|
||||
$('#bc_usebg').prop('checked','checked');
|
||||
$('#bc_usecarbs').prop('checked','checked');
|
||||
$('#bc_usecob').prop('checked','');
|
||||
$('#bc_useiob').prop('checked','checked');
|
||||
$('#bc_bgfromsensor').prop('checked','checked');
|
||||
$('#bc_usebg').prop('checked', 'checked');
|
||||
$('#bc_usecarbs').prop('checked', 'checked');
|
||||
$('#bc_usecob').prop('checked', '');
|
||||
$('#bc_useiob').prop('checked', 'checked');
|
||||
$('#bc_bgfromsensor').prop('checked', 'checked');
|
||||
$('#bc_carbs').val('');
|
||||
$('#bc_quickpick').val(-1);
|
||||
$('#bc_preBolus').val(0);
|
||||
@@ -189,7 +188,7 @@ function init(client, $) {
|
||||
|
||||
boluscalc.calculateInsulin = function calculateInsulin (event) {
|
||||
maybePrevent(event);
|
||||
boluscalc.gatherBoluscalcData( );
|
||||
boluscalc.gatherBoluscalcData();
|
||||
boluscalc.updateGui(boluscalc.record);
|
||||
return boluscalc.record;
|
||||
};
|
||||
@@ -236,8 +235,8 @@ function init(client, $) {
|
||||
$('#bc_bg').css('background-color', '');
|
||||
}
|
||||
$('#bc_inzulinbg').text(record.insulinbg.toFixed(2));
|
||||
$('#bc_inzulinbg').attr('title',
|
||||
'Target BG range: '+targetBGLow + ' - ' + targetBGHigh +
|
||||
$('#bc_inzulinbg').attr('title'
|
||||
, 'Target BG range: ' + targetBGLow + ' - ' + targetBGHigh +
|
||||
'\nISF: ' + isf +
|
||||
'\nBG diff: ' + record.bgdiff.toFixed(1)
|
||||
);
|
||||
@@ -252,51 +251,51 @@ function init(client, $) {
|
||||
if (record.foods.length) {
|
||||
var html = '<table style="float:right;margin-right:20px;font-size:12px">';
|
||||
var carbs = 0;
|
||||
for (var fi=0; fi<record.foods.length; fi++) {
|
||||
for (var fi = 0; fi < record.foods.length; fi++) {
|
||||
var f = record.foods[fi];
|
||||
carbs += f.carbs * f.portions;
|
||||
html += '<tr>';
|
||||
html += '<td>';
|
||||
if ($('#bc_quickpick').val() < 0) { // do not allow deleting while quickpick active
|
||||
html += '<img style="cursor:pointer" title="Delete record" src="'+icon_remove+'" href="#" class="deleteFoodRecord" index="'+fi+'">';
|
||||
html += '<img style="cursor:pointer" title="Delete record" src="' + icon_remove + '" href="#" class="deleteFoodRecord" index="' + fi + '">';
|
||||
}
|
||||
html += '</td>';
|
||||
html += '<td>'+ f.name + '</td>';
|
||||
html += '<td>'+ (f.portion*f.portions).toFixed(1) + ' ' + translate(f.unit) + '</td>';
|
||||
html += '<td>('+ (f.carbs*f.portions).toFixed(1) + ' g)</td>';
|
||||
html += '<td>' + f.name + '</td>';
|
||||
html += '<td>' + (f.portion * f.portions).toFixed(1) + ' ' + translate(f.unit) + '</td>';
|
||||
html += '<td>(' + (f.carbs * f.portions).toFixed(1) + ' g)</td>';
|
||||
html += '</tr>';
|
||||
}
|
||||
html += '</table>';
|
||||
$('#bc_food').html(html);
|
||||
$('.deleteFoodRecord').click(deleteFoodRecord);
|
||||
$('#bc_carbs').val(carbs.toFixed(0));
|
||||
$('#bc_carbs').attr('disabled',true);
|
||||
$('#bc_gi').css('display','none');
|
||||
$('#bc_gicalculated').css('display','');
|
||||
$('#bc_carbs').attr('disabled', true);
|
||||
$('#bc_gi').css('display', 'none');
|
||||
$('#bc_gicalculated').css('display', '');
|
||||
$('#bc_gicalculated').text(record.gi);
|
||||
} else {
|
||||
$('#bc_food').html('');
|
||||
$('#bc_carbs').attr('disabled',false);
|
||||
$('#bc_gi').css('display','');
|
||||
$('#bc_gicalculated').css('display','none');
|
||||
$('#bc_carbs').attr('disabled', false);
|
||||
$('#bc_gi').css('display', '');
|
||||
$('#bc_gicalculated').css('display', 'none');
|
||||
$('#bc_gicalculated').text('');
|
||||
}
|
||||
|
||||
// Show Carbs
|
||||
if ($('#bc_usecarbs').is(':checked')) {
|
||||
if ($('#bc_carbs').val() === '') {
|
||||
$('#bc_carbs').css('background-color','');
|
||||
} else if (isNaN(parseInt($('#bc_carbs').val().replace(',','.')))) {
|
||||
$('#bc_carbs').css('background-color','red');
|
||||
$('#bc_carbs').css('background-color', '');
|
||||
} else if (isNaN(parseInt($('#bc_carbs').val().replace(',', '.')))) {
|
||||
$('#bc_carbs').css('background-color', 'red');
|
||||
} else {
|
||||
$('#bc_carbs').css('background-color','');
|
||||
$('#bc_carbs').css('background-color', '');
|
||||
}
|
||||
$('#bc_inzulincarbs').text(record.insulincarbs.toFixed(2));
|
||||
$('#bc_inzulincarbs').attr('title','IC: ' + ic);
|
||||
$('#bc_inzulincarbs').attr('title', 'IC: ' + ic);
|
||||
} else {
|
||||
$('#bc_carbs').css('background-color','');
|
||||
$('#bc_carbs').css('background-color', '');
|
||||
$('#bc_inzulincarbs').text('');
|
||||
$('#bc_inzulincarbs').attr('title','');
|
||||
$('#bc_inzulincarbs').attr('title', '');
|
||||
$('#bc_carbs').text('');
|
||||
}
|
||||
|
||||
@@ -309,21 +308,21 @@ function init(client, $) {
|
||||
if (record.othercorrection === 0 && record.carbs === 0 && record.cob === 0 && record.bg > 0 && outcome > targetBGLow && outcome < targetBGHigh) {
|
||||
$('#bc_carbsneeded').text('');
|
||||
$('#bc_insulinover').text('');
|
||||
$('#bc_carbsneededtr').css('display','none');
|
||||
$('#bc_insulinneededtr').css('display','none');
|
||||
$('#bc_calculationintarget').css('display','');
|
||||
} else if (record.insulin<0) {
|
||||
$('#bc_carbsneeded').text(record.carbsneeded+' g');
|
||||
$('#bc_carbsneededtr').css('display', 'none');
|
||||
$('#bc_insulinneededtr').css('display', 'none');
|
||||
$('#bc_calculationintarget').css('display', '');
|
||||
} else if (record.insulin < 0) {
|
||||
$('#bc_carbsneeded').text(record.carbsneeded + ' g');
|
||||
$('#bc_insulinover').text(record.insulin.toFixed(2));
|
||||
$('#bc_carbsneededtr').css('display','');
|
||||
$('#bc_insulinneededtr').css('display','none');
|
||||
$('#bc_calculationintarget').css('display','none');
|
||||
$('#bc_carbsneededtr').css('display', '');
|
||||
$('#bc_insulinneededtr').css('display', 'none');
|
||||
$('#bc_calculationintarget').css('display', 'none');
|
||||
} else {
|
||||
$('#bc_carbsneeded').text('');
|
||||
$('#bc_insulinover').text('');
|
||||
$('#bc_carbsneededtr').css('display','none');
|
||||
$('#bc_insulinneededtr').css('display','');
|
||||
$('#bc_calculationintarget').css('display','none');
|
||||
$('#bc_carbsneededtr').css('display', 'none');
|
||||
$('#bc_insulinneededtr').css('display', '');
|
||||
$('#bc_calculationintarget').css('display', 'none');
|
||||
}
|
||||
|
||||
// Show basal rate
|
||||
@@ -335,7 +334,7 @@ function init(client, $) {
|
||||
$('#bc_basal').text(tempMark + basal.totalbasal.toFixed(3));
|
||||
};
|
||||
|
||||
boluscalc.gatherBoluscalcData = function gatherBoluscalcData() {
|
||||
boluscalc.gatherBoluscalcData = function gatherBoluscalcData () {
|
||||
boluscalc.record = {};
|
||||
var record = boluscalc.record;
|
||||
|
||||
@@ -351,7 +350,6 @@ function init(client, $) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Calculate event time from date & time
|
||||
record.eventTime = new Date();
|
||||
if ($('#bc_othertime').is(':checked')) {
|
||||
@@ -373,19 +371,19 @@ function init(client, $) {
|
||||
record.ic = ic;
|
||||
|
||||
if (targetBGLow === 0 || targetBGHigh === 0 || isf === 0 || ic === 0) {
|
||||
$('#bc_inzulinbgtd').css('background-color','red');
|
||||
$('#bc_inzulinbgtd').css('background-color', 'red');
|
||||
boluscalc.record = {};
|
||||
return;
|
||||
} else {
|
||||
$('#bc_inzulinbgtd').css('background-color','');
|
||||
$('#bc_inzulinbgtd').css('background-color', '');
|
||||
}
|
||||
|
||||
if (ic === 0) {
|
||||
$('#bc_inzulincarbstd').css('background-color','red');
|
||||
$('#bc_inzulincarbstd').css('background-color', 'red');
|
||||
boluscalc.record = {};
|
||||
return;
|
||||
} else {
|
||||
$('#bc_inzulincarbstd').css('background-color','');
|
||||
$('#bc_inzulincarbstd').css('background-color', '');
|
||||
}
|
||||
|
||||
// Load IOB
|
||||
@@ -407,7 +405,7 @@ function init(client, $) {
|
||||
record.insulinbg = 0;
|
||||
record.bgdiff = 0;
|
||||
if ($('#bc_usebg').is(':checked')) {
|
||||
record.bg = parseFloat($('#bc_bg').val().replace(',','.'));
|
||||
record.bg = parseFloat($('#bc_bg').val().replace(',', '.'));
|
||||
if (isNaN(record.bg)) {
|
||||
record.bg = 0;
|
||||
}
|
||||
@@ -417,7 +415,7 @@ function init(client, $) {
|
||||
record.bgdiff = record.bg - targetBGHigh;
|
||||
}
|
||||
record.bgdiff = roundTo(record.bgdiff, 0.1);
|
||||
if (record.bg !== 0){
|
||||
if (record.bg !== 0) {
|
||||
record.insulinbg = roundTo(record.bgdiff / isf, 0.01);
|
||||
}
|
||||
}
|
||||
@@ -427,7 +425,7 @@ function init(client, $) {
|
||||
record.foods = _.cloneDeep(foods);
|
||||
if (record.foods.length) {
|
||||
var gisum = 0;
|
||||
for (var fi=0; fi<record.foods.length; fi++) {
|
||||
for (var fi = 0; fi < record.foods.length; fi++) {
|
||||
var f = record.foods[fi];
|
||||
record.carbs += f.carbs * f.portions;
|
||||
gisum += f.carbs * f.portions * f.gi;
|
||||
@@ -441,7 +439,7 @@ function init(client, $) {
|
||||
record.insulincarbs = 0;
|
||||
if ($('#bc_usecarbs').is(':checked')) {
|
||||
if (record.carbs === 0) { // not set from foods
|
||||
record.carbs = parseInt($('#bc_carbs').val().replace(',','.'));
|
||||
record.carbs = parseInt($('#bc_carbs').val().replace(',', '.'));
|
||||
}
|
||||
if (isNaN(record.carbs)) {
|
||||
record.carbs = 0;
|
||||
@@ -462,15 +460,15 @@ function init(client, $) {
|
||||
|
||||
// Carbs needed if too much iob
|
||||
record.carbsneeded = 0;
|
||||
if (record.insulin<0) {
|
||||
if (record.insulin < 0) {
|
||||
record.carbsneeded = Math.ceil(-total * ic);
|
||||
}
|
||||
|
||||
console.log('Insulin calculation result: ',record);
|
||||
console.log('Insulin calculation result: ', record);
|
||||
return record;
|
||||
};
|
||||
|
||||
function gatherData ( ) {
|
||||
function gatherData () {
|
||||
var data = {};
|
||||
data.boluscalc = boluscalc.calculateInsulin();
|
||||
if (!data.boluscalc) {
|
||||
@@ -480,14 +478,14 @@ function init(client, $) {
|
||||
|
||||
data.enteredBy = $('#bc_enteredBy').val();
|
||||
data.eventType = 'Bolus Wizard';
|
||||
if ($('#bc_bg').val()!==0) {
|
||||
data.glucose = $('#bc_bg').val().replace(',','.');
|
||||
if ($('#bc_bg').val() !== 0) {
|
||||
data.glucose = $('#bc_bg').val().replace(',', '.');
|
||||
data.glucoseType = $('#boluscalc-form').find('input[name=bc_bginput]:checked').val();
|
||||
data.units = client.settings.units;
|
||||
}
|
||||
data.carbs = $('#bc_carbs').val().replace(',','.');
|
||||
data.carbs = $('#bc_carbs').val().replace(',', '.');
|
||||
data.insulin = $('#bc_insulintotal').text();
|
||||
if (data.insulin<=0) {
|
||||
if (data.insulin <= 0) {
|
||||
delete data.insulin;
|
||||
}
|
||||
data.preBolus = parseInt($('#bc_preBolus').val());
|
||||
@@ -503,7 +501,7 @@ function init(client, $) {
|
||||
return data;
|
||||
}
|
||||
|
||||
boluscalc.submit = function submit(event) {
|
||||
boluscalc.submit = function submit (event) {
|
||||
var data = gatherData();
|
||||
if (data) {
|
||||
confirmPost(data);
|
||||
@@ -512,9 +510,10 @@ function init(client, $) {
|
||||
return false;
|
||||
};
|
||||
|
||||
function buildConfirmText(data) {
|
||||
function buildConfirmText (data) {
|
||||
var text = [
|
||||
translate('Please verify that the data entered is correct') + ': '
|
||||
|
||||
, translate('Event Type') + ': ' + translate(data.eventType)
|
||||
];
|
||||
|
||||
@@ -538,11 +537,11 @@ function init(client, $) {
|
||||
return text.join('\n');
|
||||
}
|
||||
|
||||
function confirmPost(data) {
|
||||
function confirmPost (data) {
|
||||
if (window.confirm(buildConfirmText(data))) {
|
||||
$.ajax({
|
||||
method: 'POST',
|
||||
url: '/api/v1/treatments/'
|
||||
method: 'POST'
|
||||
, url: '/api/v1/treatments/'
|
||||
, headers: client.headers()
|
||||
, data: data
|
||||
}).done(function treatmentSaved (response) {
|
||||
@@ -560,33 +559,33 @@ function init(client, $) {
|
||||
}
|
||||
|
||||
// Food manipulation
|
||||
function deleteFoodRecord(event) {
|
||||
function deleteFoodRecord (event) {
|
||||
var index = $(this).attr('index');
|
||||
foods.splice(index,1);
|
||||
foods.splice(index, 1);
|
||||
$('#bc_carbs').val('');
|
||||
boluscalc.calculateInsulin();
|
||||
maybePrevent(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
function quickpickChange(event) {
|
||||
function quickpickChange (event) {
|
||||
var qpiselected = $('#bc_quickpick').val();
|
||||
|
||||
if (qpiselected === null || qpiselected === '-1') { // (none)
|
||||
$('#bc_carbs').val(0);
|
||||
foods = [];
|
||||
$('#bc_addfoodarea').css('display','');
|
||||
$('#bc_addfoodarea').css('display', '');
|
||||
} else {
|
||||
var qp = quickpicks[qpiselected];
|
||||
foods = _.cloneDeep(qp.foods);
|
||||
$('#bc_addfoodarea').css('display','none');
|
||||
$('#bc_addfoodarea').css('display', 'none');
|
||||
}
|
||||
|
||||
boluscalc.calculateInsulin();
|
||||
maybePrevent(event);
|
||||
}
|
||||
|
||||
function quickpickHideFood() {
|
||||
function quickpickHideFood () {
|
||||
var qpiselected = $('#bc_quickpick').val();
|
||||
|
||||
if (qpiselected >= 0) {
|
||||
@@ -618,11 +617,11 @@ function init(client, $) {
|
||||
, name: ''
|
||||
};
|
||||
|
||||
boluscalc.loadFoodDatabase = function loadFoodDatabase(event, callback) {
|
||||
boluscalc.loadFoodDatabase = function loadFoodDatabase (event, callback) {
|
||||
categories = [];
|
||||
foodlist = [];
|
||||
var records = client.sbx.data.food || [];
|
||||
records.forEach(function (r) {
|
||||
records.forEach(function(r) {
|
||||
if (r.type == 'food') {
|
||||
foodlist.push(r);
|
||||
if (r.category && !categories[r.category]) {
|
||||
@@ -640,77 +639,77 @@ function init(client, $) {
|
||||
if (callback) { callback(); }
|
||||
};
|
||||
|
||||
boluscalc.loadFoodQuickpicks = function loadFoodQuickpicks( ) {
|
||||
boluscalc.loadFoodQuickpicks = function loadFoodQuickpicks () {
|
||||
// Load quickpicks
|
||||
quickpicks = [];
|
||||
var records = client.sbx.data.food || [];
|
||||
records.forEach(function (r) {
|
||||
records.forEach(function(r) {
|
||||
if (r.type == 'quickpick') {
|
||||
quickpicks.push(r);
|
||||
}
|
||||
});
|
||||
$('#bc_quickpick').empty().append('<option value="-1">' + translate('(none)') + '</option>');
|
||||
for (var i=0; i<records.length; i++) {
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
var r = records[i];
|
||||
$('#bc_quickpick').append('<option value="' + i +'">' + r.name + ' (' + r.carbs + ' g)</option>');
|
||||
};
|
||||
$('#bc_quickpick').append('<option value="' + i + '">' + r.name + ' (' + r.carbs + ' g)</option>');
|
||||
}
|
||||
$('#bc_quickpick').val(-1);
|
||||
$('#bc_quickpick').change(quickpickChange);
|
||||
};
|
||||
|
||||
function fillForm(event) {
|
||||
function fillForm (event) {
|
||||
$('#bc_filter_category').empty().append('<option value="">' + translate('(none)') + '</option>');
|
||||
Object.keys(categories).forEach( function eachCategory(s) {
|
||||
$('#bc_filter_category').append('<option value="' + s +'">' + s + '</option>');
|
||||
Object.keys(categories).forEach(function eachCategory (s) {
|
||||
$('#bc_filter_category').append('<option value="' + s + '">' + s + '</option>');
|
||||
});
|
||||
filter.category = '';
|
||||
fillSubcategories();
|
||||
|
||||
$('#bc_filter_category').change(fillSubcategories);
|
||||
$('#bc_filter_subcategory').change(doFilter);
|
||||
$('#bc_filter_name').on('input',doFilter);
|
||||
$('#bc_filter_name').on('input', doFilter);
|
||||
|
||||
maybePrevent(event);
|
||||
return false;
|
||||
}
|
||||
|
||||
function fillSubcategories(event) {
|
||||
function fillSubcategories (event) {
|
||||
maybePrevent(event);
|
||||
filter.category = $('#bc_filter_category').val();
|
||||
filter.subcategory = '';
|
||||
$('#bc_filter_subcategory').empty().append('<option value="">' + translate('(none)') + '</option>');
|
||||
if (filter.category !== '') {
|
||||
Object.keys(categories[filter.category]).forEach( function eachSubcategory(s) {
|
||||
$('#bc_filter_subcategory').append('<option value="' + s +'">' + s + '</option>');
|
||||
Object.keys(categories[filter.category]).forEach(function eachSubcategory (s) {
|
||||
$('#bc_filter_subcategory').append('<option value="' + s + '">' + s + '</option>');
|
||||
});
|
||||
}
|
||||
doFilter();
|
||||
}
|
||||
|
||||
function doFilter(event) {
|
||||
function doFilter (event) {
|
||||
if (event) {
|
||||
filter.category = $('#bc_filter_category').val();
|
||||
filter.subcategory = $('#bc_filter_subcategory').val();
|
||||
filter.name = $('#bc_filter_name').val();
|
||||
}
|
||||
$('#bc_data').empty();
|
||||
for (var i=0; i<foodlist.length; i++) {
|
||||
for (var i = 0; i < foodlist.length; i++) {
|
||||
if (filter.category !== '' && foodlist[i].category !== filter.category) { continue; }
|
||||
if (filter.subcategory !== '' && foodlist[i].subcategory !== filter.subcategory) { continue; }
|
||||
if (filter.name!== '' && foodlist[i].name.toLowerCase().indexOf(filter.name.toLowerCase())<0) { continue; }
|
||||
if (filter.name !== '' && foodlist[i].name.toLowerCase().indexOf(filter.name.toLowerCase()) < 0) { continue; }
|
||||
var o = '';
|
||||
o += foodlist[i].name + ' | ';
|
||||
o += 'Portion: ' + foodlist[i].portion + ' ';
|
||||
o += foodlist[i].unit + ' | ';
|
||||
o += 'Carbs: ' + foodlist[i].carbs+' g';
|
||||
$('#bc_data').append('<option value="' + i +'">' + o + '</option>');
|
||||
o += 'Carbs: ' + foodlist[i].carbs + ' g';
|
||||
$('#bc_data').append('<option value="' + i + '">' + o + '</option>');
|
||||
}
|
||||
$('#bc_addportions').val('1');
|
||||
|
||||
maybePrevent(event);
|
||||
}
|
||||
|
||||
function addFoodFromDatabase(event) {
|
||||
function addFoodFromDatabase (event) {
|
||||
if (!databaseloaded) {
|
||||
boluscalc.loadFoodDatabase(event, addFoodFromDatabase);
|
||||
return;
|
||||
@@ -721,27 +720,29 @@ function init(client, $) {
|
||||
width: 640
|
||||
, height: 400
|
||||
, buttons: [
|
||||
{ text: translate('Add'),
|
||||
click: function() {
|
||||
{
|
||||
text: translate('Add')
|
||||
, click: function() {
|
||||
var index = $('#bc_data').val();
|
||||
var portions = parseFloat($('#bc_addportions').val().replace(',','.'));
|
||||
if (index !== null && !isNaN(portions) && portions >0) {
|
||||
var portions = parseFloat($('#bc_addportions').val().replace(',', '.'));
|
||||
if (index !== null && !isNaN(portions) && portions > 0) {
|
||||
foodlist[index].portions = portions;
|
||||
foods.push(_.cloneDeep(foodlist[index]));
|
||||
$( this ).dialog( 'close' );
|
||||
$(this).dialog('close');
|
||||
boluscalc.calculateInsulin();
|
||||
}
|
||||
}
|
||||
},
|
||||
{ text: translate('Reload database'),
|
||||
class: 'leftButton',
|
||||
click: boluscalc.loadFoodDatabase
|
||||
}
|
||||
, {
|
||||
text: translate('Reload database')
|
||||
, class: 'leftButton'
|
||||
, click: boluscalc.loadFoodDatabase
|
||||
}
|
||||
]
|
||||
, open : function() {
|
||||
, open: function() {
|
||||
$(this).parent().css('box-shadow', '20px 20px 20px 0px black');
|
||||
$(this).parent().find('.ui-dialog-buttonset' ).css({'width':'100%','text-align':'right'});
|
||||
$(this).parent().find('button:contains("'+translate('Add')+'")').css({'float':'left'});
|
||||
$(this).parent().find('.ui-dialog-buttonset').css({ 'width': '100%', 'text-align': 'right' });
|
||||
$(this).parent().find('button:contains("' + translate('Add') + '")').css({ 'float': 'left' });
|
||||
$('#bc_filter_name').focus();
|
||||
}
|
||||
|
||||
@@ -750,7 +751,7 @@ function init(client, $) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function findClosestSGVToPastTime(time) {
|
||||
function findClosestSGVToPastTime (time) {
|
||||
var nowData = client.entries.filter(function(d) {
|
||||
return d.type === 'sgv' && d.mills <= time.getTime();
|
||||
});
|
||||
@@ -766,12 +767,12 @@ function init(client, $) {
|
||||
// Make it faster on mobile devices
|
||||
$('.insulincalculationpart').change(boluscalc.calculateInsulin);
|
||||
} else {
|
||||
$('.insulincalculationpart').on('input',boluscalc.calculateInsulin);
|
||||
$('.insulincalculationpart').on('input', boluscalc.calculateInsulin);
|
||||
$('input:checkbox.insulincalculationpart').change(boluscalc.calculateInsulin);
|
||||
}
|
||||
$('#bc_bgfrommeter').change(boluscalc.calculateInsulin);
|
||||
$('#bc_addfromdatabase').click(addFoodFromDatabase);
|
||||
$('#bc_bgfromsensor').change(function bc_bgfromsensor_click(event) {
|
||||
$('#bc_bgfromsensor').change(function bc_bgfromsensor_click (event) {
|
||||
boluscalc.updateVisualisations(client.sbx);
|
||||
boluscalc.calculateInsulin();
|
||||
maybePrevent(event);
|
||||
|
||||
@@ -8,18 +8,18 @@ var Storages = require('js-storage');
|
||||
|
||||
function init (client, serverSettings, $) {
|
||||
|
||||
serverSettings = serverSettings || {settings: {}};
|
||||
serverSettings = serverSettings || { settings: {} };
|
||||
|
||||
var storage = Storages.localStorage;
|
||||
var settings = require('../settings')();
|
||||
|
||||
function loadForm ( ) {
|
||||
function loadForm () {
|
||||
var utils = client.utils;
|
||||
var language = require('../language')();
|
||||
language.set(settings.language);
|
||||
var translate = language.translate;
|
||||
|
||||
function appendThresholdValue(threshold) {
|
||||
function appendThresholdValue (threshold) {
|
||||
return settings.alarmTypes.indexOf('simple') === -1 ? '' : ' (' + utils.scaleMgdl(threshold) + ')';
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ function init (client, serverSettings, $) {
|
||||
|
||||
var langSelect = $('#language');
|
||||
|
||||
_.each(language.languages, function eachLanguage(lang) {
|
||||
langSelect.append('<option value="' + lang.code+ '">' + lang.language + '</option>');
|
||||
_.each(language.languages, function eachLanguage (lang) {
|
||||
langSelect.append('<option value="' + lang.code + '">' + lang.language + '</option>');
|
||||
});
|
||||
|
||||
langSelect.val(settings.language);
|
||||
@@ -79,7 +79,7 @@ function init (client, serverSettings, $) {
|
||||
|
||||
var showPluginsSettings = $('#show-plugins');
|
||||
var hasPluginsToShow = false;
|
||||
client.plugins.eachEnabledPlugin(function each(plugin) {
|
||||
client.plugins.eachEnabledPlugin(function each (plugin) {
|
||||
if (client.plugins.specialPlugins.indexOf(plugin.name) > -1) {
|
||||
//ignore these, they are always on for now
|
||||
} else {
|
||||
@@ -97,7 +97,7 @@ function init (client, serverSettings, $) {
|
||||
|
||||
}
|
||||
|
||||
function wireForm ( ) {
|
||||
function wireForm () {
|
||||
$('#useDefaults').click(function(event) {
|
||||
settings.eachSetting(function clearEachSetting (name) {
|
||||
storage.remove(name);
|
||||
@@ -108,43 +108,41 @@ function init (client, serverSettings, $) {
|
||||
});
|
||||
|
||||
$('#save').click(function(event) {
|
||||
function checkedPluginNames() {
|
||||
function checkedPluginNames () {
|
||||
var checkedPlugins = [];
|
||||
$('#show-plugins input:checked').each(function eachPluginCheckbox(index, checkbox) {
|
||||
$('#show-plugins input:checked').each(function eachPluginCheckbox (index, checkbox) {
|
||||
checkedPlugins.push($(checkbox).val());
|
||||
});
|
||||
return checkedPlugins.join(' ');
|
||||
}
|
||||
|
||||
function storeInBrowser(data) {
|
||||
for (var k in data) {
|
||||
if (data.hasOwnProperty(k)) {
|
||||
function storeInBrowser (data) {
|
||||
Object.keys(data).forEach(k => {
|
||||
storage.set(k, data[k]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
storeInBrowser({
|
||||
units: $('input:radio[name=units-browser]:checked').val(),
|
||||
alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked'),
|
||||
alarmHigh: $('#alarm-high-browser').prop('checked'),
|
||||
alarmLow: $('#alarm-low-browser').prop('checked'),
|
||||
alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked'),
|
||||
alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked'),
|
||||
alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15,
|
||||
alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked'),
|
||||
alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30,
|
||||
nightMode: $('#nightmode-browser').prop('checked'),
|
||||
editMode: $('#editmode-browser').prop('checked'),
|
||||
showRawbg: $('input:radio[name=show-rawbg]:checked').val(),
|
||||
customTitle: $('input#customTitle').prop('value'),
|
||||
theme: $('input:radio[name=theme-browser]:checked').val(),
|
||||
timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val()),
|
||||
language: $('#language').val(),
|
||||
scaleY: $('#scaleY').val(),
|
||||
basalrender: $('#basalrender').val(),
|
||||
showPlugins: checkedPluginNames(),
|
||||
storageVersion: STORAGE_VERSION
|
||||
units: $('input:radio[name=units-browser]:checked').val()
|
||||
, alarmUrgentHigh: $('#alarm-urgenthigh-browser').prop('checked')
|
||||
, alarmHigh: $('#alarm-high-browser').prop('checked')
|
||||
, alarmLow: $('#alarm-low-browser').prop('checked')
|
||||
, alarmUrgentLow: $('#alarm-urgentlow-browser').prop('checked')
|
||||
, alarmTimeagoWarn: $('#alarm-timeagowarn-browser').prop('checked')
|
||||
, alarmTimeagoWarnMins: parseInt($('#alarm-timeagowarnmins-browser').val()) || 15
|
||||
, alarmTimeagoUrgent: $('#alarm-timeagourgent-browser').prop('checked')
|
||||
, alarmTimeagoUrgentMins: parseInt($('#alarm-timeagourgentmins-browser').val()) || 30
|
||||
, nightMode: $('#nightmode-browser').prop('checked')
|
||||
, editMode: $('#editmode-browser').prop('checked')
|
||||
, showRawbg: $('input:radio[name=show-rawbg]:checked').val()
|
||||
, customTitle: $('input#customTitle').prop('value')
|
||||
, theme: $('input:radio[name=theme-browser]:checked').val()
|
||||
, timeFormat: parseInt($('input:radio[name=timeformat-browser]:checked').val())
|
||||
, language: $('#language').val()
|
||||
, scaleY: $('#scaleY').val()
|
||||
, basalrender: $('#basalrender').val()
|
||||
, showPlugins: checkedPluginNames()
|
||||
, storageVersion: STORAGE_VERSION
|
||||
});
|
||||
|
||||
event.preventDefault();
|
||||
@@ -152,13 +150,13 @@ function init (client, serverSettings, $) {
|
||||
});
|
||||
}
|
||||
|
||||
function showLocalstorageError ( ) {
|
||||
function showLocalstorageError () {
|
||||
var msg = '<b>Settings are disabled.</b><br /><br />Please enable cookies so you may customize your Nightscout site.';
|
||||
$('.browserSettings').html('<legend>Settings</legend>'+msg+'');
|
||||
$('.browserSettings').html('<legend>Settings</legend>' + msg + '');
|
||||
$('#save').hide();
|
||||
}
|
||||
|
||||
function handleStorageVersions ( ) {
|
||||
function handleStorageVersions () {
|
||||
var previousVersion = parseInt(storage.get('storageVersion'));
|
||||
|
||||
//un-versioned settings
|
||||
@@ -174,7 +172,7 @@ function init (client, serverSettings, $) {
|
||||
}
|
||||
}
|
||||
|
||||
settings.extendedSettings = serverSettings.extendedSettings || {settings: {}};
|
||||
settings.extendedSettings = serverSettings.extendedSettings || { settings: {} };
|
||||
|
||||
try {
|
||||
settings.eachSetting(function setEach (name) {
|
||||
@@ -200,12 +198,12 @@ function init (client, serverSettings, $) {
|
||||
|
||||
var stored = storage.get('basalrender');
|
||||
settings.extendedSettings.basal.render = stored !== null ? stored : settings.extendedSettings.basal.render;
|
||||
} catch(err) {
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
showLocalstorageError();
|
||||
}
|
||||
|
||||
init.loadAndWireForm = function loadAndWireForm ( ) {
|
||||
init.loadAndWireForm = function loadAndWireForm () {
|
||||
loadForm();
|
||||
wireForm();
|
||||
};
|
||||
@@ -213,5 +211,4 @@ function init (client, serverSettings, $) {
|
||||
return settings;
|
||||
}
|
||||
|
||||
|
||||
module.exports = init;
|
||||
|
||||
+19
-21
@@ -13,9 +13,9 @@ function init ($) {
|
||||
$('#drawer').find('.tip').tooltip();
|
||||
}
|
||||
$.fn.tooltip.defaults = {
|
||||
fade: true,
|
||||
gravity: 'n',
|
||||
opacity: 0.75
|
||||
fade: true
|
||||
, gravity: 'n'
|
||||
, opacity: 0.75
|
||||
};
|
||||
|
||||
var querystring = queryParms();
|
||||
@@ -38,31 +38,30 @@ function init ($) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
$('.navigation a').click(function navigationClick ( ) {
|
||||
$('.navigation a').click(function navigationClick () {
|
||||
closeDrawer('#drawer');
|
||||
});
|
||||
|
||||
function reload() {
|
||||
function reload () {
|
||||
//strip '#' so form submission does not fail
|
||||
var url = window.location.href;
|
||||
url = url.replace(/#$/, '');
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
|
||||
function queryParms() {
|
||||
function queryParms () {
|
||||
var params = {};
|
||||
if (location.search) {
|
||||
location.search.substr(1).split('&').forEach(function(item) {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
params[item.split('=')[0]] = item.split('=')[1].replace(/[_\+]/g, ' ');
|
||||
});
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function isTouch() {
|
||||
try { document.createEvent('TouchEvent'); return true; }
|
||||
catch (e) { return false; }
|
||||
function isTouch () {
|
||||
try { document.createEvent('TouchEvent'); return true; } catch (e) { return false; }
|
||||
}
|
||||
|
||||
function closeLastOpenedDrawer (callback) {
|
||||
@@ -73,15 +72,15 @@ function init ($) {
|
||||
}
|
||||
}
|
||||
|
||||
function closeDrawer(id, callback) {
|
||||
function closeDrawer (id, callback) {
|
||||
lastOpenedDrawer = null;
|
||||
$('html, body').css({ scrollTop: 0 });
|
||||
$(id).css({display: 'none', right: '-300px'});
|
||||
$(id).css({ display: 'none', right: '-300px' });
|
||||
if (callback) { callback(); }
|
||||
}
|
||||
|
||||
function openDrawer(id, prepare) {
|
||||
function closeOpenDraw(callback) {
|
||||
function openDrawer (id, prepare) {
|
||||
function closeOpenDraw (callback) {
|
||||
if (lastOpenedDrawer) {
|
||||
closeDrawer(lastOpenedDrawer, callback);
|
||||
} else {
|
||||
@@ -89,11 +88,11 @@ function init ($) {
|
||||
}
|
||||
}
|
||||
|
||||
closeOpenDraw(function () {
|
||||
closeOpenDraw(function() {
|
||||
lastOpenedDrawer = id;
|
||||
if (prepare) { prepare(); }
|
||||
|
||||
var style = {display:'block', right: '0'};
|
||||
var style = { display: 'block', right: '0' };
|
||||
|
||||
var windowWidth = $(window).width();
|
||||
var windowHeight = $(window).height();
|
||||
@@ -114,13 +113,12 @@ function init ($) {
|
||||
style.width = '350px';
|
||||
}
|
||||
|
||||
|
||||
$(id).css(style);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function toggleDrawer(id, openPrepare, closeCallback) {
|
||||
function toggleDrawer (id, openPrepare, closeCallback) {
|
||||
if (lastOpenedDrawer === id) {
|
||||
closeDrawer(id, closeCallback);
|
||||
} else {
|
||||
@@ -128,13 +126,13 @@ function init ($) {
|
||||
}
|
||||
}
|
||||
|
||||
function closeNotification() {
|
||||
function closeNotification () {
|
||||
var notify = $('#notification');
|
||||
notify.hide();
|
||||
notify.find('span').html('');
|
||||
}
|
||||
|
||||
function showNotification(note, type) {
|
||||
function showNotification (note, type) {
|
||||
var notify = $('#notification');
|
||||
notify.hide();
|
||||
|
||||
@@ -150,7 +148,7 @@ function init ($) {
|
||||
notify.show();
|
||||
}
|
||||
|
||||
function getLastOpenedDrawer() {
|
||||
function getLastOpenedDrawer () {
|
||||
return lastOpenedDrawer;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ client.settings = browserSettings(client, window.serverSettings, $);
|
||||
// console.log('settings', client.settings);
|
||||
// client.settings now contains all settings
|
||||
|
||||
client.query = function query() {
|
||||
client.query = function query () {
|
||||
console.log('query');
|
||||
$.ajax('/api/v1/entries.json?count=3', {
|
||||
success: client.render
|
||||
});
|
||||
}
|
||||
|
||||
client.render = function render(xhr) {
|
||||
client.render = function render (xhr) {
|
||||
console.log('got data', xhr);
|
||||
|
||||
let rec;
|
||||
@@ -33,9 +33,9 @@ client.render = function render(xhr) {
|
||||
|
||||
// Convert BG to mmol/L if necessary.
|
||||
if (window.serverSettings.settings.units == 'mmol') {
|
||||
var displayValue = Nightscout.units.mgdlToMMOL(rec.sgv);
|
||||
var displayValue = window.Nightscout.units.mgdlToMMOL(rec.sgv);
|
||||
} else {
|
||||
var displayValue = rec.sgv;
|
||||
displayValue = rec.sgv;
|
||||
}
|
||||
|
||||
// Insert the BG value text.
|
||||
@@ -53,8 +53,8 @@ client.render = function render(xhr) {
|
||||
|
||||
// Generate and insert the clock.
|
||||
let timeDivisor = (client.settings.timeFormat) ? client.settings.timeFormat : 12;
|
||||
let today = new Date(),
|
||||
h = today.getHours() % timeDivisor;
|
||||
let today = new Date()
|
||||
, h = today.getHours() % timeDivisor;
|
||||
if (timeDivisor == 12) {
|
||||
h = (h == 0) ? 12 : h; // In the case of 00:xx, change to 12:xx for 12h time
|
||||
}
|
||||
@@ -65,6 +65,8 @@ client.render = function render(xhr) {
|
||||
if (m < 10) m = "0" + m;
|
||||
$('#clock').text(h + ":" + m);
|
||||
|
||||
// defined in the template this is loaded into
|
||||
// eslint-disable-next-line no-undef
|
||||
if (clockFace == 'clock-color') {
|
||||
|
||||
var bgHigh = window.serverSettings.settings.thresholds.bgHigh;
|
||||
@@ -115,7 +117,7 @@ client.render = function render(xhr) {
|
||||
}
|
||||
}
|
||||
|
||||
client.init = function init() {
|
||||
client.init = function init () {
|
||||
console.log('init');
|
||||
client.query();
|
||||
setInterval(client.query, 1 * 60 * 1000);
|
||||
|
||||
+94
-99
@@ -16,13 +16,13 @@ var levels = require('../levels');
|
||||
var times = require('../times');
|
||||
var receiveDData = require('./receiveddata');
|
||||
|
||||
var client = { };
|
||||
var client = {};
|
||||
|
||||
$('#loadingMessageText').html('Connecting to server');
|
||||
|
||||
client.hashauth = require('../hashauth').init(client, $);
|
||||
|
||||
client.headers = function headers ( ) {
|
||||
client.headers = function headers () {
|
||||
if (client.authorized) {
|
||||
return {
|
||||
Authorization: 'Bearer ' + client.authorized.token
|
||||
@@ -32,11 +32,11 @@ client.headers = function headers ( ) {
|
||||
'api-secret': client.hashauth.hash()
|
||||
};
|
||||
} else {
|
||||
return { };
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
client.init = function init(callback) {
|
||||
client.init = function init (callback) {
|
||||
|
||||
client.browserUtils = require('./browser-utils')($);
|
||||
|
||||
@@ -60,7 +60,8 @@ client.init = function init(callback) {
|
||||
console.log('Application appears to be online');
|
||||
$('#centerMessagePanel').hide();
|
||||
client.load(serverSettings, callback);
|
||||
}).fail(function fail(jqXHR, textStatus, errorThrown) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
}).fail(function fail (jqXHR, textStatus, errorThrown) {
|
||||
|
||||
// check if we couldn't reach the server at all, show offline message
|
||||
if (jqXHR.readyState == 0) {
|
||||
@@ -79,7 +80,7 @@ client.init = function init(callback) {
|
||||
client.translate = language.translate;
|
||||
// auth failed, hide loader and request for key
|
||||
$('#centerMessagePanel').hide();
|
||||
client.hashauth.requestAuthentication(function afterRequest ( ) {
|
||||
client.hashauth.requestAuthentication(function afterRequest () {
|
||||
client.init(null, callback);
|
||||
});
|
||||
}
|
||||
@@ -87,23 +88,21 @@ client.init = function init(callback) {
|
||||
|
||||
};
|
||||
|
||||
client.load = function load(serverSettings, callback) {
|
||||
client.load = function load (serverSettings, callback) {
|
||||
|
||||
var UPDATE_TRANS_MS = 750 // milliseconds
|
||||
, FORMAT_TIME_12 = '%-I:%M %p'
|
||||
, FORMAT_TIME_12_COMPACT = '%-I:%M'
|
||||
, FORMAT_TIME_24 = '%H:%M%'
|
||||
, FORMAT_TIME_12_SCALE = '%-I %p'
|
||||
, FORMAT_TIME_24_SCALE = '%H'
|
||||
;
|
||||
, FORMAT_TIME_24_SCALE = '%H';
|
||||
|
||||
var history = 48;
|
||||
|
||||
var chart
|
||||
, socket
|
||||
, isInitialData = false
|
||||
, prevSGV
|
||||
, opacity = {current: 1, DAY: 1, NIGHT: 0.5}
|
||||
, opacity = { current: 1, DAY: 1, NIGHT: 0.5 }
|
||||
, clientAlarms = {}
|
||||
, alarmInProgress = false
|
||||
, alarmMessage
|
||||
@@ -111,8 +110,7 @@ client.load = function load(serverSettings, callback) {
|
||||
, currentAnnouncement
|
||||
, alarmSound = 'alarm.mp3'
|
||||
, urgentAlarmSound = 'alarm2.mp3'
|
||||
, previousNotifyTimestamp
|
||||
;
|
||||
, previousNotifyTimestamp;
|
||||
|
||||
client.entryToDate = function entryToDate (entry) { return new Date(entry.mills); };
|
||||
|
||||
@@ -130,8 +128,7 @@ client.load = function load(serverSettings, callback) {
|
||||
, minorPills = $('.bgStatus .minorPills')
|
||||
, statusPills = $('.status .statusPills')
|
||||
, primary = $('.primary')
|
||||
, editButton = $('#editbutton')
|
||||
;
|
||||
, editButton = $('#editbutton');
|
||||
|
||||
client.tooltip = d3.select('body').append('div')
|
||||
.attr('class', 'tooltip')
|
||||
@@ -248,13 +245,13 @@ client.load = function load(serverSettings, callback) {
|
||||
//start the bus after setting up listeners
|
||||
//client.ctx.bus.uptime( );
|
||||
|
||||
client.dataExtent = function dataExtent ( ) {
|
||||
client.dataExtent = function dataExtent () {
|
||||
return client.entries.length > 0 ?
|
||||
d3.extent(client.entries, client.entryToDate)
|
||||
: d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]);
|
||||
d3.extent(client.entries, client.entryToDate) :
|
||||
d3.extent([new Date(client.now - times.hours(history).msecs), new Date(client.now)]);
|
||||
};
|
||||
|
||||
client.bottomOfPills = function bottomOfPills ( ) {
|
||||
client.bottomOfPills = function bottomOfPills () {
|
||||
//the offset's might not exist for some tests
|
||||
var bottomOfPrimary = primary.offset() ? primary.offset().top + primary.height() : 0;
|
||||
var bottomOfMinorPills = minorPills.offset() ? minorPills.offset().top + minorPills.height() : 0;
|
||||
@@ -262,7 +259,7 @@ client.load = function load(serverSettings, callback) {
|
||||
return Math.max(bottomOfPrimary, bottomOfMinorPills, bottomOfStatusPills);
|
||||
};
|
||||
|
||||
function formatTime(time, compact) {
|
||||
function formatTime (time, compact) {
|
||||
var timeFormat = getTimeFormat(false, compact);
|
||||
time = d3.time.format(timeFormat)(time);
|
||||
if (client.settings.timeFormat !== 24) {
|
||||
@@ -271,7 +268,7 @@ client.load = function load(serverSettings, callback) {
|
||||
return time;
|
||||
}
|
||||
|
||||
function getTimeFormat(isForScale, compact) {
|
||||
function getTimeFormat (isForScale, compact) {
|
||||
var timeFormat = FORMAT_TIME_12;
|
||||
if (client.settings.timeFormat === 24) {
|
||||
timeFormat = isForScale ? FORMAT_TIME_24_SCALE : FORMAT_TIME_24;
|
||||
@@ -283,7 +280,7 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
|
||||
//TODO: replace with utils.scaleMgdl and/or utils.roundBGForDisplay
|
||||
function scaleBg(bg) {
|
||||
function scaleBg (bg) {
|
||||
if (client.settings.units === 'mmol') {
|
||||
return units.mgdlToMMOL(bg);
|
||||
} else {
|
||||
@@ -291,8 +288,8 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function generateTitle ( ) {
|
||||
function s(value, sep) { return value ? value + ' ' : sep || ''; }
|
||||
function generateTitle () {
|
||||
function s (value, sep) { return value ? value + ' ' : sep || ''; }
|
||||
|
||||
var title = '';
|
||||
|
||||
@@ -317,12 +314,12 @@ client.load = function load(serverSettings, callback) {
|
||||
return title;
|
||||
}
|
||||
|
||||
function resetCustomTitle ( ) {
|
||||
function resetCustomTitle () {
|
||||
var customTitle = client.settings.customTitle || 'Nightscout';
|
||||
$('.customTitle').text(customTitle);
|
||||
}
|
||||
|
||||
function checkAnnouncement() {
|
||||
function checkAnnouncement () {
|
||||
var result = {
|
||||
inProgress: currentAnnouncement ? Date.now() - currentAnnouncement.received < times.mins(5).msecs : false
|
||||
};
|
||||
@@ -339,14 +336,14 @@ client.load = function load(serverSettings, callback) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateTitle ( ) {
|
||||
function updateTitle () {
|
||||
|
||||
var windowTitle;
|
||||
var announcementStatus = checkAnnouncement();
|
||||
|
||||
if (alarmMessage && alarmInProgress) {
|
||||
$('.customTitle').text(alarmMessage);
|
||||
if (!isTimeAgoAlarmType( )) {
|
||||
if (!isTimeAgoAlarmType()) {
|
||||
windowTitle = alarmMessage + ': ' + generateTitle();
|
||||
}
|
||||
} else if (announcementStatus.inProgress && announcementStatus.message) {
|
||||
@@ -360,8 +357,8 @@ client.load = function load(serverSettings, callback) {
|
||||
$(document).attr('title', windowTitle || generateTitle());
|
||||
}
|
||||
|
||||
// clears the current user brush and resets to the current real time data
|
||||
function updateBrushToNow(skipBrushing) {
|
||||
// clears the current user brush and resets to the current real time data
|
||||
function updateBrushToNow (skipBrushing) {
|
||||
|
||||
// get current time range
|
||||
var dataRange = client.dataExtent();
|
||||
@@ -377,15 +374,15 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function alarmingNow() {
|
||||
function alarmingNow () {
|
||||
return container.hasClass('alarming');
|
||||
}
|
||||
|
||||
function inRetroMode() {
|
||||
function inRetroMode () {
|
||||
return chart && chart.inRetroMode();
|
||||
}
|
||||
|
||||
function brushed ( ) {
|
||||
function brushed () {
|
||||
|
||||
var brushExtent = chart.brush.extent();
|
||||
|
||||
@@ -403,7 +400,7 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function adjustCurrentSGVClasses(value, isCurrent) {
|
||||
function adjustCurrentSGVClasses (value, isCurrent) {
|
||||
var reallyCurrentAndNotAlarming = isCurrent && !inRetroMode() && !alarmingNow();
|
||||
|
||||
bgStatus.toggleClass('current', alarmingNow() || reallyCurrentAndNotAlarming);
|
||||
@@ -469,7 +466,7 @@ client.load = function load(serverSettings, callback) {
|
||||
forecastOption.append(forecastLabel);
|
||||
forecastLabel.append(forecastCheckbox);
|
||||
forecastLabel.append('<span>Show ' + info.label + '</span>');
|
||||
forecastCheckbox.change(function onChange(event) {
|
||||
forecastCheckbox.change(function onChange (event) {
|
||||
var checkbox = $(event.target);
|
||||
var type = checkbox.attr('data-forecast-type');
|
||||
var checked = checkbox.prop('checked');
|
||||
@@ -477,7 +474,7 @@ client.load = function load(serverSettings, callback) {
|
||||
client.settings.showForecast += ' ' + type;
|
||||
} else {
|
||||
client.settings.showForecast = _.chain(client.settings.showForecast.split(' '))
|
||||
.filter(function (forecast) { return forecast !== type; })
|
||||
.filter(function(forecast) { return forecast !== type; })
|
||||
.value()
|
||||
.join(' ');
|
||||
}
|
||||
@@ -491,7 +488,7 @@ client.load = function load(serverSettings, callback) {
|
||||
client.boluscalc.updateVisualisations(client.sbx);
|
||||
}
|
||||
|
||||
function clearCurrentSGV ( ) {
|
||||
function clearCurrentSGV () {
|
||||
currentBG.text('---');
|
||||
container.removeClass('urgent warning inrange');
|
||||
}
|
||||
@@ -502,7 +499,7 @@ client.load = function load(serverSettings, callback) {
|
||||
});
|
||||
var focusPoint = _.last(nowData);
|
||||
|
||||
function updateHeader() {
|
||||
function updateHeader () {
|
||||
if (inRetroMode()) {
|
||||
nowDate = brushExtent[1];
|
||||
$('#currentTime')
|
||||
@@ -533,10 +530,10 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
|
||||
var top = (client.bottomOfPills() + 5);
|
||||
$('#chartContainer').css({top: top + 'px', height: $(window).height() - top - 10});
|
||||
$('#chartContainer').css({ top: top + 'px', height: $(window).height() - top - 10 });
|
||||
}
|
||||
|
||||
function sgvToColor(sgv) {
|
||||
function sgvToColor (sgv) {
|
||||
var color = 'grey';
|
||||
|
||||
if (client.settings.theme !== 'default') {
|
||||
@@ -556,7 +553,7 @@ client.load = function load(serverSettings, callback) {
|
||||
return color;
|
||||
}
|
||||
|
||||
function sgvToColoredRange(sgv) {
|
||||
function sgvToColoredRange (sgv) {
|
||||
var range = '';
|
||||
|
||||
if (client.settings.theme !== 'default') {
|
||||
@@ -576,7 +573,7 @@ client.load = function load(serverSettings, callback) {
|
||||
return range;
|
||||
}
|
||||
|
||||
function formatAlarmMessage(notify) {
|
||||
function formatAlarmMessage (notify) {
|
||||
var announcementMessage = notify && notify.isAnnouncement && notify.message && notify.message.length > 1;
|
||||
|
||||
if (announcementMessage) {
|
||||
@@ -599,7 +596,7 @@ client.load = function load(serverSettings, callback) {
|
||||
var selector = '.audio.alarms audio.' + file;
|
||||
|
||||
if (!alarmingNow()) {
|
||||
d3.select(selector).each(function () {
|
||||
d3.select(selector).each(function() {
|
||||
var audio = this;
|
||||
playAlarm(audio);
|
||||
$(this).addClass('playing');
|
||||
@@ -628,7 +625,7 @@ client.load = function load(serverSettings, callback) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function playAlarm(audio) {
|
||||
function playAlarm (audio) {
|
||||
// ?mute=true disables alarms to testers.
|
||||
if (client.browserUtils.queryParms().mute !== 'true') {
|
||||
audio.play();
|
||||
@@ -637,11 +634,11 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function stopAlarm(isClient, silenceTime, notify) {
|
||||
function stopAlarm (isClient, silenceTime, notify) {
|
||||
alarmInProgress = false;
|
||||
alarmMessage = null;
|
||||
container.removeClass('urgent warning');
|
||||
d3.selectAll('audio.playing').each(function () {
|
||||
d3.selectAll('audio.playing').each(function() {
|
||||
var audio = this;
|
||||
audio.pause();
|
||||
$(this).removeClass('playing');
|
||||
@@ -688,7 +685,7 @@ client.load = function load(serverSettings, callback) {
|
||||
brushed();
|
||||
}
|
||||
|
||||
function refreshAuthIfNeeded ( ) {
|
||||
function refreshAuthIfNeeded () {
|
||||
var token = client.browserUtils.queryParms().token;
|
||||
if (token && client.authorized) {
|
||||
var renewTime = (client.authorized.exp * 1000) - times.mins(15).msecs - Math.abs((client.authorized.iat * 1000) - client.authorized.lat);
|
||||
@@ -696,7 +693,7 @@ client.load = function load(serverSettings, callback) {
|
||||
if (client.now > renewTime) {
|
||||
console.info('Refreshing authorization');
|
||||
$.ajax('/api/v2/authorization/request/' + token, {
|
||||
success: function (authorized) {
|
||||
success: function(authorized) {
|
||||
if (authorized) {
|
||||
console.info('Got new authorization', authorized);
|
||||
authorized.lat = client.now;
|
||||
@@ -710,10 +707,10 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateClock() {
|
||||
function updateClock () {
|
||||
updateClockDisplay();
|
||||
var interval = (60 - (new Date()).getSeconds()) * 1000 + 5;
|
||||
setTimeout(updateClock,interval);
|
||||
setTimeout(updateClock, interval);
|
||||
|
||||
updateTimeAgo();
|
||||
if (chart) {
|
||||
@@ -735,7 +732,7 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
function updateClockDisplay() {
|
||||
function updateClockDisplay () {
|
||||
if (inRetroMode()) {
|
||||
return;
|
||||
}
|
||||
@@ -743,7 +740,7 @@ client.load = function load(serverSettings, callback) {
|
||||
$('#currentTime').text(formatTime(new Date(client.now), true)).css('text-decoration', '');
|
||||
}
|
||||
|
||||
function getClientAlarm(level, group) {
|
||||
function getClientAlarm (level, group) {
|
||||
var key = level + '-' + group;
|
||||
var alarm = clientAlarms[key];
|
||||
if (!alarm) {
|
||||
@@ -753,13 +750,13 @@ client.load = function load(serverSettings, callback) {
|
||||
return alarm;
|
||||
}
|
||||
|
||||
function isTimeAgoAlarmType() {
|
||||
function isTimeAgoAlarmType () {
|
||||
return currentNotify && currentNotify.group === 'Time Ago';
|
||||
}
|
||||
|
||||
function isStale (status) {
|
||||
return client.settings.alarmTimeagoWarn && status === 'warn'
|
||||
|| client.settings.alarmTimeagoUrgent && status === 'urgent';
|
||||
return client.settings.alarmTimeagoWarn && status === 'warn' ||
|
||||
client.settings.alarmTimeagoUrgent && status === 'urgent';
|
||||
}
|
||||
|
||||
function notAcked (alarm) {
|
||||
@@ -786,12 +783,12 @@ client.load = function load(serverSettings, callback) {
|
||||
|
||||
container.toggleClass('alarming-timeago', status !== 'current');
|
||||
|
||||
if (alarmingNow() && status === 'current' && isTimeAgoAlarmType( )) {
|
||||
if (alarmingNow() && status === 'current' && isTimeAgoAlarmType()) {
|
||||
stopAlarm(true, times.min().msecs);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTimeAgo() {
|
||||
function updateTimeAgo () {
|
||||
var status = client.timeago.checkStatus(client.sbx);
|
||||
if (status !== 'current') {
|
||||
updateTitle();
|
||||
@@ -799,20 +796,20 @@ client.load = function load(serverSettings, callback) {
|
||||
checkTimeAgoAlarm(status);
|
||||
}
|
||||
|
||||
function updateTimeAgoSoon() {
|
||||
setTimeout(function updatingTimeAgoNow() {
|
||||
function updateTimeAgoSoon () {
|
||||
setTimeout(function updatingTimeAgoNow () {
|
||||
updateTimeAgo();
|
||||
}, times.secs(10).msecs);
|
||||
}
|
||||
|
||||
function refreshChart(updateToNow) {
|
||||
function refreshChart (updateToNow) {
|
||||
if (updateToNow) {
|
||||
updateBrushToNow();
|
||||
}
|
||||
chart.update(false);
|
||||
}
|
||||
|
||||
(function watchVisibility ( ) {
|
||||
(function watchVisibility () {
|
||||
// Set the name of the hidden property and the change event for visibility
|
||||
var hidden, visibilityChange;
|
||||
if (typeof document.hidden !== 'undefined') {
|
||||
@@ -829,7 +826,7 @@ client.load = function load(serverSettings, callback) {
|
||||
visibilityChange = 'webkitvisibilitychange';
|
||||
}
|
||||
|
||||
document.addEventListener(visibilityChange, function visibilityChanged ( ) {
|
||||
document.addEventListener(visibilityChange, function visibilityChanged () {
|
||||
var prevHidden = client.documentHidden;
|
||||
client.documentHidden = document[hidden];
|
||||
|
||||
@@ -845,7 +842,7 @@ client.load = function load(serverSettings, callback) {
|
||||
updateClock();
|
||||
updateTimeAgoSoon();
|
||||
|
||||
function Dropdown(el) {
|
||||
function Dropdown (el) {
|
||||
this.ddmenuitem = 0;
|
||||
|
||||
this.$el = $(el);
|
||||
@@ -853,13 +850,13 @@ client.load = function load(serverSettings, callback) {
|
||||
|
||||
$(document).click(function() { that.close(); });
|
||||
}
|
||||
Dropdown.prototype.close = function () {
|
||||
Dropdown.prototype.close = function() {
|
||||
if (this.ddmenuitem) {
|
||||
this.ddmenuitem.css('visibility', 'hidden');
|
||||
this.ddmenuitem = 0;
|
||||
}
|
||||
};
|
||||
Dropdown.prototype.open = function (e) {
|
||||
Dropdown.prototype.open = function(e) {
|
||||
this.close();
|
||||
this.ddmenuitem = $(this.$el).css('visibility', 'visible');
|
||||
e.stopPropagation();
|
||||
@@ -868,7 +865,7 @@ client.load = function load(serverSettings, callback) {
|
||||
var silenceDropdown = new Dropdown('#silenceBtn');
|
||||
var viewDropdown = new Dropdown('#viewMenu');
|
||||
|
||||
$('.bgButton').click(function (e) {
|
||||
$('.bgButton').click(function(e) {
|
||||
if (alarmingNow()) {
|
||||
silenceDropdown.open(e);
|
||||
}
|
||||
@@ -888,22 +885,22 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Client-side code to connect to server and handle incoming data
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// eslint-disable-next-line no-undef
|
||||
client.socket = socket = io.connect();
|
||||
|
||||
socket.on('dataUpdate', dataUpdate);
|
||||
|
||||
function resetRetro ( ) {
|
||||
function resetRetro () {
|
||||
client.retro = {
|
||||
loadedMills: 0
|
||||
, loadStartedMills: 0
|
||||
};
|
||||
}
|
||||
|
||||
client.resetRetroIfNeeded = function resetRetroIfNeeded ( ) {
|
||||
client.resetRetroIfNeeded = function resetRetroIfNeeded () {
|
||||
if (client.retro.loadedMills > 0 && Date.now() - client.retro.loadedMills > times.mins(5).msecs) {
|
||||
resetRetro();
|
||||
console.info('Cleared retro data to free memory');
|
||||
@@ -912,7 +909,7 @@ client.load = function load(serverSettings, callback) {
|
||||
|
||||
resetRetro();
|
||||
|
||||
client.loadRetroIfNeeded = function loadRetroIfNeeded ( ) {
|
||||
client.loadRetroIfNeeded = function loadRetroIfNeeded () {
|
||||
var now = Date.now();
|
||||
if (now - client.retro.loadStartedMills < times.secs(30).msecs) {
|
||||
console.info('retro already loading, started', new Date(client.retro.loadStartedMills));
|
||||
@@ -940,7 +937,7 @@ client.load = function load(serverSettings, callback) {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Alarms and Text handling
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
socket.on('connect', function () {
|
||||
socket.on('connect', function() {
|
||||
console.log('Client connected to server.');
|
||||
socket.emit(
|
||||
'authorize'
|
||||
@@ -950,10 +947,10 @@ client.load = function load(serverSettings, callback) {
|
||||
, token: client.authorized && client.authorized.token
|
||||
, history: history
|
||||
}
|
||||
, function authCallback(data) {
|
||||
console.log('Client rights: ',data);
|
||||
, function authCallback (data) {
|
||||
console.log('Client rights: ', data);
|
||||
if (!data.read || !hasRequiredPermission()) {
|
||||
client.hashauth.requestAuthentication(function afterRequest ( ) {
|
||||
client.hashauth.requestAuthentication(function afterRequest () {
|
||||
client.hashauth.updateSocketAuth();
|
||||
if (callback) {
|
||||
callback();
|
||||
@@ -966,7 +963,7 @@ client.load = function load(serverSettings, callback) {
|
||||
);
|
||||
});
|
||||
|
||||
function hasRequiredPermission ( ) {
|
||||
function hasRequiredPermission () {
|
||||
if (client.requiredPermission) {
|
||||
if (client.hashauth && client.hashauth.isAuthenticated()) {
|
||||
return true;
|
||||
@@ -980,21 +977,20 @@ client.load = function load(serverSettings, callback) {
|
||||
|
||||
//with predicted alarms, latestSGV may still be in target so to see if the alarm
|
||||
// is for a HIGH we can only check if it's >= the bottom of the target
|
||||
function isAlarmForHigh() {
|
||||
function isAlarmForHigh () {
|
||||
return client.latestSGV && client.latestSGV.mgdl >= client.settings.thresholds.bgTargetBottom;
|
||||
}
|
||||
|
||||
//with predicted alarms, latestSGV may still be in target so to see if the alarm
|
||||
// is for a LOW we can only check if it's <= the top of the target
|
||||
function isAlarmForLow() {
|
||||
function isAlarmForLow () {
|
||||
return client.latestSGV && client.latestSGV.mgdl <= client.settings.thresholds.bgTargetTop;
|
||||
}
|
||||
|
||||
socket.on('notification', function (notify) {
|
||||
console.log('notification from server:',notify);
|
||||
socket.on('notification', function(notify) {
|
||||
console.log('notification from server:', notify);
|
||||
|
||||
if (notify.timestamp && previousNotifyTimestamp != notify.timestamp)
|
||||
{
|
||||
if (notify.timestamp && previousNotifyTimestamp != notify.timestamp) {
|
||||
previousNotifyTimestamp = notify.timestamp;
|
||||
client.plugins.visualizeAlarm(client.sbx, notify, notify.title + ' ' + notify.message);
|
||||
} else {
|
||||
@@ -1002,17 +998,17 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('announcement', function (notify) {
|
||||
socket.on('announcement', function(notify) {
|
||||
console.info('announcement received from server');
|
||||
console.log('notify:',notify);
|
||||
console.log('notify:', notify);
|
||||
currentAnnouncement = notify;
|
||||
currentAnnouncement.received = Date.now();
|
||||
updateTitle();
|
||||
});
|
||||
|
||||
socket.on('alarm', function (notify) {
|
||||
socket.on('alarm', function(notify) {
|
||||
console.info('alarm received from server');
|
||||
console.log('notify:',notify);
|
||||
console.log('notify:', notify);
|
||||
var enabled = (isAlarmForHigh() && client.settings.alarmHigh) || (isAlarmForLow() && client.settings.alarmLow);
|
||||
if (enabled) {
|
||||
console.log('Alarm raised!');
|
||||
@@ -1023,9 +1019,9 @@ client.load = function load(serverSettings, callback) {
|
||||
chart.update(false);
|
||||
});
|
||||
|
||||
socket.on('urgent_alarm', function (notify) {
|
||||
socket.on('urgent_alarm', function(notify) {
|
||||
console.info('urgent alarm received from server');
|
||||
console.log('notify:',notify);
|
||||
console.log('notify:', notify);
|
||||
|
||||
var enabled = (isAlarmForHigh() && client.settings.alarmUrgentHigh) || (isAlarmForLow() && client.settings.alarmUrgentLow);
|
||||
if (enabled) {
|
||||
@@ -1037,7 +1033,7 @@ client.load = function load(serverSettings, callback) {
|
||||
chart.update(false);
|
||||
});
|
||||
|
||||
socket.on('clear_alarm', function (notify) {
|
||||
socket.on('clear_alarm', function(notify) {
|
||||
console.info('got clear_alarm', notify);
|
||||
if (alarmInProgress) {
|
||||
console.log('clearing alarm');
|
||||
@@ -1054,7 +1050,7 @@ client.load = function load(serverSettings, callback) {
|
||||
window.speechSynthesis.speak(msg);
|
||||
}
|
||||
|
||||
d3.selectAll('.audio.alarms audio').each(function () {
|
||||
d3.selectAll('.audio.alarms audio').each(function() {
|
||||
var audio = this;
|
||||
playAlarm(audio);
|
||||
setTimeout(function() {
|
||||
@@ -1079,30 +1075,30 @@ client.load = function load(serverSettings, callback) {
|
||||
$('.cobcontrol').toggle(client.settings.enable.indexOf('cob') > -1);
|
||||
container.toggleClass('has-minor-pills', client.plugins.hasShownType('pill-minor', client.settings));
|
||||
|
||||
function prepareEntries ( ) {
|
||||
function prepareEntries () {
|
||||
// Post processing after data is in
|
||||
var temp1 = [ ];
|
||||
var temp1 = [];
|
||||
var sbx = client.sbx.withExtendedSettings(client.rawbg);
|
||||
|
||||
if (client.ddata.cal && client.rawbg.isEnabled(sbx)) {
|
||||
temp1 = client.ddata.sgvs.map(function (entry) {
|
||||
temp1 = client.ddata.sgvs.map(function(entry) {
|
||||
var rawbgValue = client.rawbg.showRawBGs(entry.mgdl, entry.noise, client.ddata.cal, sbx) ? client.rawbg.calc(entry, client.ddata.cal, sbx) : 0;
|
||||
if (rawbgValue > 0) {
|
||||
return { mills: entry.mills - 2000, mgdl: rawbgValue, color: 'white', type: 'rawbg' };
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}).filter(function (entry) {
|
||||
}).filter(function(entry) {
|
||||
return entry !== null;
|
||||
});
|
||||
}
|
||||
var temp2 = client.ddata.sgvs.map(function (obj) {
|
||||
return { mills: obj.mills, mgdl: obj.mgdl, direction: obj.direction, color: sgvToColor(obj.mgdl), type: 'sgv', noise: obj.noise, filtered: obj.filtered, unfiltered: obj.unfiltered};
|
||||
var temp2 = client.ddata.sgvs.map(function(obj) {
|
||||
return { mills: obj.mills, mgdl: obj.mgdl, direction: obj.direction, color: sgvToColor(obj.mgdl), type: 'sgv', noise: obj.noise, filtered: obj.filtered, unfiltered: obj.unfiltered };
|
||||
});
|
||||
client.entries = [];
|
||||
client.entries = client.entries.concat(temp1, temp2);
|
||||
|
||||
client.entries = client.entries.concat(client.ddata.mbgs.map(function (obj) {
|
||||
client.entries = client.entries.concat(client.ddata.mbgs.map(function(obj) {
|
||||
return { mills: obj.mills, mgdl: obj.mgdl, color: 'red', type: 'mbg', device: obj.device };
|
||||
}));
|
||||
|
||||
@@ -1111,7 +1107,7 @@ client.load = function load(serverSettings, callback) {
|
||||
return entry.mills > tooOld;
|
||||
});
|
||||
|
||||
client.entries.forEach(function (point) {
|
||||
client.entries.forEach(function(point) {
|
||||
if (point.mgdl < 39) {
|
||||
point.color = 'transparent';
|
||||
}
|
||||
@@ -1131,10 +1127,9 @@ client.load = function load(serverSettings, callback) {
|
||||
}
|
||||
|
||||
if (client.ddata.sgvs) {
|
||||
// change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr)
|
||||
// TODO change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr)
|
||||
client.ctx.data.lastUpdated = lastUpdated;
|
||||
client.latestSGV = client.ddata.sgvs[client.ddata.sgvs.length - 1];
|
||||
prevSGV = client.ddata.sgvs[client.ddata.sgvs.length - 2];
|
||||
}
|
||||
|
||||
client.ddata.inRetroMode = false;
|
||||
|
||||
@@ -4,22 +4,22 @@ var _ = require('lodash');
|
||||
|
||||
var TWO_DAYS = 172800000;
|
||||
|
||||
function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) {
|
||||
function mergeDataUpdate (isDelta, cachedDataArray, receivedDataArray, maxAge) {
|
||||
|
||||
function nsArrayDiff(oldArray, newArray) {
|
||||
var seen = {};
|
||||
function nsArrayDiff (oldArray, newArray) {
|
||||
var seen = [];
|
||||
var l = oldArray.length;
|
||||
|
||||
for (var i = 0; i < l; i++) {
|
||||
if (oldArray[i] !== null) {
|
||||
seen[oldArray[i].mills] = true;
|
||||
seen.push(oldArray[i].mills);
|
||||
}
|
||||
}
|
||||
|
||||
var result = [];
|
||||
l = newArray.length;
|
||||
for (var j = 0; j < l; j++) {
|
||||
if (!seen.hasOwnProperty(newArray[j].mills)) {
|
||||
if (!seen.includes(newArray[j].mills)) {
|
||||
result.push(newArray[j]); //console.log('delta data found');
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) {
|
||||
for (var i = 0; i < cachedDataArray.length; i++) {
|
||||
var element = cachedDataArray[i];
|
||||
if (element !== null && element !== undefined && element.mills <= twoDaysAgo) {
|
||||
cachedDataArray.splice(i,0);
|
||||
cachedDataArray.splice(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ function mergeDataUpdate(isDelta, cachedDataArray, receivedDataArray, maxAge) {
|
||||
});
|
||||
}
|
||||
|
||||
function mergeTreatmentUpdate(isDelta, cachedDataArray, receivedDataArray) {
|
||||
function mergeTreatmentUpdate (isDelta, cachedDataArray, receivedDataArray) {
|
||||
|
||||
// If there was no delta data, just return the original data
|
||||
if (!receivedDataArray) {
|
||||
@@ -78,12 +78,12 @@ function mergeTreatmentUpdate(isDelta, cachedDataArray, receivedDataArray) {
|
||||
for (var j = 0; j < m; j++) {
|
||||
if (no._id === cachedDataArray[j]._id) {
|
||||
if (no.action === 'remove') {
|
||||
cachedDataArray.splice(j,1);
|
||||
cachedDataArray.splice(j, 1);
|
||||
break;
|
||||
}
|
||||
if (no.action === 'update') {
|
||||
delete no.action;
|
||||
cachedDataArray.splice(j,1,no);
|
||||
cachedDataArray.splice(j, 1, no);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+257
-266
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@ var ONE_DAY = 86400000,
|
||||
function uniq(a) {
|
||||
var seen = {};
|
||||
return a.filter(function(item) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
return seen.hasOwnProperty(item.mills) ? false : (seen[item.mills] = true);
|
||||
});
|
||||
}
|
||||
|
||||
+46
-47
@@ -5,21 +5,21 @@ var times = require('../times');
|
||||
|
||||
var DEVICE_TYPE_FIELDS = ['uploader', 'pump', 'openaps', 'loop', 'xdripjs'];
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
|
||||
var ddata = {
|
||||
sgvs: [],
|
||||
treatments: [],
|
||||
mbgs: [],
|
||||
cals: [],
|
||||
profiles: [],
|
||||
devicestatus: [],
|
||||
food: [],
|
||||
activity: [],
|
||||
lastUpdated: 0
|
||||
sgvs: []
|
||||
, treatments: []
|
||||
, mbgs: []
|
||||
, cals: []
|
||||
, profiles: []
|
||||
, devicestatus: []
|
||||
, food: []
|
||||
, activity: []
|
||||
, lastUpdated: 0
|
||||
};
|
||||
|
||||
ddata.clone = function clone() {
|
||||
ddata.clone = function clone () {
|
||||
return _.clone(ddata, function(value) {
|
||||
//special handling of mongo ObjectID's
|
||||
//see https://github.com/lodash/lodash/issues/602#issuecomment-47414964
|
||||
@@ -32,21 +32,21 @@ function init() {
|
||||
});
|
||||
};
|
||||
|
||||
ddata.splitRecent = function splitRecent(time, cutoff, max, treatmentsToo) {
|
||||
ddata.splitRecent = function splitRecent (time, cutoff, max, treatmentsToo) {
|
||||
var result = {
|
||||
first: {},
|
||||
rest: {}
|
||||
first: {}
|
||||
, rest: {}
|
||||
};
|
||||
|
||||
function recent(item) {
|
||||
function recent (item) {
|
||||
return item.mills >= time - cutoff;
|
||||
}
|
||||
|
||||
function filterMax(item) {
|
||||
function filterMax (item) {
|
||||
return item.mills >= time - max;
|
||||
}
|
||||
|
||||
function partition(field, filter) {
|
||||
function partition (field, filter) {
|
||||
var data;
|
||||
if (filter) {
|
||||
data = ddata[field].filter(filterMax);
|
||||
@@ -67,13 +67,12 @@ function init() {
|
||||
result.first.cals = ddata.cals;
|
||||
|
||||
var profiles = _.cloneDeep(ddata.profiles);
|
||||
if (profiles && profiles[0])
|
||||
for (var k in profiles[0].store) {
|
||||
if (profiles[0].store.hasOwnProperty(k)) {
|
||||
if (profiles && profiles[0]) {
|
||||
Object.keys(profiles[0].store).forEach(k => {
|
||||
if (k.indexOf('@@@@@') > 0) {
|
||||
delete profiles[0].store[k];
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
result.first.profiles = profiles;
|
||||
|
||||
@@ -87,20 +86,20 @@ function init() {
|
||||
return result;
|
||||
};
|
||||
|
||||
ddata.recentDeviceStatus = function recentDeviceStatus(time) {
|
||||
ddata.recentDeviceStatus = function recentDeviceStatus (time) {
|
||||
|
||||
var deviceAndTypes =
|
||||
_.chain(ddata.devicestatus)
|
||||
.map(function eachStatus(status) {
|
||||
.map(function eachStatus (status) {
|
||||
return _.chain(status)
|
||||
.keys()
|
||||
.filter(function isExcluded(key) {
|
||||
.filter(function isExcluded (key) {
|
||||
return _.includes(DEVICE_TYPE_FIELDS, key);
|
||||
})
|
||||
.map(function toDeviceTypeKey(key) {
|
||||
.map(function toDeviceTypeKey (key) {
|
||||
return {
|
||||
device: status.device,
|
||||
type: key
|
||||
device: status.device
|
||||
, type: key
|
||||
};
|
||||
})
|
||||
.value();
|
||||
@@ -112,12 +111,12 @@ function init() {
|
||||
//console.info('>>>deviceAndTypes', deviceAndTypes);
|
||||
|
||||
var rv = _.chain(deviceAndTypes)
|
||||
.map(function findMostRecent(deviceAndType) {
|
||||
.map(function findMostRecent (deviceAndType) {
|
||||
return _.chain(ddata.devicestatus)
|
||||
.filter(function isSameDeviceType(status) {
|
||||
.filter(function isSameDeviceType (status) {
|
||||
return status.device === deviceAndType.device && _.has(status, deviceAndType.type)
|
||||
})
|
||||
.filter(function notInTheFuture(status) {
|
||||
.filter(function notInTheFuture (status) {
|
||||
return status.mills <= time;
|
||||
})
|
||||
.sortBy('mills')
|
||||
@@ -137,17 +136,17 @@ function init() {
|
||||
|
||||
};
|
||||
|
||||
ddata.processDurations = function processDurations(treatments, keepzeroduration) {
|
||||
ddata.processDurations = function processDurations (treatments, keepzeroduration) {
|
||||
|
||||
treatments = _.uniqBy(treatments, 'mills');
|
||||
|
||||
// cut temp basals by end events
|
||||
// better to do it only on data update
|
||||
var endevents = treatments.filter(function filterEnd(t) {
|
||||
var endevents = treatments.filter(function filterEnd (t) {
|
||||
return !t.duration;
|
||||
});
|
||||
|
||||
function cutIfInInterval(base, end) {
|
||||
function cutIfInInterval (base, end) {
|
||||
if (base.mills < end.mills && base.mills + times.mins(base.duration).msecs > end.mills) {
|
||||
base.duration = times.msecs(end.mills - base.mills).mins;
|
||||
if (end.profile) {
|
||||
@@ -158,18 +157,18 @@ function init() {
|
||||
}
|
||||
|
||||
// cut by end events
|
||||
treatments.forEach(function allTreatments(t) {
|
||||
treatments.forEach(function allTreatments (t) {
|
||||
if (t.duration) {
|
||||
endevents.forEach(function allEndevents(e) {
|
||||
endevents.forEach(function allEndevents (e) {
|
||||
cutIfInInterval(t, e);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// cut by overlaping events
|
||||
treatments.forEach(function allTreatments(t) {
|
||||
treatments.forEach(function allTreatments (t) {
|
||||
if (t.duration) {
|
||||
treatments.forEach(function allEndevents(e) {
|
||||
treatments.forEach(function allEndevents (e) {
|
||||
cutIfInInterval(t, e);
|
||||
});
|
||||
}
|
||||
@@ -178,44 +177,44 @@ function init() {
|
||||
if (keepzeroduration) {
|
||||
return treatments;
|
||||
} else {
|
||||
return treatments.filter(function filterEnd(t) {
|
||||
return treatments.filter(function filterEnd (t) {
|
||||
return t.duration;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ddata.processTreatments = function processTreatments(preserveOrignalTreatments) {
|
||||
ddata.processTreatments = function processTreatments (preserveOrignalTreatments) {
|
||||
|
||||
// filter & prepare 'Site Change' events
|
||||
ddata.sitechangeTreatments = ddata.treatments.filter(function filterSensor(t) {
|
||||
ddata.sitechangeTreatments = ddata.treatments.filter(function filterSensor (t) {
|
||||
return t.eventType.indexOf('Site Change') > -1;
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
});
|
||||
|
||||
// filter & prepare 'Insulin Change' events
|
||||
ddata.insulinchangeTreatments = ddata.treatments.filter(function filterInsulin(t) {
|
||||
ddata.insulinchangeTreatments = ddata.treatments.filter(function filterInsulin (t) {
|
||||
return t.eventType.indexOf('Insulin Change') > -1;
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
});
|
||||
|
||||
// filter & prepare 'Pump Battery Change' events
|
||||
ddata.batteryTreatments = ddata.treatments.filter(function filterSensor(t) {
|
||||
ddata.batteryTreatments = ddata.treatments.filter(function filterSensor (t) {
|
||||
return t.eventType.indexOf('Pump Battery Change') > -1;
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
});
|
||||
|
||||
// filter & prepare 'Sensor' events
|
||||
ddata.sensorTreatments = ddata.treatments.filter(function filterSensor(t) {
|
||||
ddata.sensorTreatments = ddata.treatments.filter(function filterSensor (t) {
|
||||
return t.eventType.indexOf('Sensor') > -1;
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
});
|
||||
|
||||
// filter & prepare 'Profile Switch' events
|
||||
var profileTreatments = ddata.treatments.filter(function filterProfiles(t) {
|
||||
var profileTreatments = ddata.treatments.filter(function filterProfiles (t) {
|
||||
return t.eventType === 'Profile Switch';
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
@@ -225,14 +224,14 @@ function init() {
|
||||
ddata.profileTreatments = ddata.processDurations(profileTreatments, true);
|
||||
|
||||
// filter & prepare 'Combo Bolus' events
|
||||
ddata.combobolusTreatments = ddata.treatments.filter(function filterComboBoluses(t) {
|
||||
ddata.combobolusTreatments = ddata.treatments.filter(function filterComboBoluses (t) {
|
||||
return t.eventType === 'Combo Bolus';
|
||||
}).sort(function(a, b) {
|
||||
return a.mills > b.mills;
|
||||
});
|
||||
|
||||
// filter & prepare temp basals
|
||||
var tempbasalTreatments = ddata.treatments.filter(function filterBasals(t) {
|
||||
var tempbasalTreatments = ddata.treatments.filter(function filterBasals (t) {
|
||||
return t.eventType && t.eventType.indexOf('Temp Basal') > -1;
|
||||
});
|
||||
if (preserveOrignalTreatments)
|
||||
@@ -240,7 +239,7 @@ function init() {
|
||||
ddata.tempbasalTreatments = ddata.processDurations(tempbasalTreatments, false);
|
||||
|
||||
// filter temp target
|
||||
var tempTargetTreatments = ddata.treatments.filter(function filterTargets(t) {
|
||||
var tempTargetTreatments = ddata.treatments.filter(function filterTargets (t) {
|
||||
//check for a units being sent
|
||||
if (t.units) {
|
||||
if (t.units == 'mmol') {
|
||||
|
||||
+23
-393
@@ -834,7 +834,6 @@ function init() {
|
||||
,dk: 'Noter indeholder'
|
||||
,fi: 'Merkinnät sisältävät'
|
||||
,nb: 'Notater inneholder'
|
||||
,he: 'הערות מכילות'
|
||||
,pl: 'Zawierają uwagi'
|
||||
,ru: 'Примечания содержат'
|
||||
,sk: 'Poznámky obsahujú'
|
||||
@@ -1460,7 +1459,6 @@ function init() {
|
||||
,sv: 'temp basal måste vara synlig för denna rapport'
|
||||
,de: 'temporäre Basalraten müssen für diesen Report sichtbar sein'
|
||||
,fi: 'tämä raportti vaatii, että basaalien piirto on päällä'
|
||||
,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה'
|
||||
,bg: 'временните базали трябва да са показани за да се покаже тази това'
|
||||
,hr: 'temp bazali moraju biti prikazani kako bi se vidio ovaj izvještaj'
|
||||
,he: 'חובה לאפשר רמה בזלית זמנית כדי לרות דוח זה'
|
||||
@@ -1469,7 +1467,6 @@ function init() {
|
||||
}
|
||||
,'Weekly success' : {
|
||||
cs: 'Statistika po týdnech'
|
||||
,he: 'הצלחה שבועית'
|
||||
,de: 'Wöchentlicher Erfolg'
|
||||
,es: 'Resultados semanales'
|
||||
,fr: 'Résultat hebdomadaire'
|
||||
@@ -1747,7 +1744,6 @@ function init() {
|
||||
cs: 'Normální'
|
||||
,de: 'Normal'
|
||||
,es: 'Normal'
|
||||
,he: 'נורמלי '
|
||||
,fr: 'Normale'
|
||||
,el: 'Εντός Στόχου'
|
||||
,pt: 'Normal'
|
||||
@@ -1871,7 +1867,6 @@ function init() {
|
||||
}
|
||||
,'Glucose Percentile report' : {
|
||||
cs: 'Tabulka percentil glykémií'
|
||||
,he: 'דוח אחוזוני גלוקוזה'
|
||||
,de: 'Glukose-Perzentil Bericht'
|
||||
,es: 'Informe de percetiles de glucemia'
|
||||
,fr: 'Rapport percentiles Glycémie'
|
||||
@@ -2196,7 +2191,6 @@ function init() {
|
||||
}
|
||||
,'Weekly Success' : {
|
||||
cs: 'Týdenní úspěšnost'
|
||||
,he: 'הצלחה שבועית '
|
||||
,de: 'Wöchtlicher Erfolg'
|
||||
,es: 'Resultados semanales'
|
||||
,fr: 'Réussite hebdomadaire'
|
||||
@@ -2263,7 +2257,6 @@ function init() {
|
||||
,dk: 'Anvender gemt API-nøgle'
|
||||
,fi: 'Tallennettu salainen API-tarkiste käytössä'
|
||||
,nb: 'Bruker lagret API nøkkel'
|
||||
,he: 'עורך אוכל'
|
||||
,pl: 'Korzystając z zapisanego poufnego hasha API'
|
||||
,ru: 'Применение сохраненного пароля API'
|
||||
,sk: 'Používam uložený API hash heslo'
|
||||
@@ -2275,7 +2268,6 @@ function init() {
|
||||
}
|
||||
,'No API secret hash stored yet. You need to enter API secret.' : {
|
||||
cs: 'Není uložený žádný hash API hesla. Musíte zadat API heslo.'
|
||||
,he: 'הכנס את סיסמת ממשק תכנות יישומים הסודית'
|
||||
,de: 'Keine API-Prüfsumme gespeichert. Bitte API-Prüfsumme eingeben.'
|
||||
,es: 'No se ha almacenado ningún hash todavía. Debe introducir su secreto API.'
|
||||
,fr: 'Pas de secret API existant. Vous devez en entrer un.'
|
||||
@@ -2302,7 +2294,6 @@ function init() {
|
||||
}
|
||||
,'Database loaded' : {
|
||||
cs: 'Databáze načtena'
|
||||
,he: 'אגר מידע נטען '
|
||||
,de: 'Datenbank geladen'
|
||||
,es: 'Base de datos cargada'
|
||||
,fr: 'Base de données chargée'
|
||||
@@ -2496,7 +2487,6 @@ function init() {
|
||||
,pl: 'IG'
|
||||
,ru: 'ГИ'
|
||||
,sk: 'GI'
|
||||
,he: 'GI'
|
||||
,nl: 'Glycemische index '
|
||||
,ko: '혈당 지수'
|
||||
,tr: 'GI-Glisemik İndeks'
|
||||
@@ -2638,7 +2628,6 @@ function init() {
|
||||
,ro: 'Cheia API trebuie să aibă mai mult de 12 caractere'
|
||||
,bg: 'Вашата АPI парола трябва да е дълга поне 12 символа'
|
||||
,hr: 'Vaš tajni API mora sadržavati barem 12 znakova'
|
||||
,he:' הסיסמא הסודית חייבת להיות באורך של 12 תווים לפחות'
|
||||
,sv: 'Hemlig API-nyckel måsta innehålla 12 tecken'
|
||||
,it: 'il vostro API secreto deve essere lungo almeno 12 caratteri'
|
||||
,ja: 'APIシークレットは12文字以上の長さが必要です'
|
||||
@@ -2673,7 +2662,6 @@ function init() {
|
||||
,nb: 'Ugyldig API nøkkel'
|
||||
,pl: 'Błędny klucz API'
|
||||
,ru: 'Плохой пароль API'
|
||||
,he: ' הסיסמא הסודית אינה חוקית'
|
||||
,sk: 'Nesprávne API heslo'
|
||||
,nl: 'Onjuist API wachtwoord'
|
||||
,ko: '잘못된 API secret'
|
||||
@@ -2699,7 +2687,6 @@ function init() {
|
||||
,fi: 'API salaisuus talletettu'
|
||||
,nb: 'API nøkkel lagret'
|
||||
,pl: 'Poufne klucz API zapisane'
|
||||
,he: ' הסיסמא הסודית נשמרה'
|
||||
,ru: 'Хэш пароля API сохранен'
|
||||
,sk: 'Hash API hesla uložený'
|
||||
,nl: 'API wachtwoord opgeslagen'
|
||||
@@ -2750,7 +2737,6 @@ function init() {
|
||||
,dk: 'Ikke indlæst'
|
||||
,fi: 'Ei ladattu'
|
||||
,nb: 'Ikke lest'
|
||||
,he: 'לא נטען'
|
||||
,pl: 'Nie załadowany'
|
||||
,ru: 'Не загружено'
|
||||
,sk: 'Nenačítaný'
|
||||
@@ -2773,7 +2759,6 @@ function init() {
|
||||
,sv: 'Födoämneseditor'
|
||||
,it: 'NS - Database Alimenti'
|
||||
,ja: '食事編集'
|
||||
,he: 'עורך מזון'
|
||||
,dk: 'Mad editor'
|
||||
,fi: 'Muokkaa ruokia'
|
||||
,nb: 'Mat editor'
|
||||
@@ -2973,7 +2958,6 @@ function init() {
|
||||
,ro: 'Cheia API'
|
||||
,bg: 'Твоята API парола'
|
||||
,hr: 'Vaš tajni API'
|
||||
,he: 'הסיסמא הסודית שלך'
|
||||
,it: 'Il tuo API secreto'
|
||||
,ja: 'あなたのAPI Secret'
|
||||
,dk: 'Din API-nøgle'
|
||||
@@ -3005,7 +2989,6 @@ function init() {
|
||||
,dk: 'Gemme hash på denne computer (brug kun på privat computer)'
|
||||
,fi: 'Tallenna avain tälle tietokoneelle (käytä vain omalla tietokoneellasi)'
|
||||
,nb: 'Lagre hash på denne pc (bruk kun på privat pc)'
|
||||
,he:'שמור סיסמא הסודית על המחשב ( יש להשתמש רק על מחשב פרטי)'
|
||||
,pl: 'Zapisz na tym komputerze (korzystaj tylko na komputerach prywatnych)'
|
||||
,ru: 'Сохранить хеш на этом ПК (только для личных компьютеров)'
|
||||
,sk: 'Uložiť hash na tomto počítači (Používajte iba na súkromných počítačoch)'
|
||||
@@ -7692,7 +7675,7 @@ function init() {
|
||||
cs: 'Odstraňování záznamů ...'
|
||||
,he: 'מוחק רשומות ... '
|
||||
,nb: 'Fjerner elementer...'
|
||||
,fr: 'Effacement d\événements...'
|
||||
,fr: 'Effacement dévénements...'
|
||||
,ro: 'Se șterg înregistrările...'
|
||||
,el: 'Αφαίρεση Εγγραφών'
|
||||
,de: 'Entferne Einträge ...'
|
||||
@@ -7714,29 +7697,7 @@ function init() {
|
||||
,zh_tw: '正在刪除記錄...'
|
||||
}
|
||||
,'%1 records deleted' : {
|
||||
cs: '%1 records deleted'
|
||||
,he: '%1 records deleted'
|
||||
,nb: '%1 records deleted'
|
||||
,fr: '%1 records deleted'
|
||||
,ro: '%1 records deleted'
|
||||
,el: '%1 records deleted'
|
||||
,de: '%1 records deleted'
|
||||
,es: '%1 records deleted'
|
||||
,dk: '%1 records deleted'
|
||||
,sv: '%1 records deleted'
|
||||
,bg: '%1 records deleted'
|
||||
,hr: 'obrisano %1 zapisa'
|
||||
,it: '%1 records deleted'
|
||||
,fi: '%1 records deleted'
|
||||
,pl: '%1 records deleted'
|
||||
,pt: '%1 records deleted'
|
||||
,ru: '%1 records deleted'
|
||||
,sk: '%1 records deleted'
|
||||
,nl: '%1 records deleted'
|
||||
,ko: '%1 records deleted'
|
||||
,tr: '%1 records deleted'
|
||||
,zh_cn: '%1 records deleted'
|
||||
,zh_tw: '%1 records deleted'
|
||||
hr: 'obrisano %1 zapisa'
|
||||
}
|
||||
,'Clean Mongo status database' : {
|
||||
cs: 'Vyčištění Mongo databáze statusů'
|
||||
@@ -7906,379 +7867,49 @@ function init() {
|
||||
,zh_cn: '所有记录已经被清除'
|
||||
}
|
||||
,'Delete all documents from devicestatus collection older than 30 days' : {
|
||||
cs: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,he: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,nb: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,fr: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,ro: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,el: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,de: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,es: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,dk: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,sv: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,bg: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,hr: 'Obriši sve statuse starije od 30 dana'
|
||||
,it: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,fi: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,pl: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,pt: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,ru: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,sk: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,nl: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,ko: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,tr: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,zh_cn: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
,zh_tw: 'Delete all documents from devicestatus collection older than 30 days'
|
||||
hr: 'Obriši sve statuse starije od 30 dana'
|
||||
}
|
||||
,'Number of Days to Keep:' : {
|
||||
cs: 'Number of Days to Keep:'
|
||||
,he: 'Number of Days to Keep:'
|
||||
,nb: 'Number of Days to Keep:'
|
||||
,fr: 'Number of Days to Keep:'
|
||||
,ro: 'Number of Days to Keep:'
|
||||
,el: 'Number of Days to Keep:'
|
||||
,de: 'Number of Days to Keep:'
|
||||
,es: 'Number of Days to Keep:'
|
||||
,dk: 'Number of Days to Keep:'
|
||||
,sv: 'Number of Days to Keep:'
|
||||
,bg: 'Number of Days to Keep:'
|
||||
,hr: 'Broj dana za sačuvati:'
|
||||
,it: 'Number of Days to Keep:'
|
||||
,fi: 'Number of Days to Keep:'
|
||||
,pl: 'Number of Days to Keep:'
|
||||
,pt: 'Number of Days to Keep:'
|
||||
,ru: 'Number of Days to Keep:'
|
||||
,sk: 'Number of Days to Keep:'
|
||||
,nl: 'Number of Days to Keep:'
|
||||
,ko: 'Number of Days to Keep:'
|
||||
,tr: 'Number of Days to Keep:'
|
||||
,zh_cn: 'Number of Days to Keep:'
|
||||
,zh_tw: 'Number of Days to Keep:'
|
||||
hr: 'Broj dana za sačuvati:'
|
||||
}
|
||||
,'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' : {
|
||||
cs: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,he: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,nb: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,fr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,ro: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,el: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,de: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,es: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,dk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,sv: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,bg: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,hr: 'Ovo uklanja sve statuse starije od 30 dana. Korisno kada se status baterije uploadera ne osvježava ispravno.'
|
||||
,it: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,fi: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,pl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,pt: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,ru: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,sk: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,nl: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,ko: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,tr: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_cn: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_tw: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.'
|
||||
hr: 'Ovo uklanja sve statuse starije od 30 dana. Korisno kada se status baterije uploadera ne osvježava ispravno.'
|
||||
}
|
||||
,'Delete old documents from devicestatus collection?' : {
|
||||
cs: 'Delete old documents from devicestatus collection?'
|
||||
,he: 'Delete old documents from devicestatus collection?'
|
||||
,nb: 'Delete old documents from devicestatus collection?'
|
||||
,fr: 'Delete old documents from devicestatus collection?'
|
||||
,ro: 'Delete old documents from devicestatus collection?'
|
||||
,el: 'Delete old documents from devicestatus collection?'
|
||||
,de: 'Delete old documents from devicestatus collection?'
|
||||
,es: 'Delete old documents from devicestatus collection?'
|
||||
,dk: 'Delete old documents from devicestatus collection?'
|
||||
,sv: 'Delete old documents from devicestatus collection?'
|
||||
,bg: 'Delete old documents from devicestatus collection?'
|
||||
,hr: 'Obriši stare statuse'
|
||||
,it: 'Delete old documents from devicestatus collection?'
|
||||
,fi: 'Delete old documents from devicestatus collection?'
|
||||
,pl: 'Delete old documents from devicestatus collection?'
|
||||
,pt: 'Delete old documents from devicestatus collection?'
|
||||
,ru: 'Delete old documents from devicestatus collection?'
|
||||
,sk: 'Delete old documents from devicestatus collection?'
|
||||
,nl: 'Delete old documents from devicestatus collection?'
|
||||
,ko: 'Delete old documents from devicestatus collection?'
|
||||
,tr: 'Delete old documents from devicestatus collection?'
|
||||
,zh_cn: 'Delete old documents from devicestatus collection?'
|
||||
,zh_tw: 'Delete old documents from devicestatus collection?'
|
||||
hr: 'Obriši stare statuse'
|
||||
}
|
||||
,'Clean Mongo entries (glucose entries) database' : {
|
||||
cs: 'Clean Mongo entries (glucose entries) database'
|
||||
,he: 'Clean Mongo entries (glucose entries) database'
|
||||
,nb: 'Clean Mongo entries (glucose entries) database'
|
||||
,fr: 'Clean Mongo entries (glucose entries) database'
|
||||
,ro: 'Clean Mongo entries (glucose entries) database'
|
||||
,el: 'Clean Mongo entries (glucose entries) database'
|
||||
,de: 'Clean Mongo entries (glucose entries) database'
|
||||
,es: 'Clean Mongo entries (glucose entries) database'
|
||||
,dk: 'Clean Mongo entries (glucose entries) database'
|
||||
,sv: 'Clean Mongo entries (glucose entries) database'
|
||||
,bg: 'Clean Mongo entries (glucose entries) database'
|
||||
,hr: 'Obriši GUK zapise iz baze'
|
||||
,it: 'Clean Mongo entries (glucose entries) database'
|
||||
,fi: 'Clean Mongo entries (glucose entries) database'
|
||||
,pl: 'Clean Mongo entries (glucose entries) database'
|
||||
,pt: 'Clean Mongo entries (glucose entries) database'
|
||||
,ru: 'Clean Mongo entries (glucose entries) database'
|
||||
,sk: 'Clean Mongo entries (glucose entries) database'
|
||||
,nl: 'Clean Mongo entries (glucose entries) database'
|
||||
,ko: 'Clean Mongo entries (glucose entries) database'
|
||||
,tr: 'Clean Mongo entries (glucose entries) database'
|
||||
,zh_cn: 'Clean Mongo entries (glucose entries) database'
|
||||
,zh_tw: 'Clean Mongo entries (glucose entries) database'
|
||||
hr: 'Obriši GUK zapise iz baze'
|
||||
}
|
||||
,'Delete all documents from entries collection older than 180 days' : {
|
||||
cs: 'Delete all documents from entries collection older than 180 days'
|
||||
,he: 'Delete all documents from entries collection older than 180 days'
|
||||
,nb: 'Delete all documents from entries collection older than 180 days'
|
||||
,fr: 'Delete all documents from entries collection older than 180 days'
|
||||
,ro: 'Delete all documents from entries collection older than 180 days'
|
||||
,el: 'Delete all documents from entries collection older than 180 days'
|
||||
,de: 'Delete all documents from entries collection older than 180 days'
|
||||
,es: 'Delete all documents from entries collection older than 180 days'
|
||||
,dk: 'Delete all documents from entries collection older than 180 days'
|
||||
,sv: 'Delete all documents from entries collection older than 180 days'
|
||||
,bg: 'Delete all documents from entries collection older than 180 days'
|
||||
,hr: 'Obriši sve zapise starije od 180 dana'
|
||||
,it: 'Delete all documents from entries collection older than 180 days'
|
||||
,fi: 'Delete all documents from entries collection older than 180 days'
|
||||
,pl: 'Delete all documents from entries collection older than 180 days'
|
||||
,pt: 'Delete all documents from entries collection older than 180 days'
|
||||
,ru: 'Delete all documents from entries collection older than 180 days'
|
||||
,sk: 'Delete all documents from entries collection older than 180 days'
|
||||
,nl: 'Delete all documents from entries collection older than 180 days'
|
||||
,ko: 'Delete all documents from entries collection older than 180 days'
|
||||
,tr: 'Delete all documents from entries collection older than 180 days'
|
||||
,zh_cn: 'Delete all documents from entries collection older than 180 days'
|
||||
,zh_tw: 'Delete all documents from entries collection older than 180 days'
|
||||
hr: 'Obriši sve zapise starije od 180 dana'
|
||||
}
|
||||
,'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : {
|
||||
cs: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,he: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,nb: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,fr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ro: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,el: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,de: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,es: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,dk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,sv: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,bg: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,hr: 'Ovo briše sve zapise starije od 180 dana. Korisno kada se status baterije uploadera ne osvježava.'
|
||||
,it: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,fi: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,pl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,pt: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ru: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,sk: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,nl: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ko: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,tr: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_cn: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_tw: 'This task removes all documents from entries collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
hr: 'Ovo briše sve zapise starije od 180 dana. Korisno kada se status baterije uploadera ne osvježava.'
|
||||
}
|
||||
,'Delete old documents' : {
|
||||
cs: 'Delete old documents'
|
||||
,he: 'Delete old documents'
|
||||
,nb: 'Delete old documents'
|
||||
,fr: 'Delete old documents'
|
||||
,ro: 'Delete old documents'
|
||||
,el: 'Delete old documents'
|
||||
,de: 'Delete old documents'
|
||||
,es: 'Delete old documents'
|
||||
,dk: 'Delete old documents'
|
||||
,sv: 'Delete old documents'
|
||||
,bg: 'Delete old documents'
|
||||
,hr: 'Obriši stare zapise'
|
||||
,it: 'Delete old documents'
|
||||
,fi: 'Delete old documents'
|
||||
,pl: 'Delete old documents'
|
||||
,pt: 'Delete old documents'
|
||||
,ru: 'Delete old documents'
|
||||
,sk: 'Delete old documents'
|
||||
,nl: 'Delete old documents'
|
||||
,ko: 'Delete old documents'
|
||||
,tr: 'Delete old documents'
|
||||
,zh_cn: 'Delete old documents'
|
||||
,zh_tw: 'Delete old documents'
|
||||
hr: 'Obriši stare zapise'
|
||||
}
|
||||
,'Delete old documents from entries collection?' : {
|
||||
cs: 'Delete old documents from entries collection?'
|
||||
,he: 'Delete old documents from entries collection?'
|
||||
,nb: 'Delete old documents from entries collection?'
|
||||
,fr: 'Delete old documents from entries collection?'
|
||||
,ro: 'Delete old documents from entries collection?'
|
||||
,el: 'Delete old documents from entries collection?'
|
||||
,de: 'Delete old documents from entries collection?'
|
||||
,es: 'Delete old documents from entries collection?'
|
||||
,dk: 'Delete old documents from entries collection?'
|
||||
,sv: 'Delete old documents from entries collection?'
|
||||
,bg: 'Delete old documents from entries collection?'
|
||||
,hr: 'Obriši stare zapise?'
|
||||
,it: 'Delete old documents from entries collection?'
|
||||
,fi: 'Delete old documents from entries collection?'
|
||||
,pl: 'Delete old documents from entries collection?'
|
||||
,pt: 'Delete old documents from entries collection?'
|
||||
,ru: 'Delete old documents from entries collection?'
|
||||
,sk: 'Delete old documents from entries collection?'
|
||||
,nl: 'Delete old documents from entries collection?'
|
||||
,ko: 'Delete old documents from entries collection?'
|
||||
,tr: 'Delete old documents from entries collection?'
|
||||
,zh_cn: 'Delete old documents from entries collection?'
|
||||
,zh_tw: 'Delete old documents from entries collection?'
|
||||
hr: 'Obriši stare zapise?'
|
||||
}
|
||||
,'%1 is not a valid number' : {
|
||||
cs: '%1 is not a valid number'
|
||||
,he: '%1 is not a valid number'
|
||||
,nb: '%1 is not a valid number'
|
||||
,fr: '%1 is not a valid number'
|
||||
,ro: '%1 is not a valid number'
|
||||
,el: '%1 is not a valid number'
|
||||
,de: '%1 is not a valid number'
|
||||
,es: '%1 is not a valid number'
|
||||
,dk: '%1 is not a valid number'
|
||||
,sv: '%1 is not a valid number'
|
||||
,bg: '%1 is not a valid number'
|
||||
,hr: '%1 nije valjan broj'
|
||||
,it: '%1 is not a valid number'
|
||||
,fi: '%1 is not a valid number'
|
||||
,pl: '%1 is not a valid number'
|
||||
,pt: '%1 is not a valid number'
|
||||
,ru: '%1 is not a valid number'
|
||||
,sk: '%1 is not a valid number'
|
||||
,nl: '%1 is not a valid number'
|
||||
,ko: '%1 is not a valid number'
|
||||
,tr: '%1 is not a valid number'
|
||||
,zh_cn: '%1 is not a valid number'
|
||||
,zh_tw: '%1 is not a valid number'
|
||||
hr: '%1 nije valjan broj'
|
||||
}
|
||||
,'%1 is not a valid number - must be more than 2' : {
|
||||
cs: '%1 is not a valid number - must be more than 2'
|
||||
,he: '%1 is not a valid number - must be more than 2'
|
||||
,nb: '%1 is not a valid number - must be more than 2'
|
||||
,fr: '%1 is not a valid number - must be more than 2'
|
||||
,ro: '%1 is not a valid number - must be more than 2'
|
||||
,el: '%1 is not a valid number - must be more than 2'
|
||||
,de: '%1 is not a valid number - must be more than 2'
|
||||
,es: '%1 is not a valid number - must be more than 2'
|
||||
,dk: '%1 is not a valid number - must be more than 2'
|
||||
,sv: '%1 is not a valid number - must be more than 2'
|
||||
,bg: '%1 is not a valid number - must be more than 2'
|
||||
,hr: '%1 nije valjan broj - mora biti veći od 2'
|
||||
,it: '%1 is not a valid number - must be more than 2'
|
||||
,fi: '%1 is not a valid number - must be more than 2'
|
||||
,pl: '%1 is not a valid number - must be more than 2'
|
||||
,pt: '%1 is not a valid number - must be more than 2'
|
||||
,ru: '%1 is not a valid number - must be more than 2'
|
||||
,sk: '%1 is not a valid number - must be more than 2'
|
||||
,nl: '%1 is not a valid number - must be more than 2'
|
||||
,ko: '%1 is not a valid number - must be more than 2'
|
||||
,tr: '%1 is not a valid number - must be more than 2'
|
||||
,zh_cn: '%1 is not a valid number - must be more than 2'
|
||||
,zh_tw: '%1 is not a valid number - must be more than 2'
|
||||
hr: '%1 nije valjan broj - mora biti veći od 2'
|
||||
}
|
||||
,'Clean Mongo treatments database' : {
|
||||
cs: 'Clean Mongo treatments database'
|
||||
,he: 'Clean Mongo treatments database'
|
||||
,nb: 'Clean Mongo treatments database'
|
||||
,fr: 'Clean Mongo treatments database'
|
||||
,ro: 'Clean Mongo treatments database'
|
||||
,el: 'Clean Mongo treatments database'
|
||||
,de: 'Clean Mongo treatments database'
|
||||
,es: 'Clean Mongo treatments database'
|
||||
,dk: 'Clean Mongo treatments database'
|
||||
,sv: 'Clean Mongo treatments database'
|
||||
,bg: 'Clean Mongo treatments database'
|
||||
,hr: 'Obriši tretmane iz baze'
|
||||
,it: 'Clean Mongo treatments database'
|
||||
,fi: 'Clean Mongo treatments database'
|
||||
,pl: 'Clean Mongo treatments database'
|
||||
,pt: 'Clean Mongo treatments database'
|
||||
,ru: 'Clean Mongo treatments database'
|
||||
,sk: 'Clean Mongo treatments database'
|
||||
,nl: 'Clean Mongo treatments database'
|
||||
,ko: 'Clean Mongo treatments database'
|
||||
,tr: 'Clean Mongo treatments database'
|
||||
,zh_cn: 'Clean Mongo treatments database'
|
||||
,zh_tw: 'Clean Mongo treatments database'
|
||||
hr: 'Obriši tretmane iz baze'
|
||||
}
|
||||
,'Delete all documents from treatments collection older than 180 days' : {
|
||||
cs: 'Delete all documents from treatments collection older than 180 days'
|
||||
,he: 'Delete all documents from treatments collection older than 180 days'
|
||||
,nb: 'Delete all documents from treatments collection older than 180 days'
|
||||
,fr: 'Delete all documents from treatments collection older than 180 days'
|
||||
,ro: 'Delete all documents from treatments collection older than 180 days'
|
||||
,el: 'Delete all documents from treatments collection older than 180 days'
|
||||
,de: 'Delete all documents from treatments collection older than 180 days'
|
||||
,es: 'Delete all documents from treatments collection older than 180 days'
|
||||
,dk: 'Delete all documents from treatments collection older than 180 days'
|
||||
,sv: 'Delete all documents from treatments collection older than 180 days'
|
||||
,bg: 'Delete all documents from treatments collection older than 180 days'
|
||||
,hr: 'Obriši tretmane starije od 180 dana iz baze'
|
||||
,it: 'Delete all documents from treatments collection older than 180 days'
|
||||
,fi: 'Delete all documents from treatments collection older than 180 days'
|
||||
,pl: 'Delete all documents from treatments collection older than 180 days'
|
||||
,pt: 'Delete all documents from treatments collection older than 180 days'
|
||||
,ru: 'Delete all documents from treatments collection older than 180 days'
|
||||
,sk: 'Delete all documents from treatments collection older than 180 days'
|
||||
,nl: 'Delete all documents from treatments collection older than 180 days'
|
||||
,ko: 'Delete all documents from treatments collection older than 180 days'
|
||||
,tr: 'Delete all documents from treatments collection older than 180 days'
|
||||
,zh_cn: 'Delete all documents from treatments collection older than 180 days'
|
||||
,zh_tw: 'Delete all documents from treatments collection older than 180 days'
|
||||
hr: 'Obriši tretmane starije od 180 dana iz baze'
|
||||
}
|
||||
,'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.' : {
|
||||
cs: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,he: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,nb: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,fr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ro: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,el: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,de: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,es: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,dk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,sv: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,bg: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,hr: 'Ovo briše sve tretmane starije od 180 dana iz baze. Korisno kada se status baterije uploadera ne osvježava.'
|
||||
,it: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,fi: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,pl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,pt: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ru: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,sk: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,nl: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,ko: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,tr: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_cn: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
,zh_tw: 'This task removes all documents from treatments collection that are older than 180 days. Useful when uploader battery status is not properly updated.'
|
||||
hr: 'Ovo briše sve tretmane starije od 180 dana iz baze. Korisno kada se status baterije uploadera ne osvježava.'
|
||||
}
|
||||
,'Delete old documents from treatments collection?' : {
|
||||
cs: 'Delete old documents from treatments collection?'
|
||||
,he: 'Delete old documents from treatments collection?'
|
||||
,nb: 'Delete old documents from treatments collection?'
|
||||
,fr: 'Delete old documents from treatments collection?'
|
||||
,ro: 'Delete old documents from treatments collection?'
|
||||
,el: 'Delete old documents from treatments collection?'
|
||||
,de: 'Delete old documents from treatments collection?'
|
||||
,es: 'Delete old documents from treatments collection?'
|
||||
,dk: 'Delete old documents from treatments collection?'
|
||||
,sv: 'Delete old documents from treatments collection?'
|
||||
,bg: 'Delete old documents from treatments collection?'
|
||||
,hr: 'Obriši stare tretmane?'
|
||||
,it: 'Delete old documents from treatments collection?'
|
||||
,fi: 'Delete old documents from treatments collection?'
|
||||
,pl: 'Delete old documents from treatments collection?'
|
||||
,pt: 'Delete old documents from treatments collection?'
|
||||
,ru: 'Delete old documents from treatments collection?'
|
||||
,sk: 'Delete old documents from treatments collection?'
|
||||
,nl: 'Delete old documents from treatments collection?'
|
||||
,ko: 'Delete old documents from treatments collection?'
|
||||
,tr: 'Delete old documents from treatments collection?'
|
||||
,zh_cn: 'Delete old documents from treatments collection?'
|
||||
,zh_tw: 'Delete old documents from treatments collection?'
|
||||
hr: 'Obriši stare tretmane?'
|
||||
}
|
||||
,'Admin Tools' : {
|
||||
cs: 'Nástroje pro správu'
|
||||
@@ -10106,7 +9737,7 @@ function init() {
|
||||
}
|
||||
,'Profile is going to be saved in newer format used in Nightscout 0.9.0 and above and will not be usable in older versions anymore.\nAre you sure?' : {
|
||||
cs: 'Profil bude uložen v novějším formátu používaném v Nightscoutu 0.9.0 a novějších. Již nebude použitelný se starší verzí.\nJste si jistý?'
|
||||
,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \ האם אתה בטוח? '
|
||||
,he: 'הפרופיל עומד להישמר בתבנית חדשה יותר בשימוש ב- Nightscout 0.9.0 ומעלה ולא יהיה ניתן להשתמש בו בגרסאות ישנות יותר. \n האם אתה בטוח? '
|
||||
,el: 'Το προφίλ πρόκειται να αποθηκευτεί με τη νέα του μορφή (έκδοση Nighscout 0.9.0 και πάνω) και δεν πρόκειται να μπορεί να χρησιμοποιηθεί σε παλαιότερες εκδόσεις. \nΕίστε σίγουροι?'
|
||||
,fr: 'Le profil va être sauvegardé dans un nouveau format utilisé par Nightscout 0.9.0 et suivants, et il ne pourra plus être utilisé par les versions antérieures. \nÊtes-vous sûr?'
|
||||
,ro: 'Profilul va fi salvat într-un format nou, folosit în Nightscout 0.9.0 și superior și nu va mai fi posibilă folosirea pentru versiunile mai vechi.\nSunteți de acord?'
|
||||
@@ -10130,7 +9761,7 @@ function init() {
|
||||
}
|
||||
,'Wrong profile setting.\nNo profile defined to displayed time.\nRedirecting to profile editor to create new profile.' : {
|
||||
cs: 'Chybě nastavený profil.\nNení definovaný žádný platný profil k času zobrazení.\nProvádím přesměrování na editor profilu.'
|
||||
,he: 'הגדרת פרופיל שגוי. \ N פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. '
|
||||
,he: 'הגדרת פרופיל שגוי. \n פרופיל מוגדר לזמן המוצג. מפנה מחדש לעורך פרופיל כדי ליצור פרופיל חדש. '
|
||||
,el: 'Λάθος προφίλ. Παρακαλώ δημιουργήστε ένα νέο προφίλ'
|
||||
,fr: 'Erreur de réglage de profil. \nAucun profil défini pour indiquer l\'heure. \nRedirection vers la création d\'un nouveau profil. '
|
||||
,de: 'Falsche Profileinstellung.\nKein Profil festgelegt zur angezeigten Zeit.\n Weiter zum Profileditor, um ein neues Profil zu erstellen.'
|
||||
@@ -10709,7 +10340,6 @@ function init() {
|
||||
,nb: 'Hver enkelt rolle vil ha en eller flere rettigheter. <em>*</em>-rettigheten er wildcard. Rettigheter settes hierarkisk med <em>:</em> som separator.'
|
||||
,fi: 'Jokaisella roolilla on yksi tai useampia oikeuksia. <em>*</em> on jokeri (tunnistuu kaikkina oikeuksina), oikeudet ovat hierarkia joka käyttää <em>:</em> merkkiä erottimena.'
|
||||
,de: 'Jede Rolle hat eine oder mehrere Berechtigungen. Die <em>*</em> Berechtigung ist ein Platzhalter, Berechtigungen sind hierachrchisch mit <em>:</em> als Separator.'
|
||||
,sv: 'Hver rolle vil have en eller flere rettigheder. <em>*</em> er en joker, rettigheder sættes hierakisk med <em>:</em> som skilletegn.'
|
||||
,es: 'Cada Rol tiene uno o más permisos. El permiso <em>*</em> es un marcador de posición y los permisos son jerárquicos con <em>:</em> como separador.'
|
||||
,pt: 'Cada função terá uma ou mais permissões. A permissão <em>*</em> é um wildcard, permissões são uma hierarquia utilizando <em>*</em> como um separador.'
|
||||
,sk: 'Každá rola má 1 alebo viac oprávnení. Oprávnenie <em>*</em> je zástupný znak, oprávnenia sú hierarchie používajúce <em>:</em> ako oddelovač.'
|
||||
@@ -11994,7 +11624,6 @@ function init() {
|
||||
,sk: 'Nadbytok inzulínu o %1U viac ako je potrebné na dosiahnutie spodnej cieľovej hranice. Neráta sa so sacharidmi.'
|
||||
,ko: '낮은 혈당 목표에 도달하기 위해 필요한 인슐린양보다 %1U의 인슐린 양이 초과 되었고 탄수화물 양이 초과되지 않았습니다.'
|
||||
,it: 'L\'eccesso d\'insulina equivalente %1U più che necessari per raggiungere l\'obiettivo basso, non rappresentano i carboidrati.'
|
||||
,nl: 'Overschot insuline %1U meer dan nodig om het laag doel te bereiken, geen rekening gehouden met KH'
|
||||
,tr: 'Fazla insülin: Karbonhidratları dikkate alınmadan, alt hedefe ulaşmak için gerekenden %1U\'den daha fazla' //???
|
||||
,zh_cn: '胰岛素超过至血糖下限目标所需剂量%1单位,不计算碳水化合物'
|
||||
, pl: 'Nadmiar insuliny, %1J więcej niż potrzeba, aby osiągnąć cel dolnej granicy, nie biorąc pod uwagę węglowodanów'
|
||||
@@ -12427,7 +12056,7 @@ function init() {
|
||||
,sv: 'Applicerad'
|
||||
,nb: 'Satt inn'
|
||||
,fi: 'Asetettu'
|
||||
,es: 'Insertar'
|
||||
,es: 'Insertado'
|
||||
,pt: 'Inserido'
|
||||
,sk: 'Zavedený'
|
||||
,ko: '삽입된'
|
||||
@@ -12453,7 +12082,7 @@ function init() {
|
||||
,nb: 'Nål alder'
|
||||
,fi: 'KIKÄ'
|
||||
,pt: 'ICAT'
|
||||
,es: 'Carb.desde'
|
||||
,es: 'Cánula desde'
|
||||
,sk: 'SET'
|
||||
,ko: '주입세트사용기간'
|
||||
,it: 'CAGE'
|
||||
@@ -12477,7 +12106,7 @@ function init() {
|
||||
,nb: 'Aktive karbohydrater'
|
||||
,fi: 'AH'
|
||||
,pt: 'COB'
|
||||
,es: 'Carbohidratos activos'
|
||||
,es: 'Carb. activos'
|
||||
,sk: 'SACH'
|
||||
,ko: 'COB'
|
||||
,it: 'COB'
|
||||
@@ -14490,6 +14119,7 @@ function init() {
|
||||
}
|
||||
if (options && options.params) {
|
||||
for (var i = 0; i < options.params.length; i++) {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
var r = new RegExp('\%' + (i+1), 'g');
|
||||
translated = translated.replace(r, options.params[i]);
|
||||
}
|
||||
|
||||
+19
-24
@@ -15,7 +15,7 @@ var Alarm = function(level, group, label) {
|
||||
};
|
||||
|
||||
// list of alarms with their thresholds
|
||||
var alarms = { };
|
||||
var alarms = {};
|
||||
|
||||
function init (env, ctx) {
|
||||
function notifications () {
|
||||
@@ -41,7 +41,7 @@ function init (env, ctx) {
|
||||
|
||||
var sendClear = false;
|
||||
|
||||
for (var level = 1; level <=2; level++) {
|
||||
for (var level = 1; level <= 2; level++) {
|
||||
var alarm = getAlarm(level, group);
|
||||
if (alarm.lastEmitTime) {
|
||||
console.info('auto acking ' + alarm.level, ' - ', group);
|
||||
@@ -51,7 +51,7 @@ function init (env, ctx) {
|
||||
}
|
||||
|
||||
if (sendClear) {
|
||||
var notify = {clear: true, title: 'All Clear', message: 'Auto ack\'d alarm(s)', group: group};
|
||||
var notify = { clear: true, title: 'All Clear', message: 'Auto ack\'d alarm(s)', group: group };
|
||||
ctx.bus.emit('notification', notify);
|
||||
logEmitEvent(notify);
|
||||
}
|
||||
@@ -70,8 +70,8 @@ function init (env, ctx) {
|
||||
|
||||
var requests = {};
|
||||
|
||||
notifications.initRequests = function initRequests ( ) {
|
||||
requests = { notifies: [] , snoozes: []};
|
||||
notifications.initRequests = function initRequests () {
|
||||
requests = { notifies: [], snoozes: [] };
|
||||
};
|
||||
|
||||
notifications.initRequests();
|
||||
@@ -82,12 +82,12 @@ function init (env, ctx) {
|
||||
*/
|
||||
notifications.findHighestAlarm = function findHighestAlarm (group) {
|
||||
group = group || 'default';
|
||||
var filtered = _.filter(requests.notifies, {group: group});
|
||||
return _.find(filtered, {level: levels.URGENT}) || _.find(filtered, {level: levels.WARN});
|
||||
var filtered = _.filter(requests.notifies, { group: group });
|
||||
return _.find(filtered, { level: levels.URGENT }) || _.find(filtered, { level: levels.WARN });
|
||||
};
|
||||
|
||||
notifications.findUnSnoozeable = function findUnSnoozeable ( ) {
|
||||
return _.filter(requests.notifies, function (notify) {
|
||||
notifications.findUnSnoozeable = function findUnSnoozeable () {
|
||||
return _.filter(requests.notifies, function(notify) {
|
||||
return notify.level <= levels.INFO || notify.isAnnouncement;
|
||||
});
|
||||
};
|
||||
@@ -95,7 +95,7 @@ function init (env, ctx) {
|
||||
notifications.snoozedBy = function snoozedBy (notify) {
|
||||
if (notify.isAnnouncement) { return false; }
|
||||
|
||||
var filtered = _.filter(requests.snoozes, {group: notify.group});
|
||||
var filtered = _.filter(requests.snoozes, { group: notify.group });
|
||||
|
||||
if (_.isEmpty(filtered)) { return false; }
|
||||
|
||||
@@ -107,13 +107,8 @@ function init (env, ctx) {
|
||||
return _.last(sorted);
|
||||
};
|
||||
|
||||
notifications.registerGroup = function registerGroup (group) {
|
||||
if (groups.indexOf(group) < 0) {
|
||||
groups.push(group);
|
||||
}
|
||||
};
|
||||
|
||||
notifications.requestNotify = function requestNotify (notify) {
|
||||
// eslint-disable-next-line no-prototype-builtins
|
||||
if (!notify.hasOwnProperty('level') || !notify.title || !notify.message || !notify.plugin) {
|
||||
console.error(new Error('Unable to request notification, since the notify isn\'t complete: ' + JSON.stringify(notify)));
|
||||
return;
|
||||
@@ -135,7 +130,7 @@ function init (env, ctx) {
|
||||
requests.snoozes.push(snooze);
|
||||
};
|
||||
|
||||
notifications.process = function process ( ) {
|
||||
notifications.process = function process () {
|
||||
|
||||
var notifyGroups = _.map(requests.notifies, function eachNotify (notify) {
|
||||
return notify.group;
|
||||
@@ -205,7 +200,7 @@ function init (env, ctx) {
|
||||
|
||||
};
|
||||
|
||||
function ifTestModeThen(callback) {
|
||||
function ifTestModeThen (callback) {
|
||||
if (env.testMode) {
|
||||
return callback();
|
||||
} else {
|
||||
@@ -213,15 +208,15 @@ function init (env, ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
notifications.resetStateForTests = function resetStateForTests ( ) {
|
||||
ifTestModeThen(function doResetStateForTests ( ) {
|
||||
notifications.resetStateForTests = function resetStateForTests () {
|
||||
ifTestModeThen(function doResetStateForTests () {
|
||||
console.info('resetting notifications state for tests');
|
||||
alarms = {};
|
||||
});
|
||||
};
|
||||
|
||||
notifications.getAlarmForTests = function getAlarmForTests (level, group) {
|
||||
return ifTestModeThen(function doResetStateForTests ( ) {
|
||||
return ifTestModeThen(function doResetStateForTests () {
|
||||
group = group || 'default';
|
||||
var alarm = getAlarm(level, group);
|
||||
console.info('got alarm for tests: ', alarm);
|
||||
@@ -249,7 +244,7 @@ function init (env, ctx) {
|
||||
};
|
||||
}
|
||||
|
||||
function logEmitEvent(notify) {
|
||||
function logEmitEvent (notify) {
|
||||
var type = notify.level >= levels.WARN ? 'ALARM' : (notify.clear ? 'ALL CLEAR' : 'NOTIFICATION');
|
||||
console.info([
|
||||
logTimestamp() + '\tEMITTING ' + type + ':'
|
||||
@@ -257,7 +252,7 @@ function init (env, ctx) {
|
||||
].join('\n'));
|
||||
}
|
||||
|
||||
function logSnoozingEvent(highestAlarm, snoozedBy) {
|
||||
function logSnoozingEvent (highestAlarm, snoozedBy) {
|
||||
console.info([
|
||||
logTimestamp() + '\tSNOOZING ALARM:'
|
||||
, ' ' + JSON.stringify(notifyToView(highestAlarm))
|
||||
@@ -267,7 +262,7 @@ function init (env, ctx) {
|
||||
}
|
||||
|
||||
//TODO: we need a common logger, but until then...
|
||||
function logTimestamp ( ) {
|
||||
function logTimestamp () {
|
||||
return (new Date).toISOString();
|
||||
}
|
||||
|
||||
|
||||
+15
-16
@@ -15,6 +15,7 @@ var AR = [-0.723, 1.716];
|
||||
//TODO: move this to css
|
||||
var AR2_COLOR = 'cyan';
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function init (ctx) {
|
||||
|
||||
var ar2 = {
|
||||
@@ -23,7 +24,7 @@ function init (ctx) {
|
||||
, pluginType: 'forecast'
|
||||
};
|
||||
|
||||
function buildTitle(prop, sbx) {
|
||||
function buildTitle (prop, sbx) {
|
||||
var rangeLabel = prop.eventName ? sbx.translate(prop.eventName, { ci: true }).toUpperCase() : sbx.translate('Check BG');
|
||||
var title = sbx.levels.toDisplay(prop.level) + ', ' + rangeLabel;
|
||||
|
||||
@@ -35,7 +36,7 @@ function init (ctx) {
|
||||
}
|
||||
|
||||
ar2.setProperties = function setProperties (sbx) {
|
||||
sbx.offerProperty('ar2', function setAR2 ( ) {
|
||||
sbx.offerProperty('ar2', function setAR2 () {
|
||||
|
||||
var prop = {
|
||||
forecast: ar2.forecast(sbx)
|
||||
@@ -49,7 +50,7 @@ function init (ctx) {
|
||||
}
|
||||
|
||||
var predicted = prop.forecast && prop.forecast.predicted;
|
||||
var scaled = predicted && _.map(predicted, function(p) { return sbx.scaleEntry(p) } );
|
||||
var scaled = predicted && _.map(predicted, function(p) { return sbx.scaleEntry(p) });
|
||||
|
||||
if (scaled && scaled.length >= 3) {
|
||||
prop.displayLine = 'BG 15m: ' + scaled[2] + ' ' + sbx.unitsLabel;
|
||||
@@ -106,8 +107,8 @@ function init (ctx) {
|
||||
return result;
|
||||
};
|
||||
|
||||
ar2.updateVisualisation = function updateVisualisation(sbx) {
|
||||
sbx.pluginBase.addForecastPoints(ar2.forecastCone(sbx), {type: 'ar2', label: 'AR2 Forecast'});
|
||||
ar2.updateVisualisation = function updateVisualisation (sbx) {
|
||||
sbx.pluginBase.addForecastPoints(ar2.forecastCone(sbx), { type: 'ar2', label: 'AR2 Forecast' });
|
||||
};
|
||||
|
||||
ar2.forecastCone = function forecastCone (sbx) {
|
||||
@@ -118,7 +119,7 @@ function init (ctx) {
|
||||
|
||||
var coneFactor = getConeFactor(sbx);
|
||||
|
||||
function pushConePoints(result, step) {
|
||||
function pushConePoints (result, step) {
|
||||
var next = incrementAR2(result);
|
||||
|
||||
//offset from points so they are at a unique time
|
||||
@@ -172,8 +173,8 @@ function init (ctx) {
|
||||
ar2.alexa = {
|
||||
intentHandlers: [{
|
||||
intent: 'MetricNow'
|
||||
, routableSlot:'metric'
|
||||
, slots:['ar2 forecast', 'forecast']
|
||||
, routableSlot: 'metric'
|
||||
, slots: ['ar2 forecast', 'forecast']
|
||||
, intentHandler: alexaAr2Handler
|
||||
}]
|
||||
};
|
||||
@@ -181,7 +182,7 @@ function init (ctx) {
|
||||
return ar2;
|
||||
}
|
||||
|
||||
function checkForecast(forecast, sbx) {
|
||||
function checkForecast (forecast, sbx) {
|
||||
var result = undefined;
|
||||
|
||||
if (forecast && forecast.avgLoss > URGENT_THRESHOLD) {
|
||||
@@ -199,7 +200,7 @@ function checkForecast(forecast, sbx) {
|
||||
}
|
||||
|
||||
function selectEventType (prop, sbx) {
|
||||
var predicted = prop.forecast && _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) } );
|
||||
var predicted = prop.forecast && _.map(prop.forecast.predicted, function(p) { return sbx.scaleEntry(p) });
|
||||
|
||||
var in20mins = predicted && predicted.length >= 4 ? predicted[3] : undefined;
|
||||
|
||||
@@ -239,7 +240,7 @@ function getConeFactor (sbx) {
|
||||
return value;
|
||||
}
|
||||
|
||||
function okToForecast(sbx) {
|
||||
function okToForecast (sbx) {
|
||||
|
||||
var bgnow = sbx.properties.bgnow;
|
||||
var delta = sbx.properties.delta;
|
||||
@@ -273,7 +274,7 @@ function incrementAR2 (result) {
|
||||
};
|
||||
}
|
||||
|
||||
function pushPoint(result) {
|
||||
function pushPoint (result) {
|
||||
var next = incrementAR2(result);
|
||||
|
||||
next.points.push(ar2Point(
|
||||
@@ -284,8 +285,7 @@ function pushPoint(result) {
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
function ar2Point(next, options) {
|
||||
function ar2Point (next, options) {
|
||||
var step = options.step || 0;
|
||||
var coneFactor = options.coneFactor || 0;
|
||||
var offset = options.offset || 0;
|
||||
@@ -301,7 +301,6 @@ function ar2Point(next, options) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function buildDebug (prop, sbx) {
|
||||
return prop.forecast && {
|
||||
forecast: {
|
||||
@@ -311,6 +310,6 @@ function buildDebug (prop, sbx) {
|
||||
};
|
||||
}
|
||||
|
||||
function log10(val) { return Math.log(val) / Math.LN10; }
|
||||
function log10 (val) { return Math.log(val) / Math.LN10; }
|
||||
|
||||
module.exports = init;
|
||||
|
||||
@@ -8,6 +8,7 @@ function init() {
|
||||
, pluginType: 'drawer'
|
||||
};
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
careportal.getEventTypes = function getEventTypes (sbx) {
|
||||
|
||||
//TODO: use sbx and new CAREPORTAL_EVENTTYPE_GROUPS="core temps combo dad sensor site etc"
|
||||
|
||||
+30
-33
@@ -4,7 +4,7 @@ var _ = require('lodash')
|
||||
, moment = require('moment')
|
||||
, times = require('../times');
|
||||
|
||||
function init(ctx) {
|
||||
function init (ctx) {
|
||||
var translate = ctx.language.translate;
|
||||
var iob = require('./iob')(ctx);
|
||||
|
||||
@@ -16,15 +16,15 @@ function init(ctx) {
|
||||
|
||||
cob.RECENCY_THRESHOLD = times.mins(30).msecs;
|
||||
|
||||
cob.setProperties = function setProperties(sbx) {
|
||||
sbx.offerProperty('cob', function setCOB ( ) {
|
||||
cob.setProperties = function setProperties (sbx) {
|
||||
sbx.offerProperty('cob', function setCOB () {
|
||||
return cob.cobTotal(sbx.data.treatments, sbx.data.devicestatus, sbx.data.profile, sbx.time);
|
||||
});
|
||||
};
|
||||
|
||||
cob.cobTotal = function cobTotal(treatments, devicestatus, profile, time, spec_profile) {
|
||||
cob.cobTotal = function cobTotal (treatments, devicestatus, profile, time, spec_profile) {
|
||||
|
||||
if (!profile || !profile.hasData()) {
|
||||
if (!profile || !profile.hasData()) {
|
||||
console.warn('For the COB plugin to function you need a treatment profile');
|
||||
return {};
|
||||
}
|
||||
@@ -55,7 +55,7 @@ function init(ctx) {
|
||||
return addDisplay(result);
|
||||
};
|
||||
|
||||
function addDisplay(cob) {
|
||||
function addDisplay (cob) {
|
||||
if (_.isEmpty(cob) || cob.cob === undefined) {
|
||||
return {};
|
||||
}
|
||||
@@ -82,7 +82,7 @@ function init(ctx) {
|
||||
var recentMills = time - cob.RECENCY_THRESHOLD;
|
||||
|
||||
return _.chain(devicestatus)
|
||||
.filter(function (cobStatus) {
|
||||
.filter(function(cobStatus) {
|
||||
return cobStatus.mills <= futureMills && cobStatus.mills >= recentMills;
|
||||
})
|
||||
.map(cob.fromDeviceStatus)
|
||||
@@ -95,7 +95,7 @@ function init(ctx) {
|
||||
cob.COBDeviceStatusesInTimeRange = function COBDeviceStatusesInTimeRange (devicestatus, from, to) {
|
||||
|
||||
return _.chain(devicestatus)
|
||||
.filter(function (cobStatus) {
|
||||
.filter(function(cobStatus) {
|
||||
return cobStatus.mills > from && cobStatus.mills < to;
|
||||
})
|
||||
.map(cob.fromDeviceStatus)
|
||||
@@ -104,7 +104,7 @@ function init(ctx) {
|
||||
.value();
|
||||
};
|
||||
|
||||
cob.fromDeviceStatus = function fromDeviceStatus(devicestatusEntry) {
|
||||
cob.fromDeviceStatus = function fromDeviceStatus (devicestatusEntry) {
|
||||
|
||||
var cobObj;
|
||||
if (_.get(devicestatusEntry, 'openaps') !== undefined) {
|
||||
@@ -140,7 +140,7 @@ function init(ctx) {
|
||||
cob: lastCOB
|
||||
, source: 'OpenAPS'
|
||||
, device: devicestatusEntry.device
|
||||
, mills: lastMoment.valueOf( )
|
||||
, mills: lastMoment.valueOf()
|
||||
};
|
||||
} else if (_.get(devicestatusEntry, 'loop.cob') !== undefined) {
|
||||
cobObj = devicestatusEntry.loop.cob;
|
||||
@@ -148,7 +148,7 @@ function init(ctx) {
|
||||
cob: cobObj.cob
|
||||
, source: 'Loop'
|
||||
, device: devicestatusEntry.device
|
||||
, mills: moment(cobObj.timestamp).valueOf( )
|
||||
, mills: moment(cobObj.timestamp).valueOf()
|
||||
};
|
||||
} else {
|
||||
return {};
|
||||
@@ -164,7 +164,7 @@ function init(ctx) {
|
||||
var isDecaying = 0;
|
||||
var lastDecayedBy = 0;
|
||||
|
||||
_.each(treatments, function eachTreatment(treatment) {
|
||||
_.each(treatments, function eachTreatment (treatment) {
|
||||
if (treatment.carbs && treatment.mills < time) {
|
||||
lastCarbs = treatment;
|
||||
var cCalc = cob.cobCalc(treatment, profile, lastDecayedBy, time, spec_profile);
|
||||
@@ -175,7 +175,7 @@ function init(ctx) {
|
||||
var actEnd = iob.calcTotal(treatments, devicestatus, profile, cCalc.decayedBy, spec_profile).activity;
|
||||
var avgActivity = (actStart + actEnd) / 2;
|
||||
// units: g = BG * scalar / BG / U * g / U
|
||||
var delayedCarbs = ( avgActivity * liverSensRatio / profile.getSensitivity(treatment.mills, spec_profile) ) * profile.getCarbRatio(treatment.mills, spec_profile);
|
||||
var delayedCarbs = (avgActivity * liverSensRatio / profile.getSensitivity(treatment.mills, spec_profile)) * profile.getCarbRatio(treatment.mills, spec_profile);
|
||||
var delayMinutes = Math.round(delayedCarbs / profile.getCarbAbsorptionRate(treatment.mills, spec_profile) * 60);
|
||||
if (delayMinutes > 0) {
|
||||
cCalc.decayedBy.setMinutes(cCalc.decayedBy.getMinutes() + delayMinutes);
|
||||
@@ -211,7 +211,7 @@ function init(ctx) {
|
||||
};
|
||||
};
|
||||
|
||||
cob.carbImpact = function carbImpact(rawCarbImpact, insulinImpact) {
|
||||
cob.carbImpact = function carbImpact (rawCarbImpact, insulinImpact) {
|
||||
var liverSensRatio = 1.0;
|
||||
var liverCarbImpactMax = 0.7;
|
||||
var liverCarbImpact = Math.min(liverCarbImpactMax, liverSensRatio * insulinImpact);
|
||||
@@ -219,12 +219,12 @@ function init(ctx) {
|
||||
var netCarbImpact = Math.max(0, rawCarbImpact - liverCarbImpact);
|
||||
var totalImpact = netCarbImpact - insulinImpact;
|
||||
return {
|
||||
netCarbImpact: netCarbImpact,
|
||||
totalImpact: totalImpact
|
||||
netCarbImpact: netCarbImpact
|
||||
, totalImpact: totalImpact
|
||||
};
|
||||
};
|
||||
|
||||
cob.cobCalc = function cobCalc(treatment, profile, lastDecayedBy, time, spec_profile) {
|
||||
cob.cobCalc = function cobCalc (treatment, profile, lastDecayedBy, time, spec_profile) {
|
||||
|
||||
var delay = 20;
|
||||
var isDecaying = 0;
|
||||
@@ -241,31 +241,28 @@ function init(ctx) {
|
||||
decayedBy.setMinutes(decayedBy.getMinutes() + Math.max(delay, minutesleft) + treatment.carbs / carbs_min);
|
||||
if (delay > minutesleft) {
|
||||
initialCarbs = parseInt(treatment.carbs);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
initialCarbs = parseInt(treatment.carbs) + minutesleft * carbs_min;
|
||||
}
|
||||
var startDecay = new Date(carbTime);
|
||||
startDecay.setMinutes(carbTime.getMinutes() + delay);
|
||||
if (time < lastDecayedBy || time > startDecay) {
|
||||
isDecaying = 1;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
isDecaying = 0;
|
||||
}
|
||||
return {
|
||||
initialCarbs: initialCarbs,
|
||||
decayedBy: decayedBy,
|
||||
isDecaying: isDecaying,
|
||||
carbTime: carbTime
|
||||
initialCarbs: initialCarbs
|
||||
, decayedBy: decayedBy
|
||||
, isDecaying: isDecaying
|
||||
, carbTime: carbTime
|
||||
};
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
cob.updateVisualisation = function updateVisualisation(sbx) {
|
||||
cob.updateVisualisation = function updateVisualisation (sbx) {
|
||||
|
||||
var prop = sbx.properties.cob;
|
||||
|
||||
@@ -273,16 +270,16 @@ function init(ctx) {
|
||||
|
||||
var displayCob = Math.round(prop.cob * 10) / 10;
|
||||
|
||||
var info = [ ];
|
||||
var info = [];
|
||||
if (prop.treatmentCOB !== undefined && prop.treatmentCOB.cob) {
|
||||
info.push({label: translate('Careportal COB'), value: Math.round(prop.treatmentCOB.cob * 10) / 10});
|
||||
info.push({ label: translate('Careportal COB'), value: Math.round(prop.treatmentCOB.cob * 10) / 10 });
|
||||
}
|
||||
|
||||
var lastCarbs = prop.lastCarbs || (prop.treatmentCOB && prop.treatmentCOB.lastCarbs);
|
||||
if (lastCarbs) {
|
||||
var when = new Date(lastCarbs.mills).toLocaleString();
|
||||
var amount = lastCarbs.carbs + 'g';
|
||||
info.push({label: translate('Last Carbs'), value: amount + ' @ ' + when});
|
||||
info.push({ label: translate('Last Carbs'), value: amount + ' @ ' + when });
|
||||
}
|
||||
|
||||
sbx.pluginBase.updatePillText(sbx, {
|
||||
@@ -305,8 +302,8 @@ function init(ctx) {
|
||||
cob.alexa = {
|
||||
intentHandlers: [{
|
||||
intent: 'MetricNow'
|
||||
, routableSlot:'metric'
|
||||
, slots:['cob', 'carbs on board', 'carbohydrates on board']
|
||||
, routableSlot: 'metric'
|
||||
, slots: ['cob', 'carbs on board', 'carbohydrates on board']
|
||||
, intentHandler: alexaCOBHandler
|
||||
}]
|
||||
};
|
||||
|
||||
+35
-36
@@ -7,12 +7,12 @@ var _get = require('lodash/get');
|
||||
var _isArray = require('lodash/isArray');
|
||||
var _map = require('lodash/map');
|
||||
|
||||
function init(ctx) {
|
||||
function init (ctx) {
|
||||
|
||||
var allPlugins = [],
|
||||
enabledPlugins = [];
|
||||
var allPlugins = []
|
||||
, enabledPlugins = [];
|
||||
|
||||
function plugins(name) {
|
||||
function plugins (name) {
|
||||
if (name) {
|
||||
return _find(allPlugins, {
|
||||
name: name
|
||||
@@ -75,18 +75,18 @@ function init(ctx) {
|
||||
, require('./basalprofile')(ctx)
|
||||
];
|
||||
|
||||
plugins.registerServerDefaults = function registerServerDefaults() {
|
||||
plugins.registerServerDefaults = function registerServerDefaults () {
|
||||
plugins.register(serverDefaultPlugins);
|
||||
return plugins;
|
||||
};
|
||||
|
||||
plugins.registerClientDefaults = function registerClientDefaults() {
|
||||
plugins.registerClientDefaults = function registerClientDefaults () {
|
||||
plugins.register(clientDefaultPlugins);
|
||||
return plugins;
|
||||
};
|
||||
|
||||
plugins.register = function register(all) {
|
||||
_each(all, function eachPlugin(plugin) {
|
||||
plugins.register = function register (all) {
|
||||
_each(all, function eachPlugin (plugin) {
|
||||
allPlugins.push(plugin);
|
||||
});
|
||||
|
||||
@@ -94,58 +94,57 @@ function init(ctx) {
|
||||
|
||||
var enable = _get(ctx, 'settings.enable');
|
||||
|
||||
function isEnabled(plugin) {
|
||||
function isEnabled (plugin) {
|
||||
//TODO: unify client/server env/app
|
||||
return enable && enable.indexOf(plugin.name) > -1;
|
||||
}
|
||||
|
||||
_each(allPlugins, function eachPlugin(plugin) {
|
||||
_each(allPlugins, function eachPlugin (plugin) {
|
||||
plugin.enabled = isEnabled(plugin);
|
||||
if (plugin.enabled) {
|
||||
enabledPlugins.push(plugin);
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
plugins.isPluginEnabled = function isPluginEnabled(pluginName) {
|
||||
var p = _.find(enabledPlugins, 'name', pluginName);
|
||||
plugins.isPluginEnabled = function isPluginEnabled (pluginName) {
|
||||
var p = _find(enabledPlugins, 'name', pluginName);
|
||||
return (p !== null);
|
||||
}
|
||||
|
||||
plugins.getPlugin = function getPlugin(pluginName) {
|
||||
return _.find(enabledPlugins, 'name', pluginName);
|
||||
plugins.getPlugin = function getPlugin (pluginName) {
|
||||
return _find(enabledPlugins, 'name', pluginName);
|
||||
}
|
||||
|
||||
plugins.eachPlugin = function eachPlugin(f) {
|
||||
plugins.eachPlugin = function eachPlugin (f) {
|
||||
_each(allPlugins, f);
|
||||
};
|
||||
|
||||
plugins.eachEnabledPlugin = function eachEnabledPlugin(f) {
|
||||
plugins.eachEnabledPlugin = function eachEnabledPlugin (f) {
|
||||
_each(enabledPlugins, f);
|
||||
};
|
||||
|
||||
//these plugins are either always on or have custom settings
|
||||
plugins.specialPlugins = 'ar2 bgnow delta direction timeago upbat rawbg errorcodes profile';
|
||||
|
||||
plugins.shownPlugins = function (sbx) {
|
||||
return _filter(enabledPlugins, function filterPlugins(plugin) {
|
||||
plugins.shownPlugins = function(sbx) {
|
||||
return _filter(enabledPlugins, function filterPlugins (plugin) {
|
||||
return plugins.specialPlugins.indexOf(plugin.name) > -1 || (sbx && sbx.showPlugins && sbx.showPlugins.indexOf(plugin.name) > -1);
|
||||
});
|
||||
};
|
||||
|
||||
plugins.eachShownPlugins = function eachShownPlugins(sbx, f) {
|
||||
plugins.eachShownPlugins = function eachShownPlugins (sbx, f) {
|
||||
_each(plugins.shownPlugins(sbx), f);
|
||||
};
|
||||
|
||||
plugins.hasShownType = function hasShownType(pluginType, sbx) {
|
||||
return _find(plugins.shownPlugins(sbx), function findWithType(plugin) {
|
||||
plugins.hasShownType = function hasShownType (pluginType, sbx) {
|
||||
return _find(plugins.shownPlugins(sbx), function findWithType (plugin) {
|
||||
return plugin.pluginType === pluginType;
|
||||
}) !== undefined;
|
||||
};
|
||||
|
||||
plugins.setProperties = function setProperties(sbx) {
|
||||
plugins.eachEnabledPlugin(function eachPlugin(plugin) {
|
||||
plugins.setProperties = function setProperties (sbx) {
|
||||
plugins.eachEnabledPlugin(function eachPlugin (plugin) {
|
||||
if (plugin.setProperties) {
|
||||
try {
|
||||
plugin.setProperties(sbx.withExtendedSettings(plugin));
|
||||
@@ -156,8 +155,8 @@ function init(ctx) {
|
||||
});
|
||||
};
|
||||
|
||||
plugins.checkNotifications = function checkNotifications(sbx) {
|
||||
plugins.eachEnabledPlugin(function eachPlugin(plugin) {
|
||||
plugins.checkNotifications = function checkNotifications (sbx) {
|
||||
plugins.eachEnabledPlugin(function eachPlugin (plugin) {
|
||||
if (plugin.checkNotifications) {
|
||||
try {
|
||||
plugin.checkNotifications(sbx.withExtendedSettings(plugin));
|
||||
@@ -168,8 +167,8 @@ function init(ctx) {
|
||||
});
|
||||
};
|
||||
|
||||
plugins.visualizeAlarm = function visualizeAlarm(sbx, alarm, alarmMessage) {
|
||||
plugins.eachShownPlugins(sbx, function eachPlugin(plugin) {
|
||||
plugins.visualizeAlarm = function visualizeAlarm (sbx, alarm, alarmMessage) {
|
||||
plugins.eachShownPlugins(sbx, function eachPlugin (plugin) {
|
||||
if (plugin.visualizeAlarm) {
|
||||
try {
|
||||
plugin.visualizeAlarm(sbx.withExtendedSettings(plugin), alarm, alarmMessage);
|
||||
@@ -180,8 +179,8 @@ function init(ctx) {
|
||||
});
|
||||
};
|
||||
|
||||
plugins.updateVisualisations = function updateVisualisations(sbx) {
|
||||
plugins.eachShownPlugins(sbx, function eachPlugin(plugin) {
|
||||
plugins.updateVisualisations = function updateVisualisations (sbx) {
|
||||
plugins.eachShownPlugins(sbx, function eachPlugin (plugin) {
|
||||
if (plugin.updateVisualisation) {
|
||||
try {
|
||||
plugin.updateVisualisation(sbx.withExtendedSettings(plugin));
|
||||
@@ -192,9 +191,9 @@ function init(ctx) {
|
||||
});
|
||||
};
|
||||
|
||||
plugins.getAllEventTypes = function getAllEventTypes(sbx) {
|
||||
plugins.getAllEventTypes = function getAllEventTypes (sbx) {
|
||||
var all = [];
|
||||
plugins.eachEnabledPlugin(function eachPlugin(plugin) {
|
||||
plugins.eachEnabledPlugin(function eachPlugin (plugin) {
|
||||
if (plugin.getEventTypes) {
|
||||
var eventTypes = plugin.getEventTypes(sbx.withExtendedSettings(plugin));
|
||||
if (_isArray(eventTypes)) {
|
||||
@@ -206,15 +205,15 @@ function init(ctx) {
|
||||
return all;
|
||||
};
|
||||
|
||||
plugins.enabledPluginNames = function enabledPluginNames() {
|
||||
return _map(enabledPlugins, function mapped(plugin) {
|
||||
plugins.enabledPluginNames = function enabledPluginNames () {
|
||||
return _map(enabledPlugins, function mapped (plugin) {
|
||||
return plugin.name;
|
||||
}).join(' ');
|
||||
};
|
||||
|
||||
plugins.extendedClientSettings = function extendedClientSettings(allExtendedSettings) {
|
||||
plugins.extendedClientSettings = function extendedClientSettings (allExtendedSettings) {
|
||||
var clientSettings = {};
|
||||
_each(clientDefaultPlugins, function eachClientPlugin(plugin) {
|
||||
_each(clientDefaultPlugins, function eachClientPlugin (plugin) {
|
||||
clientSettings[plugin.name] = allExtendedSettings[plugin.name];
|
||||
});
|
||||
|
||||
|
||||
+25
-31
@@ -7,7 +7,7 @@ var levels = require('../levels');
|
||||
|
||||
// var ALL_STATUS_FIELDS = ['status-symbol', 'status-label', 'iob', 'freq', 'rssi']; Unused variable
|
||||
|
||||
function init(ctx) {
|
||||
function init (ctx) {
|
||||
var utils = require('../utils')(ctx);
|
||||
|
||||
var loop = {
|
||||
@@ -18,7 +18,7 @@ function init(ctx) {
|
||||
|
||||
var firstPrefs = true;
|
||||
|
||||
loop.getPrefs = function getPrefs(sbx) {
|
||||
loop.getPrefs = function getPrefs (sbx) {
|
||||
|
||||
var prefs = {
|
||||
warn: sbx.extendedSettings.warn ? sbx.extendedSettings.warn : 30
|
||||
@@ -35,7 +35,7 @@ function init(ctx) {
|
||||
};
|
||||
|
||||
loop.setProperties = function setProperties (sbx) {
|
||||
sbx.offerProperty('loop', function setLoop ( ) {
|
||||
sbx.offerProperty('loop', function setLoop () {
|
||||
return loop.analyzeData(sbx);
|
||||
});
|
||||
};
|
||||
@@ -45,9 +45,9 @@ function init(ctx) {
|
||||
var recentMills = sbx.time - times.hours(recentHours).msecs;
|
||||
|
||||
var recentData = _.chain(sbx.data.devicestatus)
|
||||
.filter(function (status) {
|
||||
.filter(function(status) {
|
||||
return ('loop' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills;
|
||||
}).value( );
|
||||
}).value();
|
||||
|
||||
var prefs = loop.getPrefs(sbx);
|
||||
var recent = moment(sbx.time).subtract(prefs.warn / 2, 'minutes');
|
||||
@@ -146,7 +146,7 @@ function init(ctx) {
|
||||
return result;
|
||||
};
|
||||
|
||||
loop.checkNotifications = function checkNotifications(sbx) {
|
||||
loop.checkNotifications = function checkNotifications (sbx) {
|
||||
var prefs = loop.getPrefs(sbx);
|
||||
|
||||
if (!prefs.enableAlerts) { return; }
|
||||
@@ -182,9 +182,9 @@ function init(ctx) {
|
||||
return (value != null) ? prefix + value : '';
|
||||
}
|
||||
|
||||
var events = [ ];
|
||||
var events = [];
|
||||
|
||||
function addRecommendedTempBasal() {
|
||||
function addRecommendedTempBasal () {
|
||||
if (prop.lastLoop && prop.lastLoop.recommendedTempBasal) {
|
||||
|
||||
var recommendedTempBasal = prop.lastLoop.recommendedTempBasal;
|
||||
@@ -196,7 +196,7 @@ function init(ctx) {
|
||||
|
||||
valueParts = concatIOB(valueParts);
|
||||
valueParts = concatCOB(valueParts);
|
||||
valueParts = concatEventualBG (valueParts);
|
||||
valueParts = concatEventualBG(valueParts);
|
||||
valueParts = concatRecommendedBolus(valueParts);
|
||||
|
||||
events.push({
|
||||
@@ -206,7 +206,7 @@ function init(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
function addRSSI() {
|
||||
function addRSSI () {
|
||||
|
||||
var mostRecent = "";
|
||||
var pumpRSSI = "";
|
||||
@@ -257,19 +257,19 @@ function init(ctx) {
|
||||
|
||||
}
|
||||
|
||||
function addLastEnacted() {
|
||||
function addLastEnacted () {
|
||||
if (prop.lastEnacted) {
|
||||
var canceled = prop.lastEnacted.rate === 0 && prop.lastEnacted.duration === 0;
|
||||
|
||||
var valueParts = [
|
||||
, '<b>Temp Basal' + (canceled ? ' Canceled' : ' Started') + '</b>'
|
||||
'<b>Temp Basal' + (canceled ? ' Canceled' : ' Started') + '</b>'
|
||||
, canceled ? '' : ' ' + prop.lastEnacted.rate.toFixed(2) + 'U/hour for ' + prop.lastEnacted.duration + 'm'
|
||||
, valueString(', ', prop.lastEnacted.reason)
|
||||
];
|
||||
|
||||
valueParts = concatIOB(valueParts);
|
||||
valueParts = concatCOB(valueParts);
|
||||
valueParts = concatEventualBG (valueParts);
|
||||
valueParts = concatEventualBG(valueParts);
|
||||
valueParts = concatRecommendedBolus(valueParts);
|
||||
|
||||
events.push({
|
||||
@@ -284,7 +284,9 @@ function init(ctx) {
|
||||
var iob = prop.lastLoop.iob;
|
||||
valueParts = valueParts.concat([
|
||||
', IOB: '
|
||||
|
||||
, sbx.roundInsulinForDisplayFormat(iob.iob) + 'U'
|
||||
|
||||
, iob.basaliob ? ', Basal IOB ' + sbx.roundInsulinForDisplayFormat(iob.basaliob) + 'U' : ''
|
||||
]);
|
||||
}
|
||||
@@ -294,7 +296,6 @@ function init(ctx) {
|
||||
|
||||
function concatCOB (valueParts) {
|
||||
if (prop.lastLoop && prop.lastLoop.cob) {
|
||||
var cob = prop.lastLoop.cob;
|
||||
var cob = prop.lastLoop.cob.cob;
|
||||
cob = Math.round(cob);
|
||||
valueParts = valueParts.concat([
|
||||
@@ -309,9 +310,9 @@ function init(ctx) {
|
||||
function concatEventualBG (valueParts) {
|
||||
if (prop.lastLoop && prop.lastLoop.predicted) {
|
||||
var predictedBGvalues = prop.lastLoop.predicted.values;
|
||||
var eventualBG = predictedBGvalues[predictedBGvalues.length-1];
|
||||
var maxBG = Math.max.apply(null,predictedBGvalues);
|
||||
var minBG = Math.min.apply(null,predictedBGvalues);
|
||||
var eventualBG = predictedBGvalues[predictedBGvalues.length - 1];
|
||||
var maxBG = Math.max.apply(null, predictedBGvalues);
|
||||
var minBG = Math.min.apply(null, predictedBGvalues);
|
||||
var eventualBGscaled = sbx.settings.units === 'mmol' ?
|
||||
sbx.roundBGToDisplayFormat(sbx.scaleMgdl(eventualBG)) : eventualBG;
|
||||
var maxBGscaled = sbx.settings.units === 'mmol' ?
|
||||
@@ -324,7 +325,7 @@ function init(ctx) {
|
||||
, minBGscaled
|
||||
, '-'
|
||||
, maxBGscaled
|
||||
,', Eventual BG: '
|
||||
, ', Eventual BG: '
|
||||
, eventualBGscaled
|
||||
]);
|
||||
}
|
||||
@@ -344,8 +345,8 @@ function init(ctx) {
|
||||
return valueParts;
|
||||
}
|
||||
|
||||
function getForecastPoints ( ) {
|
||||
var points = [ ];
|
||||
function getForecastPoints () {
|
||||
var points = [];
|
||||
|
||||
function toPoints (startTime, offset) {
|
||||
return function toPoint (value, index) {
|
||||
@@ -364,12 +365,6 @@ function init(ctx) {
|
||||
if (predicted.values) {
|
||||
points = points.concat(_.map(predicted.values, toPoints(startTime, 0)));
|
||||
}
|
||||
// if (prop.lastPredBGs.IOB) {
|
||||
// points = points.concat(_.map(prop.lastPredBGs.IOB, toPoints(moment, 3000)));
|
||||
// }
|
||||
// if (prop.lastPredBGs.COB) {
|
||||
// points = points.concat(_.map(prop.lastPredBGs.COB, toPoints(moment, 7000)));
|
||||
// }
|
||||
}
|
||||
|
||||
return points;
|
||||
@@ -391,7 +386,7 @@ function init(ctx) {
|
||||
|
||||
addRSSI();
|
||||
|
||||
var sorted = _.sortBy(events, function toMill(event) {
|
||||
var sorted = _.sortBy(events, function toMill (event) {
|
||||
return event.time.valueOf();
|
||||
}).reverse();
|
||||
|
||||
@@ -411,7 +406,7 @@ function init(ctx) {
|
||||
var eventualBGValue = '';
|
||||
if (prop.lastLoop && prop.lastLoop.predicted) {
|
||||
var predictedBGvalues = prop.lastLoop.predicted.values;
|
||||
var eventualBG = predictedBGvalues[predictedBGvalues.length-1];
|
||||
var eventualBG = predictedBGvalues[predictedBGvalues.length - 1];
|
||||
if (sbx.settings.units === 'mmol') {
|
||||
eventualBG = sbx.roundBGToDisplayFormat(sbx.scaleMgdl(eventualBG));
|
||||
}
|
||||
@@ -432,7 +427,7 @@ function init(ctx) {
|
||||
|
||||
var forecastPoints = getForecastPoints();
|
||||
if (forecastPoints && forecastPoints.length > 0) {
|
||||
sbx.pluginBase.addForecastPoints(forecastPoints, {type: 'loop', label: 'Loop Forecasts'});
|
||||
sbx.pluginBase.addForecastPoints(forecastPoints, { type: 'loop', label: 'Loop Forecasts' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -470,7 +465,7 @@ function init(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
function alexaLastLoopHandler(next, slots, sbx) {
|
||||
function alexaLastLoopHandler (next, slots, sbx) {
|
||||
console.log(JSON.stringify(sbx.properties.loop.lastLoop));
|
||||
var response = 'The last successful loop was ' + moment(sbx.properties.loop.lastOkMoment).from(moment(sbx.time));
|
||||
next('Last loop', response);
|
||||
@@ -523,5 +518,4 @@ function init(ctx) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
module.exports = init;
|
||||
|
||||
+51
-28
@@ -7,7 +7,7 @@ var levels = require('../levels');
|
||||
|
||||
// var ALL_STATUS_FIELDS = ['status-symbol', 'status-label', 'iob', 'meal-assist', 'freq', 'rssi']; Unused variable
|
||||
|
||||
function init(ctx) {
|
||||
function init (ctx) {
|
||||
var utils = require('../utils')(ctx);
|
||||
var openaps = {
|
||||
name: 'openaps'
|
||||
@@ -17,7 +17,7 @@ function init(ctx) {
|
||||
var translate = ctx.language.translate;
|
||||
var firstPrefs = true;
|
||||
|
||||
openaps.getPrefs = function getPrefs(sbx) {
|
||||
openaps.getPrefs = function getPrefs (sbx) {
|
||||
|
||||
function cleanList (value) {
|
||||
return decodeURIComponent(value || '').toLowerCase().split(' ');
|
||||
@@ -27,7 +27,6 @@ function init(ctx) {
|
||||
return _.isEmpty(list) || _.isEmpty(list[0]);
|
||||
}
|
||||
|
||||
|
||||
var fields = cleanList(sbx.extendedSettings.fields);
|
||||
fields = isEmpty(fields) ? ['status-symbol', 'status-label', 'iob', 'meal-assist', 'rssi'] : fields;
|
||||
|
||||
@@ -51,7 +50,7 @@ function init(ctx) {
|
||||
};
|
||||
|
||||
openaps.setProperties = function setProperties (sbx) {
|
||||
sbx.offerProperty('openaps', function setOpenAPS ( ) {
|
||||
sbx.offerProperty('openaps', function setOpenAPS () {
|
||||
return openaps.analyzeData(sbx);
|
||||
});
|
||||
};
|
||||
@@ -61,10 +60,10 @@ function init(ctx) {
|
||||
var recentMills = sbx.time - times.hours(recentHours).msecs;
|
||||
|
||||
var recentData = _.chain(sbx.data.devicestatus)
|
||||
.filter(function (status) {
|
||||
.filter(function(status) {
|
||||
return ('openaps' in status) && sbx.entryMills(status) <= sbx.time && sbx.entryMills(status) >= recentMills;
|
||||
})
|
||||
.map(function (status) {
|
||||
.map(function(status) {
|
||||
if (status.openaps && _.isArray(status.openaps.iob) && status.openaps.iob.length > 0) {
|
||||
status.openaps.iob = status.openaps.iob[0];
|
||||
if (status.openaps.iob.time) {
|
||||
@@ -73,7 +72,7 @@ function init(ctx) {
|
||||
}
|
||||
return status;
|
||||
})
|
||||
.value( );
|
||||
.value();
|
||||
|
||||
var prefs = openaps.getPrefs(sbx);
|
||||
var recent = moment(sbx.time).subtract(prefs.warn / 2, 'minutes');
|
||||
@@ -88,7 +87,7 @@ function init(ctx) {
|
||||
, lastPredBGs: null
|
||||
};
|
||||
|
||||
function getDevice(status) {
|
||||
function getDevice (status) {
|
||||
var uri = status.device || 'device';
|
||||
var device = result.seenDevices[uri];
|
||||
|
||||
@@ -122,8 +121,7 @@ function init(ctx) {
|
||||
};
|
||||
|
||||
if (moments.notEnacted && (
|
||||
(moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent)))
|
||||
) {
|
||||
(moments.enacted && moments.notEnacted.isAfter(moments.enacted)) || (!moments.enacted && moments.notEnacted.isAfter(recent)))) {
|
||||
status.symbol = 'x';
|
||||
status.code = 'notenacted';
|
||||
status.label = 'Not Enacted';
|
||||
@@ -160,7 +158,7 @@ function init(ctx) {
|
||||
enacted.moment = moment(enacted.timestamp);
|
||||
result.lastEnacted = enacted;
|
||||
if (enacted.predBGs && (!result.lastPredBGs || enacted.moment.isAfter(result.lastPredBGs.moment))) {
|
||||
result.lastPredBGs = _.isArray(enacted.predBGs) ? {values: enacted.predBGs} : enacted.predBGs;
|
||||
result.lastPredBGs = _.isArray(enacted.predBGs) ? { values: enacted.predBGs } : enacted.predBGs;
|
||||
result.lastPredBGs.moment = enacted.moment;
|
||||
}
|
||||
}
|
||||
@@ -175,7 +173,7 @@ function init(ctx) {
|
||||
suggested.moment = moment(suggested.timestamp);
|
||||
result.lastSuggested = suggested;
|
||||
if (suggested.predBGs && (!result.lastPredBGs || suggested.moment.isAfter(result.lastPredBGs.moment))) {
|
||||
result.lastPredBGs = _.isArray(suggested.predBGs) ? {values: suggested.predBGs} : suggested.predBGs;
|
||||
result.lastPredBGs = _.isArray(suggested.predBGs) ? { values: suggested.predBGs } : suggested.predBGs;
|
||||
result.lastPredBGs.moment = suggested.moment;
|
||||
}
|
||||
}
|
||||
@@ -240,23 +238,48 @@ function init(ctx) {
|
||||
{
|
||||
val: 'Temporary Target'
|
||||
, name: 'Temporary Target'
|
||||
, bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false
|
||||
, targets: true, reasons: reasonconf
|
||||
, bg: false
|
||||
, insulin: false
|
||||
, carbs: false
|
||||
, prebolus: false
|
||||
, duration: true
|
||||
, percent: false
|
||||
, absolute: false
|
||||
, profile: false
|
||||
, split: false
|
||||
, targets: true
|
||||
, reasons: reasonconf
|
||||
}
|
||||
, {
|
||||
val: 'Temporary Target Cancel'
|
||||
, name: 'Temporary Target Cancel'
|
||||
, bg: false, insulin: false, carbs: false, prebolus: false, duration: false, percent: false, absolute: false, profile: false, split: false
|
||||
, bg: false
|
||||
, insulin: false
|
||||
, carbs: false
|
||||
, prebolus: false
|
||||
, duration: false
|
||||
, percent: false
|
||||
, absolute: false
|
||||
, profile: false
|
||||
, split: false
|
||||
}
|
||||
, {
|
||||
val: 'OpenAPS Offline'
|
||||
, name: 'OpenAPS Offline'
|
||||
, bg: false, insulin: false, carbs: false, prebolus: false, duration: true, percent: false, absolute: false, profile: false, split: false
|
||||
, bg: false
|
||||
, insulin: false
|
||||
, carbs: false
|
||||
, prebolus: false
|
||||
, duration: true
|
||||
, percent: false
|
||||
, absolute: false
|
||||
, profile: false
|
||||
, split: false
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
openaps.checkNotifications = function checkNotifications(sbx) {
|
||||
openaps.checkNotifications = function checkNotifications (sbx) {
|
||||
var prefs = openaps.getPrefs(sbx);
|
||||
|
||||
if (!prefs.enableAlerts) { return; }
|
||||
@@ -283,8 +306,8 @@ function init(ctx) {
|
||||
}
|
||||
};
|
||||
|
||||
openaps.findOfflineMarker = function findOfflineMarker(sbx) {
|
||||
return _.findLast(sbx.data.treatments, function match(treatment) {
|
||||
openaps.findOfflineMarker = function findOfflineMarker (sbx) {
|
||||
return _.findLast(sbx.data.treatments, function match (treatment) {
|
||||
var eventTime = sbx.entryMills(treatment);
|
||||
var eventEnd = treatment.duration ? eventTime + times.mins(treatment.duration).msecs : eventTime;
|
||||
return eventTime <= sbx.time && treatment.eventType === 'OpenAPS Offline' && eventEnd >= sbx.time;
|
||||
@@ -302,9 +325,9 @@ function init(ctx) {
|
||||
return value ? prefix + value : '';
|
||||
}
|
||||
|
||||
var events = [ ];
|
||||
var events = [];
|
||||
|
||||
function addSuggestion() {
|
||||
function addSuggestion () {
|
||||
if (prop.lastSuggested) {
|
||||
|
||||
var valueParts = [
|
||||
@@ -337,8 +360,8 @@ function init(ctx) {
|
||||
return valueParts;
|
||||
}
|
||||
|
||||
function getForecastPoints ( ) {
|
||||
var points = [ ];
|
||||
function getForecastPoints () {
|
||||
var points = [];
|
||||
|
||||
function toPoints (offset, forecastType) {
|
||||
return function toPoint (value, index) {
|
||||
@@ -413,7 +436,7 @@ function init(ctx) {
|
||||
}
|
||||
|
||||
if (device.mmtune) {
|
||||
var best = _.maxBy(device.mmtune.scanDetails, function (d) {
|
||||
var best = _.maxBy(device.mmtune.scanDetails, function(d) {
|
||||
return d[2];
|
||||
});
|
||||
|
||||
@@ -430,7 +453,7 @@ function init(ctx) {
|
||||
});
|
||||
});
|
||||
|
||||
var sorted = _.sortBy(events, function toMill(event) {
|
||||
var sorted = _.sortBy(events, function toMill (event) {
|
||||
return event.time.valueOf();
|
||||
}).reverse();
|
||||
|
||||
@@ -455,7 +478,7 @@ function init(ctx) {
|
||||
|
||||
var forecastPoints = getForecastPoints();
|
||||
if (forecastPoints && forecastPoints.length > 0) {
|
||||
sbx.pluginBase.addForecastPoints(forecastPoints, {type: 'openaps', label: 'OpenAPS Forecasts'});
|
||||
sbx.pluginBase.addForecastPoints(forecastPoints, { type: 'openaps', label: 'OpenAPS Forecasts' });
|
||||
}
|
||||
};
|
||||
|
||||
@@ -464,8 +487,8 @@ function init(ctx) {
|
||||
var response = translate('alexaOpenAPSForecast', {
|
||||
params: [
|
||||
sbx.properties.openaps.lastEventualBG
|
||||
]}
|
||||
);
|
||||
]
|
||||
});
|
||||
next('Loop Forecast', response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var levels = require('../levels');
|
||||
var times = require('../times');
|
||||
|
||||
var lastEntryValue;
|
||||
var lastTime;
|
||||
var lastMinutes;
|
||||
var lastEntryTime;
|
||||
|
||||
@@ -78,7 +74,7 @@ function init(ctx) {
|
||||
lastMinutes = timeMinutes;
|
||||
|
||||
var lastEntryString = translate('Last entry {0} minutes ago');
|
||||
var sayIt = lastEntryString.replace('{0}', timeMinutes);
|
||||
sayIt = lastEntryString.replace('{0}', timeMinutes);
|
||||
speech.say(sayIt);
|
||||
}
|
||||
}
|
||||
|
||||
+16
-31
@@ -12,7 +12,7 @@ var prevBasalTreatment = null;
|
||||
|
||||
function init (profileData) {
|
||||
|
||||
var profile = { };
|
||||
var profile = {};
|
||||
var cache = new c.Cache();
|
||||
|
||||
profile.loadData = function loadData (profileData) {
|
||||
@@ -27,7 +27,7 @@ function init (profileData) {
|
||||
|
||||
profile.convertToProfileStore = function convertToProfileStore (dataArray) {
|
||||
var convertedProfiles = [];
|
||||
_.each(dataArray, function (profile) {
|
||||
_.each(dataArray, function(profile) {
|
||||
if (!profile.defaultProfile) {
|
||||
var newObject = {};
|
||||
newObject.defaultProfile = 'Default';
|
||||
@@ -51,13 +51,13 @@ function init (profileData) {
|
||||
|
||||
profile.timeStringToSeconds = function timeStringToSeconds (time) {
|
||||
var split = time.split(':');
|
||||
return parseInt(split[0])*3600 + parseInt(split[1])*60;
|
||||
return parseInt(split[0]) * 3600 + parseInt(split[1]) * 60;
|
||||
};
|
||||
|
||||
// preprocess the timestamps to seconds for a couple orders of magnitude faster operation
|
||||
profile.preprocessProfileOnLoad = function preprocessProfileOnLoad (container) {
|
||||
_.each(container, function eachValue (value) {
|
||||
if( Object.prototype.toString.call(value) === '[object Array]' ) {
|
||||
if (Object.prototype.toString.call(value) === '[object Array]') {
|
||||
profile.preprocessProfileOnLoad(value);
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ function init (profileData) {
|
||||
|
||||
returnValue = valueContainer;
|
||||
|
||||
if( Object.prototype.toString.call(valueContainer) === '[object Array]' ) {
|
||||
if (Object.prototype.toString.call(valueContainer) === '[object Array]') {
|
||||
_.each(valueContainer, function eachValue (value) {
|
||||
if (timeAsSecondsFromMidnight >= value.timeAsSeconds) {
|
||||
returnValue = value.value;
|
||||
@@ -197,7 +197,7 @@ function init (profileData) {
|
||||
t.endmills = t.mills + times.mins(t.duration || 0).msecs;
|
||||
});
|
||||
|
||||
profile.tempbasaltreatments.sort (function compareTreatmentMills (a, b) {
|
||||
profile.tempbasaltreatments.sort(function compareTreatmentMills (a, b) {
|
||||
return a.mills - b.mills;
|
||||
});
|
||||
|
||||
@@ -231,7 +231,7 @@ function init (profileData) {
|
||||
|
||||
var treatment = null;
|
||||
if (profile.hasData()) {
|
||||
profile.profiletreatments.forEach( function eachTreatment (t) {
|
||||
profile.profiletreatments.forEach(function eachTreatment (t) {
|
||||
if (time >= t.mills && t.mills >= profile.data[0].mills) {
|
||||
var duration = times.mins(t.duration || 0).msecs;
|
||||
if (duration != 0 && time < t.mills + duration) {
|
||||
@@ -240,7 +240,7 @@ function init (profileData) {
|
||||
if (treatment.profileJson && !profile.data[0].store[treatment.profile]) {
|
||||
if (treatment.profile.indexOf("@@@@@") < 0)
|
||||
treatment.profile += "@@@@@" + treatment.mills;
|
||||
var json = JSON.parse(treatment.profileJson);
|
||||
let json = JSON.parse(treatment.profileJson);
|
||||
profile.data[0].store[treatment.profile] = json;
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ function init (profileData) {
|
||||
if (treatment.profileJson && !profile.data[0].store[treatment.profile]) {
|
||||
if (treatment.profile.indexOf("@@@@@") < 0)
|
||||
treatment.profile += "@@@@@" + treatment.mills;
|
||||
var json = JSON.parse(treatment.profileJson);
|
||||
let json = JSON.parse(treatment.profileJson);
|
||||
profile.data[0].store[treatment.profile] = json;
|
||||
}
|
||||
}
|
||||
@@ -263,7 +263,7 @@ function init (profileData) {
|
||||
return returnValue;
|
||||
};
|
||||
|
||||
profile.profileSwitchName = function profileSwitchName(name) {
|
||||
profile.profileSwitchName = function profileSwitchName (name) {
|
||||
var index = name.indexOf("@@@@@");
|
||||
if (index < 0) return name;
|
||||
else return name.substring(0, index);
|
||||
@@ -277,7 +277,8 @@ function init (profileData) {
|
||||
}
|
||||
|
||||
// Binary search for events for O(log n) performance
|
||||
var first = 0, last = profile.tempbasaltreatments.length - 1;
|
||||
var first = 0
|
||||
, last = profile.tempbasaltreatments.length - 1;
|
||||
|
||||
while (first <= last) {
|
||||
var i = first + Math.floor((last - first) / 2);
|
||||
@@ -298,7 +299,7 @@ function init (profileData) {
|
||||
|
||||
profile.comboBolusTreatment = function comboBolusTreatment (time) {
|
||||
var treatment = null;
|
||||
profile.combobolustreatments.forEach( function eachTreatment (t) {
|
||||
profile.combobolustreatments.forEach(function eachTreatment (t) {
|
||||
var duration = times.mins(t.duration || 0).msecs;
|
||||
if (time < t.mills + duration && time > t.mills) {
|
||||
treatment = t;
|
||||
@@ -349,29 +350,13 @@ function init (profileData) {
|
||||
var current = profile.activeProfileToTime();
|
||||
profiles.push(current);
|
||||
|
||||
for (var key in profile.data[0].store) {
|
||||
if (profile.data[0].store.hasOwnProperty(key) && key !== current) {
|
||||
if (key.indexOf('@@@@@') < 0)
|
||||
profiles.push(key);
|
||||
}
|
||||
}
|
||||
Object.keys(profile.data[0].store).forEach(key => {
|
||||
if (key !== current && key.indexOf('@@@@@') < 0) profiles.push(key);
|
||||
})
|
||||
}
|
||||
return profiles;
|
||||
};
|
||||
|
||||
// get original store without added profiles fro profileSwitches
|
||||
profile.getProfileStore = function getProfileStore () {
|
||||
var newprofiledata = _.clone(profile.data[0]);
|
||||
for (var key in profile.data[0].store) {
|
||||
if (profile.data[0].store.hasOwnProperty(key)) {
|
||||
if (key.indexOf('@@@@@') < 0)
|
||||
store[key] = profile.data[0].store[key];
|
||||
}
|
||||
}
|
||||
return store;
|
||||
};
|
||||
|
||||
|
||||
if (profileData) { profile.loadData(profileData); }
|
||||
// init treatments array
|
||||
profile.updateTreatments([], []);
|
||||
|
||||
@@ -8,30 +8,29 @@ var calibrations = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return calibrations;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
calibrations.html = function html(client) {
|
||||
calibrations.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Calibrations') + '</h2>'
|
||||
+ '<div style="width:50%;height:500px;float:left;overflow:scroll;overflow-x:hidden;" id="calibrations-list"></div>'
|
||||
+ '<div style="width:48%;float:right;" id="calibrations-chart"></div>'
|
||||
;
|
||||
'<h2>' + translate('Calibrations') + '</h2>' +
|
||||
'<div style="width:50%;height:500px;float:left;overflow:scroll;overflow-x:hidden;" id="calibrations-list"></div>' +
|
||||
'<div style="width:48%;float:right;" id="calibrations-chart"></div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
calibrations.report = function report_calibrations(datastorage,sorteddaystoshow) {
|
||||
calibrations.report = function report_calibrations (datastorage, sorteddaystoshow) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var report_plugins = Nightscout.report_plugins;
|
||||
|
||||
var padding = { top: 15, right: 15, bottom: 30, left: 70 };
|
||||
var treatments = [];
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
treatments = treatments.concat(datastorage[day].treatments.filter(function (t) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
treatments = treatments.concat(datastorage[day].treatments.filter(function(t) {
|
||||
if (t.eventType === 'Sensor Start') {
|
||||
return true;
|
||||
}
|
||||
@@ -43,41 +42,40 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
});
|
||||
|
||||
var cals = [];
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
cals = cals.concat(datastorage[day].cal);
|
||||
});
|
||||
|
||||
var sgvs = [];
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
sgvs = sgvs.concat(datastorage[day].sgv);
|
||||
});
|
||||
|
||||
var mbgs = [];
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
mbgs = mbgs.concat(datastorage[day].mbg);
|
||||
});
|
||||
mbgs.forEach(function (mbg) { calcmbg(mbg); });
|
||||
|
||||
mbgs.forEach(function(mbg) { calcmbg(mbg); });
|
||||
|
||||
var events = treatments.concat(cals).concat(mbgs).sort(function(a, b) { return a.mills - b.mills; });
|
||||
|
||||
var colors = ['Aqua','Blue','Brown','Chartreuse','Coral','CornflowerBlue','DarkCyan','DarkMagenta','DarkOrange','Fuchsia','Green','Yellow'];
|
||||
var colors = ['Aqua', 'Blue', 'Brown', 'Chartreuse', 'Coral', 'CornflowerBlue', 'DarkCyan', 'DarkMagenta', 'DarkOrange', 'Fuchsia', 'Green', 'Yellow'];
|
||||
var colorindex = 0;
|
||||
var html = '<table>';
|
||||
var lastmbg = null;
|
||||
for (var i=0; i<events.length; i++) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
var e = events[i];
|
||||
colorindex = (e.device !== undefined ? (colorindex+1)%colors.length : colorindex);
|
||||
colorindex = (e.device !== undefined ? (colorindex + 1) % colors.length : colorindex);
|
||||
var currentcolor = (!e.eventType ? colors[colorindex] : 'White');
|
||||
|
||||
html += '<tr>';
|
||||
html += '<td>' + report_plugins.utils.localeDateTime(new Date(e.mills)) + '</td><td style="background-color:'+currentcolor+'">';
|
||||
html += '<td>' + report_plugins.utils.localeDateTime(new Date(e.mills)) + '</td><td style="background-color:' + currentcolor + '">';
|
||||
e.bgcolor = colors[colorindex];
|
||||
if (e.eventType) {
|
||||
html += '<b style="text-decoration: underline;padding-left:0em">'+translate(e.eventType)+'</b>:<br>';
|
||||
html += '<b style="text-decoration: underline;padding-left:0em">' + translate(e.eventType) + '</b>:<br>';
|
||||
} else if (typeof e.device !== 'undefined') {
|
||||
html += '<input type="checkbox" index="'+i+'" class="calibrations-checkbox" id="calibrations-'+i+'"> ';
|
||||
html += '<b style="padding-left:2em">MBG</b>: ' + e.y + ' Raw: '+e.raw+'<br>';
|
||||
html += '<input type="checkbox" index="' + i + '" class="calibrations-checkbox" id="calibrations-' + i + '"> ';
|
||||
html += '<b style="padding-left:2em">MBG</b>: ' + e.y + ' Raw: ' + e.raw + '<br>';
|
||||
lastmbg = e;
|
||||
e.cals = [];
|
||||
e.checked = false;
|
||||
@@ -90,7 +88,7 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
html += JSON.stringify(e);
|
||||
}
|
||||
html += '</td></tr>';
|
||||
};
|
||||
}
|
||||
|
||||
html += '</table>';
|
||||
|
||||
@@ -103,27 +101,27 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
$('.calibrations-checkbox').change(checkboxevent);
|
||||
|
||||
function checkLastCheckboxes (maxcals) {
|
||||
for (i=events.length-1; i>0; i--) {
|
||||
for (i = events.length - 1; i > 0; i--) {
|
||||
if (typeof events[i].device !== 'undefined') {
|
||||
events[i].checked = true;
|
||||
$('#calibrations-'+i).prop('checked',true);
|
||||
if (--maxcals<1) {
|
||||
$('#calibrations-' + i).prop('checked', true);
|
||||
if (--maxcals < 1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkboxevent(event) {
|
||||
function checkboxevent (event) {
|
||||
var index = $(this).attr('index');
|
||||
events[index].checked = $(this).is(':checked');
|
||||
drawelements();
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
function drawelements() {
|
||||
function drawelements () {
|
||||
drawChart();
|
||||
for (var i=0; i<events.length; i++) {
|
||||
for (var i = 0; i < events.length; i++) {
|
||||
e = events[i];
|
||||
if (e.checked) {
|
||||
drawmbg(e);
|
||||
@@ -132,9 +130,9 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
}
|
||||
}
|
||||
|
||||
var calibration_context,xScale2,yScale2 ;
|
||||
var calibration_context, xScale2, yScale2;
|
||||
|
||||
function drawChart() {
|
||||
function drawChart () {
|
||||
var maxBG = 500;
|
||||
|
||||
$('#calibrations-chart').empty();
|
||||
@@ -149,10 +147,10 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
|
||||
// define the parts of the axis that aren't dependent on width or height
|
||||
xScale2 = d3.scale.linear()
|
||||
.domain([0,maxBG]);
|
||||
.domain([0, maxBG]);
|
||||
|
||||
yScale2 = d3.scale.linear()
|
||||
.domain([0,400000]);
|
||||
.domain([0, 400000]);
|
||||
|
||||
var xAxis2 = d3.svg.axis()
|
||||
.scale(xScale2)
|
||||
@@ -164,7 +162,7 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
.orient('left');
|
||||
|
||||
// get current data range
|
||||
var dataRange = [0,maxBG];
|
||||
var dataRange = [0, maxBG];
|
||||
var width = 600;
|
||||
var height = 500;
|
||||
|
||||
@@ -178,7 +176,7 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
|
||||
// ranges are based on the width and height available so reset
|
||||
xScale2.range([0, chartWidth]);
|
||||
yScale2.range([chartHeight,0]);
|
||||
yScale2.range([chartHeight, 0]);
|
||||
|
||||
// create the x axis container
|
||||
calibration_context.append('g')
|
||||
@@ -189,7 +187,7 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
.attr('class', 'y axis');
|
||||
|
||||
calibration_context.select('.y')
|
||||
.attr('transform', 'translate(' + (/*chartWidth + */ padding.left) + ',' + padding.top + ')')
|
||||
.attr('transform', 'translate(' + ( /*chartWidth + */ padding.left) + ',' + padding.top + ')')
|
||||
.style('stroke', 'black')
|
||||
.style('shape-rendering', 'crispEdges')
|
||||
.style('fill', 'none')
|
||||
@@ -203,58 +201,58 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
.style('fill', 'none')
|
||||
.call(xAxis2);
|
||||
|
||||
[50000,100000,150000,200000,250000,300000,350000,400000].forEach(function (li) {
|
||||
[50000, 100000, 150000, 200000, 250000, 300000, 350000, 400000].forEach(function(li) {
|
||||
calibration_context.append('line')
|
||||
.attr('class', 'high-line')
|
||||
.attr('x1', xScale2(dataRange[0])+padding.left)
|
||||
.attr('y1', yScale2(li)+padding.top)
|
||||
.attr('x2', xScale2(dataRange[1])+padding.left)
|
||||
.attr('y2', yScale2(li)+padding.top)
|
||||
.attr('x1', xScale2(dataRange[0]) + padding.left)
|
||||
.attr('y1', yScale2(li) + padding.top)
|
||||
.attr('x2', xScale2(dataRange[1]) + padding.left)
|
||||
.attr('y2', yScale2(li) + padding.top)
|
||||
.style('stroke-dasharray', ('3, 3'))
|
||||
.attr('stroke', 'grey');
|
||||
});
|
||||
[50,100,150,200,250,300,350,400,450,500].forEach(function (li) {
|
||||
[50, 100, 150, 200, 250, 300, 350, 400, 450, 500].forEach(function(li) {
|
||||
calibration_context.append('line')
|
||||
.attr('class', 'high-line')
|
||||
.attr('x1', xScale2(li)+padding.left)
|
||||
.attr('x1', xScale2(li) + padding.left)
|
||||
.attr('y1', padding.top)
|
||||
.attr('x2', xScale2(li)+padding.left)
|
||||
.attr('y2', chartHeight+padding.top)
|
||||
.attr('x2', xScale2(li) + padding.left)
|
||||
.attr('y2', chartHeight + padding.top)
|
||||
.style('stroke-dasharray', ('3, 3'))
|
||||
.attr('stroke', 'grey');
|
||||
});
|
||||
}
|
||||
|
||||
function drawcal(cal) {
|
||||
function drawcal (cal) {
|
||||
var color = cal.bgcolor;
|
||||
var y1 = 50000;
|
||||
var x1 = cal.scale * (y1 - cal.intercept) / cal.slope;
|
||||
var y2 = 400000;
|
||||
var x2 = cal.scale * (y2 - cal.intercept) / cal.slope;
|
||||
calibration_context.append('line')
|
||||
.attr('x1', xScale2(x1)+padding.left)
|
||||
.attr('y1', yScale2(y1)+padding.top)
|
||||
.attr('x2', xScale2(x2)+padding.left)
|
||||
.attr('y2', yScale2(y2)+padding.top)
|
||||
.attr('x1', xScale2(x1) + padding.left)
|
||||
.attr('y1', yScale2(y1) + padding.top)
|
||||
.attr('x2', xScale2(x2) + padding.left)
|
||||
.attr('y2', yScale2(y2) + padding.top)
|
||||
.style('stroke-width', 3)
|
||||
.attr('stroke', color);
|
||||
}
|
||||
|
||||
function calcmbg(mbg) {
|
||||
var lastsgv = findlatest(new Date(mbg.mills),sgvs);
|
||||
function calcmbg (mbg) {
|
||||
var lastsgv = findlatest(new Date(mbg.mills), sgvs);
|
||||
|
||||
if (lastsgv) {
|
||||
if (mbg.mills-lastsgv.mills>5*60*1000) {
|
||||
console.log('Last SGV too old for MBG. Time diff: '+((mbg.mills-lastsgv.mills)/1000/60).toFixed(1)+' min',mbg);
|
||||
if (mbg.mills - lastsgv.mills > 5 * 60 * 1000) {
|
||||
console.log('Last SGV too old for MBG. Time diff: ' + ((mbg.mills - lastsgv.mills) / 1000 / 60).toFixed(1) + ' min', mbg);
|
||||
} else {
|
||||
mbg.raw = lastsgv.filtered || lastsgv.unfiltered;
|
||||
}
|
||||
} else {
|
||||
console.log('Last entry not found for MBG ',mbg);
|
||||
console.log('Last entry not found for MBG ', mbg);
|
||||
}
|
||||
}
|
||||
|
||||
function drawmbg(mbg) {
|
||||
function drawmbg (mbg) {
|
||||
var color = mbg.bgcolor;
|
||||
if (mbg.raw) {
|
||||
calibration_context.append('circle')
|
||||
@@ -268,10 +266,10 @@ calibrations.report = function report_calibrations(datastorage,sorteddaystoshow)
|
||||
}
|
||||
}
|
||||
|
||||
function findlatest(date,storage) {
|
||||
function findlatest (date, storage) {
|
||||
var last = null;
|
||||
var time = date.getTime();
|
||||
for (var i=0; i<storage.length; i++) {
|
||||
for (var i = 0; i < storage.length; i++) {
|
||||
if (storage[i].mills > time) {
|
||||
return last;
|
||||
}
|
||||
|
||||
@@ -6,36 +6,34 @@ var dailystats = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return dailystats;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
dailystats.html = function html(client) {
|
||||
dailystats.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Daily stats report') + '</h2>'
|
||||
+ '<div id="dailystats-report"></div>'
|
||||
;
|
||||
'<h2>' + translate('Daily stats report') + '</h2>' +
|
||||
'<div id="dailystats-report"></div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
dailystats.css =
|
||||
'#dailystats-placeholder .tdborder {'
|
||||
+ ' width:80px;'
|
||||
+ ' border: 1px #ccc solid;'
|
||||
+ ' margin: 0;'
|
||||
+ ' padding: 1px;'
|
||||
+ ' text-align:center;'
|
||||
+ '}'
|
||||
+ '#dailystats-placeholder .inlinepiechart {'
|
||||
+ ' width: 2.0in;'
|
||||
+ ' height: 0.9in;'
|
||||
+ '}'
|
||||
;
|
||||
'#dailystats-placeholder .tdborder {' +
|
||||
' width:80px;' +
|
||||
' border: 1px #ccc solid;' +
|
||||
' margin: 0;' +
|
||||
' padding: 1px;' +
|
||||
' text-align:center;' +
|
||||
'}' +
|
||||
'#dailystats-placeholder .inlinepiechart {' +
|
||||
' width: 2.0in;' +
|
||||
' height: 0.9in;' +
|
||||
'}';
|
||||
|
||||
dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,options) {
|
||||
dailystats.report = function report_dailystats (datastorage, sorteddaystoshow, options) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
var translate = client.translate;
|
||||
@@ -52,31 +50,31 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti
|
||||
report.append(table);
|
||||
var thead = $('<tr/>');
|
||||
$('<th></th>').appendTo(thead);
|
||||
$('<th>'+translate('Date')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Low')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Normal')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('High')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Readings')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Min')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Max')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Average')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('StDev')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('25%')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('Median')+'</th>').appendTo(thead);
|
||||
$('<th>'+translate('75%')+'</th>').appendTo(thead);
|
||||
$('<th>' + translate('Date') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Low') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Normal') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('High') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Readings') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Min') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Max') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Average') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('StDev') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('25%') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('Median') + '</th>').appendTo(thead);
|
||||
$('<th>' + translate('75%') + '</th>').appendTo(thead);
|
||||
thead.appendTo(table);
|
||||
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
var tr = $('<tr>');
|
||||
|
||||
var daysRecords = datastorage[day].statsrecords;
|
||||
|
||||
if (daysRecords.length === 0) {
|
||||
$('<td/>').appendTo(tr);
|
||||
$('<td class=\"tdborder\" style=\"width:160px\">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\"colspan="10">'+translate('No data available')+'</td>').appendTo(tr);
|
||||
$('<td class="tdborder" style="width:160px">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder"colspan="10">' + translate('No data available') + '</td>').appendTo(tr);
|
||||
table.append(tr);
|
||||
return;;
|
||||
return;
|
||||
}
|
||||
|
||||
minForDay = daysRecords[0].sgv;
|
||||
@@ -101,53 +99,52 @@ dailystats.report = function report_dailystats(datastorage,sorteddaystoshow,opti
|
||||
sum += record.sgv;
|
||||
return out;
|
||||
}, {
|
||||
lows: 0,
|
||||
normal: 0,
|
||||
highs: 0
|
||||
lows: 0
|
||||
, normal: 0
|
||||
, highs: 0
|
||||
});
|
||||
var average = sum / daysRecords.length;
|
||||
|
||||
var bgValues = daysRecords.map(function(r) { return r.sgv; });
|
||||
$('<td><div id=\"dailystat-chart-' + day.toString() + '\" class=\"inlinepiechart\"></div></td>').appendTo(tr);
|
||||
$('<td><div id="dailystat-chart-' + day.toString() + '" class="inlinepiechart"></div></td>').appendTo(tr);
|
||||
|
||||
$('<td class=\"tdborder\" style=\"width:160px\">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + Math.round((100 * stats.lows) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + Math.round((100 * stats.normal) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + Math.round((100 * stats.highs) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + daysRecords.length +'</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + minForDay +'</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + maxForDay +'</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + average.toFixed(1) +'</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + ss.standard_deviation(bgValues).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.25).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.5).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class=\"tdborder\">' + ss.quantile(bgValues, 0.75).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder" style="width:160px">' + report_plugins.utils.localeDate(day) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + Math.round((100 * stats.lows) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + Math.round((100 * stats.normal) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + Math.round((100 * stats.highs) / daysRecords.length) + '%</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + daysRecords.length + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + minForDay + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + maxForDay + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + average.toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + ss.standard_deviation(bgValues).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + ss.quantile(bgValues, 0.25).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + ss.quantile(bgValues, 0.5).toFixed(1) + '</td>').appendTo(tr);
|
||||
$('<td class="tdborder">' + ss.quantile(bgValues, 0.75).toFixed(1) + '</td>').appendTo(tr);
|
||||
|
||||
table.append(tr);
|
||||
var inrange = [
|
||||
{
|
||||
label: translate('Low'),
|
||||
data: Math.round(stats.lows * 1000 / daysRecords.length) / 10
|
||||
},
|
||||
{
|
||||
label: translate('In Range'),
|
||||
data: Math.round(stats.normal * 1000 / daysRecords.length) / 10
|
||||
},
|
||||
{
|
||||
label: translate('High'),
|
||||
data: Math.round(stats.highs * 1000 / daysRecords.length) / 10
|
||||
label: translate('Low')
|
||||
, data: Math.round(stats.lows * 1000 / daysRecords.length) / 10
|
||||
}
|
||||
, {
|
||||
label: translate('In Range')
|
||||
, data: Math.round(stats.normal * 1000 / daysRecords.length) / 10
|
||||
}
|
||||
, {
|
||||
label: translate('High')
|
||||
, data: Math.round(stats.highs * 1000 / daysRecords.length) / 10
|
||||
}
|
||||
];
|
||||
$.plot(
|
||||
'#dailystat-chart-' + day.toString(),
|
||||
inrange,
|
||||
{
|
||||
'#dailystat-chart-' + day.toString()
|
||||
, inrange, {
|
||||
series: {
|
||||
pie: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
colors: ['#f88', '#8f8', '#ff8']
|
||||
}
|
||||
, colors: ['#f88', '#8f8', '#ff8']
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
+166
-171
@@ -11,71 +11,70 @@ var daytoday = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return daytoday;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
daytoday.html = function html(client) {
|
||||
daytoday.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Day to day') + '</h2>'
|
||||
+ '<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>'
|
||||
+ translate('Display') + ': '
|
||||
+ '<input type="checkbox" id="rp_optionsinsulin" checked><span style="color:blue;opacity:0.5">'+translate('Insulin')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionscarbs" checked><span style="color:red;opacity:0.5">'+translate('Carbs')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionsbasal" checked><span style="color:#0099ff;opacity:0.5">'+translate('Basal rate')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionsnotes">'+translate('Notes')
|
||||
+ '<input type="checkbox" id="rp_optionsfood" checked>'+translate('Food')
|
||||
+ '<input type="checkbox" id="rp_optionsraw"><span style="color:gray;opacity:1">'+translate('Raw')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionsiob"><span style="color:blue;opacity:0.5">'+translate('IOB')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionscob"><span style="color:red;opacity:0.5">'+translate('COB')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionspredicted"><span style="color:sienna;opacity:0.5">'+translate('Predictions')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionsopenaps"><span style="color:sienna;opacity:0.5">'+translate('OpenAPS')+'</span>'
|
||||
+ '<input type="checkbox" id="rp_optionsdistribution" checked><span style="color:blue;opacity:0.5">'+translate('Insulin distribution')+'</span>'
|
||||
+ ' '+translate('Size')
|
||||
+ ' <select id="rp_size">'
|
||||
+ ' <option x="800" y="250">800x250px</option>'
|
||||
+ ' <option x="1000" y="300" selected>1000x300px</option>'
|
||||
+ ' <option x="1200" y="400">1200x400px</option>'
|
||||
+ ' <option x="1550" y="600">1550x600px</option>'
|
||||
+ ' <option x="2400" y="800">2400x800px</option>'
|
||||
+ '</select>'
|
||||
+ '<br>'
|
||||
+ translate('Scale') + ': '
|
||||
+ '<input type="radio" name="rp_scale" id="rp_linear" checked>'
|
||||
+ translate('Linear')
|
||||
+ '<input type="radio" name="rp_scale" id="rp_log">'
|
||||
+ translate('Logarithmic')
|
||||
+ '<div id="rp_predictedSettings" style="display:none">'
|
||||
+ translate('Truncate predictions: ')
|
||||
+ '<input type="checkbox" id="rp_optionsPredictedTruncate" checked>'
|
||||
+ '<br>'
|
||||
+ translate('Predictions offset') + ': '
|
||||
+ '<b><label id="rp_predictedOffset"></label> minutes</b>'
|
||||
+ ' '
|
||||
+ '<input type="button" onclick="predictMoreBackward();" value="' + translate('-30 min')+'">'
|
||||
+ '<input type="button" onclick="predictBackward();" value="' + translate('-5 min')+'">'
|
||||
+ '<input type="button" onclick="predictResetToZero();" value="' + translate('Zero')+'">'
|
||||
+ '<input type="button" onclick="predictForward();" value="' + translate('+5 min')+'">'
|
||||
+ '<input type="button" onclick="predictMoreForward();" value="' + translate('+30 min')+'">'
|
||||
+ '</div>'
|
||||
+ '<br>'
|
||||
+ '<div id="daytodaycharts">'
|
||||
+ '</div>'
|
||||
;
|
||||
'<h2>' + translate('Day to day') + '</h2>' +
|
||||
'<b>' + translate('To see this report, press SHOW while in this view') + '</b><br>' +
|
||||
translate('Display') + ': ' +
|
||||
'<input type="checkbox" id="rp_optionsinsulin" checked><span style="color:blue;opacity:0.5">' + translate('Insulin') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionscarbs" checked><span style="color:red;opacity:0.5">' + translate('Carbs') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionsbasal" checked><span style="color:#0099ff;opacity:0.5">' + translate('Basal rate') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionsnotes">' + translate('Notes') +
|
||||
'<input type="checkbox" id="rp_optionsfood" checked>' + translate('Food') +
|
||||
'<input type="checkbox" id="rp_optionsraw"><span style="color:gray;opacity:1">' + translate('Raw') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionsiob"><span style="color:blue;opacity:0.5">' + translate('IOB') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionscob"><span style="color:red;opacity:0.5">' + translate('COB') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionspredicted"><span style="color:sienna;opacity:0.5">' + translate('Predictions') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionsopenaps"><span style="color:sienna;opacity:0.5">' + translate('OpenAPS') + '</span>' +
|
||||
'<input type="checkbox" id="rp_optionsdistribution" checked><span style="color:blue;opacity:0.5">' + translate('Insulin distribution') + '</span>' +
|
||||
' ' + translate('Size') +
|
||||
' <select id="rp_size">' +
|
||||
' <option x="800" y="250">800x250px</option>' +
|
||||
' <option x="1000" y="300" selected>1000x300px</option>' +
|
||||
' <option x="1200" y="400">1200x400px</option>' +
|
||||
' <option x="1550" y="600">1550x600px</option>' +
|
||||
' <option x="2400" y="800">2400x800px</option>' +
|
||||
'</select>' +
|
||||
'<br>' +
|
||||
translate('Scale') + ': ' +
|
||||
'<input type="radio" name="rp_scale" id="rp_linear" checked>' +
|
||||
translate('Linear') +
|
||||
'<input type="radio" name="rp_scale" id="rp_log">' +
|
||||
translate('Logarithmic') +
|
||||
'<div id="rp_predictedSettings" style="display:none">' +
|
||||
translate('Truncate predictions: ') +
|
||||
'<input type="checkbox" id="rp_optionsPredictedTruncate" checked>' +
|
||||
'<br>' +
|
||||
translate('Predictions offset') + ': ' +
|
||||
'<b><label id="rp_predictedOffset"></label> minutes</b>' +
|
||||
' ' +
|
||||
'<input type="button" onclick="predictMoreBackward();" value="' + translate('-30 min') + '">' +
|
||||
'<input type="button" onclick="predictBackward();" value="' + translate('-5 min') + '">' +
|
||||
'<input type="button" onclick="predictResetToZero();" value="' + translate('Zero') + '">' +
|
||||
'<input type="button" onclick="predictForward();" value="' + translate('+5 min') + '">' +
|
||||
'<input type="button" onclick="predictMoreForward();" value="' + translate('+30 min') + '">' +
|
||||
'</div>' +
|
||||
'<br>' +
|
||||
'<div id="daytodaycharts">' +
|
||||
'</div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
daytoday.prepareHtml = function daytodayPrepareHtml(sorteddaystoshow) {
|
||||
daytoday.prepareHtml = function daytodayPrepareHtml (sorteddaystoshow) {
|
||||
$('#daytodaycharts').html('');
|
||||
sorteddaystoshow.forEach(function eachDay(d) {
|
||||
sorteddaystoshow.forEach(function eachDay (d) {
|
||||
$('#daytodaycharts').append($('<table><tr><td><div id="daytodaychart-' + d + '"></div></td><td><div id="daytodaystatchart-' + d + '"></td></tr></table>'));
|
||||
});
|
||||
};
|
||||
|
||||
daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options) {
|
||||
daytoday.report = function report_daytoday (datastorage, sorteddaystoshow, options) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
var translate = client.translate;
|
||||
@@ -92,9 +91,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
var proteinSum = 0;
|
||||
var fatSum = 0;
|
||||
|
||||
daytoday.prepareHtml(sorteddaystoshow) ;
|
||||
sorteddaystoshow.forEach( function eachDay(day) {
|
||||
drawChart(day,datastorage[day],options);
|
||||
daytoday.prepareHtml(sorteddaystoshow);
|
||||
sorteddaystoshow.forEach(function eachDay (day) {
|
||||
drawChart(day, datastorage[day], options);
|
||||
});
|
||||
|
||||
var tddAverage = tddSum / datastorage.alldays;
|
||||
@@ -102,18 +101,17 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
var proteinAverage = proteinSum / datastorage.alldays;
|
||||
var fatAverage = fatSum / datastorage.alldays;
|
||||
|
||||
|
||||
if (options.insulindistribution)
|
||||
$('#daytodaycharts').append('<br><br><b>' + translate('TDD average') + ':</b> ' + tddAverage.toFixed(1) + 'U <b>'
|
||||
+ translate('Carbs average') + ':</b> ' + carbsAverage.toFixed(0) + 'g'
|
||||
+ translate('Protein average') + ':</b> ' + proteinAverage.toFixed(0) + 'g'
|
||||
+ translate('Fat average') + ':</b> ' + fatAverage.toFixed(0) + 'g'
|
||||
$('#daytodaycharts').append('<br><br><b>' + translate('TDD average') + ':</b> ' + tddAverage.toFixed(1) + 'U <b>' +
|
||||
translate('Carbs average') + ':</b> ' + carbsAverage.toFixed(0) + 'g' +
|
||||
translate('Protein average') + ':</b> ' + proteinAverage.toFixed(0) + 'g' +
|
||||
translate('Fat average') + ':</b> ' + fatAverage.toFixed(0) + 'g'
|
||||
);
|
||||
|
||||
function timeTicks(n,i) {
|
||||
function timeTicks (n, i) {
|
||||
var t12 = [
|
||||
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', '',
|
||||
'12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
|
||||
'12am', '', '2am', '', '4am', '', '6am', '', '8am', '', '10am', ''
|
||||
, '12pm', '', '2pm', '', '4pm', '', '6pm', '', '8pm', '', '10pm', '', '12am'
|
||||
];
|
||||
if (Nightscout.client.settings.timeFormat === 24) {
|
||||
return ('00' + i).slice(-2);
|
||||
@@ -122,14 +120,14 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
}
|
||||
}
|
||||
|
||||
function drawChart(day,data,options) {
|
||||
function drawChart (day, data, options) {
|
||||
var tickValues
|
||||
, charts
|
||||
, context
|
||||
, xScale2, yScale2
|
||||
, yInsulinScale, yCarbsScale, yScaleBasals
|
||||
, xAxis2, yAxis2
|
||||
, dateFn = function (d) { return new Date(d.date); }
|
||||
, dateFn = function(d) { return new Date(d.date); }
|
||||
, foodtexts = 0;
|
||||
|
||||
tickValues = client.ticks(client, {
|
||||
@@ -158,8 +156,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
// create svg and g to contain the chart contents
|
||||
charts = d3.select('#daytodaychart-' + day).html(
|
||||
'<b>'+
|
||||
report_plugins.utils.localeDate(day)+
|
||||
'<b>' +
|
||||
report_plugins.utils.localeDate(day) +
|
||||
'</b><br>'
|
||||
).append('svg');
|
||||
|
||||
@@ -187,7 +185,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.domain([-2 * options.maxInsulinValue, 2 * options.maxInsulinValue]);
|
||||
|
||||
yCarbsScale = d3.scale.linear()
|
||||
.domain([0, options.maxCarbsValue*1.25]);
|
||||
.domain([0, options.maxCarbsValue * 1.25]);
|
||||
|
||||
yScaleBasals = d3.scale.linear();
|
||||
|
||||
@@ -216,17 +214,17 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
// ranges are based on the width and height available so reset
|
||||
xScale2.range([0, chartWidth]);
|
||||
yScale2.range([chartHeight,0]);
|
||||
yScale2.range([chartHeight, 0]);
|
||||
yInsulinScale.range([chartHeight * 2, 0]);
|
||||
yCarbsScale.range([chartHeight,0]);
|
||||
yCarbsScale.range([chartHeight, 0]);
|
||||
yScaleBasals.range([yScale2(client.utils.scaleMgdl(72)), chartHeight]);
|
||||
|
||||
// add target BG rect
|
||||
context.append('rect')
|
||||
.attr('x', xScale2(dataRange[0])+padding.left)
|
||||
.attr('y', yScale2(options.targetHigh)+padding.top)
|
||||
.attr('width', xScale2(dataRange[1]- xScale2(dataRange[0])))
|
||||
.attr('height', yScale2(options.targetLow)-yScale2(options.targetHigh))
|
||||
.attr('x', xScale2(dataRange[0]) + padding.left)
|
||||
.attr('y', yScale2(options.targetHigh) + padding.top)
|
||||
.attr('width', xScale2(dataRange[1] - xScale2(dataRange[0])))
|
||||
.attr('height', yScale2(options.targetLow) - yScale2(options.targetHigh))
|
||||
.style('fill', '#D6FFD6')
|
||||
.attr('stroke', 'grey');
|
||||
|
||||
@@ -253,27 +251,23 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.style('fill', 'none')
|
||||
.call(xAxis2);
|
||||
|
||||
_.each(tickValues, function (n, li) {
|
||||
_.each(tickValues, function(n, li) {
|
||||
context.append('line')
|
||||
.attr('class', 'high-line')
|
||||
.attr('x1', xScale2(dataRange[0])+padding.left)
|
||||
.attr('y1', yScale2(tickValues[li])+padding.top)
|
||||
.attr('x2', xScale2(dataRange[1])+padding.left)
|
||||
.attr('y2', yScale2(tickValues[li])+padding.top)
|
||||
.attr('x1', xScale2(dataRange[0]) + padding.left)
|
||||
.attr('y1', yScale2(tickValues[li]) + padding.top)
|
||||
.attr('x2', xScale2(dataRange[1]) + padding.left)
|
||||
.attr('y2', yScale2(tickValues[li]) + padding.top)
|
||||
.style('stroke-dasharray', ('1, 5'))
|
||||
.attr('stroke', 'grey');
|
||||
});
|
||||
|
||||
// bind up the context chart data to an array of circles
|
||||
var contextCircles = context.selectAll('circle')
|
||||
.data(data.sgv);
|
||||
|
||||
function prepareContextCircles(sel) {
|
||||
function prepareContextCircles (sel) {
|
||||
var badData = [];
|
||||
sel.attr('cx', function (d) {
|
||||
sel.attr('cx', function(d) {
|
||||
return xScale2(d.date) + padding.left;
|
||||
})
|
||||
.attr('cy', function (d) {
|
||||
.attr('cy', function(d) {
|
||||
if (isNaN(d.sgv)) {
|
||||
badData.push(d);
|
||||
return yScale2(client.utils.scaleMgdl(450) + padding.top);
|
||||
@@ -281,15 +275,15 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
return yScale2(d.sgv) + padding.top;
|
||||
}
|
||||
})
|
||||
.attr('fill', function (d) {
|
||||
.attr('fill', function(d) {
|
||||
if (d.color === 'gray' && !options.raw) {
|
||||
return 'transparent';
|
||||
}
|
||||
return d.color;
|
||||
})
|
||||
.style('opacity', function () { return 0.5 })
|
||||
.attr('stroke-width', function (d) {if (d.type === 'mbg') { return 2; } else if (options.openAps && d.openaps) { return 1; } else { return 0; }})
|
||||
.attr('stroke', function () { return 'black'; })
|
||||
.style('opacity', function() { return 0.5 })
|
||||
.attr('stroke-width', function(d) { if (d.type === 'mbg') { return 2; } else if (options.openAps && d.openaps) { return 1; } else { return 0; } })
|
||||
.attr('stroke', function() { return 'black'; })
|
||||
.attr('r', function(d) {
|
||||
if (d.type === 'mbg') {
|
||||
return 4;
|
||||
@@ -297,12 +291,12 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
return 2 + (options.width - 800) / 400;
|
||||
}
|
||||
})
|
||||
.on('mouseover', function (d) {
|
||||
.on('mouseover', function(d) {
|
||||
if (options.openAps && d.openaps) {
|
||||
client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9);
|
||||
var text = '<b>BG:</b> ' + d.openaps.suggested.bg
|
||||
+ ', ' + d.openaps.suggested.reason
|
||||
+ (d.openaps.suggested.mealAssist ? ' <b>Meal Assist:</b> ' + d.openaps.suggested.mealAssist : '');
|
||||
var text = '<b>BG:</b> ' + d.openaps.suggested.bg +
|
||||
', ' + d.openaps.suggested.reason +
|
||||
(d.openaps.suggested.mealAssist ? ' <b>Meal Assist:</b> ' + d.openaps.suggested.mealAssist : '');
|
||||
client.tooltip.html(text)
|
||||
.style('left', (d3.event.pageX) + 'px')
|
||||
.style('top', (d3.event.pageY + 15) + 'px');
|
||||
@@ -318,7 +312,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
// PREDICTIONS START
|
||||
//
|
||||
function preparePredictedData() {
|
||||
function preparePredictedData () {
|
||||
|
||||
var treatmentsTimestamps = []; // Only timestamps for (carbs and bolus insulin) treatments will be captured in this array
|
||||
treatmentsTimestamps.push(dataRange[0]); // Create a fake timestamp at midnight so we can show predictions during night
|
||||
@@ -340,7 +334,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
var predictions = [];
|
||||
if (data && data.devicestatus) {
|
||||
for (var i = data.devicestatus.length - 1; i >= 0; i--) {
|
||||
for (i = data.devicestatus.length - 1; i >= 0; i--) {
|
||||
if (data.devicestatus[i].loop && data.devicestatus[i].loop.predicted) {
|
||||
predictions.push(data.devicestatus[i].loop.predicted);
|
||||
} else if (data.devicestatus[i].openaps && data.devicestatus[i].openaps.suggested && data.devicestatus[i].openaps.suggested.predBGs) {
|
||||
@@ -363,10 +357,11 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
// Iterate over all treatments, find the predictions for each and add them to the predicted array p
|
||||
for (var treatmentsIndex = 0; treatmentsIndex < treatmentsTimestamps.length; treatmentsIndex++) {
|
||||
var timestamp = treatmentsTimestamps[treatmentsIndex];
|
||||
// TODO / BUG: predictedOffset is not set
|
||||
var predictedIndex = findPredicted(predictions, timestamp, predictedOffset); // Find predictions offset before or after timestamp
|
||||
|
||||
if (predictedIndex != null) {
|
||||
var entry = predictions[predictedIndex]; // Start entry
|
||||
entry = predictions[predictedIndex]; // Start entry
|
||||
var d = moment(entry.startDate);
|
||||
var end = moment().endOf('day');
|
||||
if (options.predictedTruncate) {
|
||||
@@ -399,7 +394,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
/* Find the earliest new predicted instance that has a timestamp equal to or larger than timestamp */
|
||||
/* (so if we have bolused or eaten we want to find the prediction that Loop has estimated just after that) */
|
||||
/* Returns the index into the predictions array that is the predicted we are looking for */
|
||||
function findPredicted(predictions, timestamp, offset) {
|
||||
function findPredicted (predictions, timestamp, offset) {
|
||||
var ts = moment(timestamp).add(offset, 'minutes');
|
||||
var predicted = null;
|
||||
if (offset && offset < 0) { // If offset is negative, start searching from first prediction going forward
|
||||
@@ -409,7 +404,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
}
|
||||
}
|
||||
} else { // If offset is positive or zero, start searching from last prediction going backward
|
||||
for (var i = predictions.length - 1; i > 0; i--) {
|
||||
for (i = predictions.length - 1; i > 0; i--) {
|
||||
if (predictions[i] && predictions[i].startDate && moment(predictions[i].startDate) >= ts) {
|
||||
predicted = i;
|
||||
}
|
||||
@@ -420,7 +415,6 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
//
|
||||
// PREDICTIONS ENDS
|
||||
|
||||
|
||||
// bind up the context chart data to an array of circles
|
||||
var contextData = (options.predicted ? data.sgv.concat(preparePredictedData()) : data.sgv);
|
||||
var contextCircles = context.selectAll('circle').data(contextData);
|
||||
@@ -433,7 +427,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
var to = moment(day).add(1, 'days');
|
||||
var from = moment(day);
|
||||
var iobpolyline = '', cobpolyline = '';
|
||||
var iobpolyline = ''
|
||||
, cobpolyline = '';
|
||||
|
||||
// basals data
|
||||
var linedata = [];
|
||||
@@ -448,7 +443,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
data.netBasalPositive = [];
|
||||
data.netBasalNegative = [];
|
||||
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23].forEach(function(hour) {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) {
|
||||
data.netBasalPositive[hour] = 0;
|
||||
data.netBasalNegative[hour] = 0;
|
||||
});
|
||||
@@ -469,9 +464,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
console.log("Device COB status available: ", cobStatusAvailable);
|
||||
console.log("Device IOB status available: ", iobStatusAvailable);
|
||||
|
||||
for (var dt=moment(from); dt < to; dt.add(5, 'minutes')) {
|
||||
for (var dt = moment(from); dt < to; dt.add(5, 'minutes')) {
|
||||
if (options.iob && !iobStatusAvailable) {
|
||||
var iob = client.plugins('iob').calcTotal(datastorage.treatments,datastorage.devicestatus,profile,dt.toDate()).iob;
|
||||
var iob = client.plugins('iob').calcTotal(datastorage.treatments, datastorage.devicestatus, profile, dt.toDate()).iob;
|
||||
// make the graph discontinuous when data is missing
|
||||
if (iob === undefined) {
|
||||
iobpolyline += ', ' + (xScale2(lastDt) + padding.left) + ',' + (yInsulinScale(0) + padding.top);
|
||||
@@ -480,13 +475,13 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
if (lastIOB === undefined) {
|
||||
iobpolyline += ', ' + (xScale2(dt) + padding.left) + ',' + (yInsulinScale(0) + padding.top);
|
||||
}
|
||||
iobpolyline += ', '+ (xScale2(dt) + padding.left) + ',' + (yInsulinScale(iob) + padding.top);
|
||||
iobpolyline += ', ' + (xScale2(dt) + padding.left) + ',' + (yInsulinScale(iob) + padding.top);
|
||||
}
|
||||
lastDt = dt.clone();
|
||||
lastIOB = iob;
|
||||
}
|
||||
if (options.cob && !cobStatusAvailable) {
|
||||
var cob = client.plugins('cob').cobTotal(datastorage.treatments,datastorage.devicestatus,profile,dt.toDate()).cob;
|
||||
var cob = client.plugins('cob').cobTotal(datastorage.treatments, datastorage.devicestatus, profile, dt.toDate()).cob;
|
||||
if (!dt.isSame(from)) {
|
||||
cobpolyline += ', ';
|
||||
}
|
||||
@@ -502,26 +497,27 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
if (tempPart > 0) {
|
||||
positiveTemps += tempPart;
|
||||
data.netBasalPositive[hournow] += tempPart;
|
||||
} if (tempPart < 0) {
|
||||
}
|
||||
if (tempPart < 0) {
|
||||
negativeTemps += tempPart;
|
||||
data.netBasalNegative[hournow] += tempPart;
|
||||
}
|
||||
|
||||
if (!_.isEqual(lastbasal, basalvalue)) {
|
||||
linedata.push( { d: date, b: basalvalue.totalbasal } );
|
||||
notemplinedata.push( { d: date, b: basalvalue.basal } );
|
||||
linedata.push({ d: date, b: basalvalue.totalbasal });
|
||||
notemplinedata.push({ d: date, b: basalvalue.basal });
|
||||
if (basalvalue.combobolustreatment && basalvalue.combobolustreatment.relative) {
|
||||
tempbasalareadata.push( { d: date, b: basalvalue.tempbasal } );
|
||||
basalareadata.push( { d: date, b: 0 } );
|
||||
comboareadata.push( { d: date, b: basalvalue.totalbasal } );
|
||||
tempbasalareadata.push({ d: date, b: basalvalue.tempbasal });
|
||||
basalareadata.push({ d: date, b: 0 });
|
||||
comboareadata.push({ d: date, b: basalvalue.totalbasal });
|
||||
} else if (basalvalue.treatment) {
|
||||
tempbasalareadata.push( { d: date, b: basalvalue.totalbasal } );
|
||||
basalareadata.push( { d: date, b: 0 } );
|
||||
comboareadata.push( { d: date, b: 0 } );
|
||||
tempbasalareadata.push({ d: date, b: basalvalue.totalbasal });
|
||||
basalareadata.push({ d: date, b: 0 });
|
||||
comboareadata.push({ d: date, b: 0 });
|
||||
} else {
|
||||
tempbasalareadata.push( { d: date, b: 0 } );
|
||||
basalareadata.push( { d: date, b: basalvalue.totalbasal } );
|
||||
comboareadata.push( { d: date, b: 0 } );
|
||||
tempbasalareadata.push({ d: date, b: 0 });
|
||||
basalareadata.push({ d: date, b: basalvalue.totalbasal });
|
||||
comboareadata.push({ d: date, b: 0 });
|
||||
}
|
||||
}
|
||||
lastbasal = basalvalue;
|
||||
@@ -552,8 +548,8 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
// Draw IOB from devicestatuses if available
|
||||
if (iobStatusAvailable) {
|
||||
var lastdate = 0;
|
||||
var previousdate = 0;
|
||||
lastdate = 0;
|
||||
previousdate = 0;
|
||||
var iobArray = client.plugins('iob').IOBDeviceStatusesInTimeRange(datastorage.devicestatus, from.valueOf(), to.valueOf());
|
||||
_.each(iobArray, function drawCob (point) {
|
||||
if (previousdate !== 0 && point.mills - previousdate > times.mins(15).msecs) {
|
||||
@@ -577,24 +573,24 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('stroke', 'blue')
|
||||
.attr('opacity', '0.5')
|
||||
.attr('fill-opacity', '0.1')
|
||||
.attr('points',iobpolyline);
|
||||
.attr('points', iobpolyline);
|
||||
}
|
||||
if (options.cob) {
|
||||
context.append('polyline')
|
||||
.attr('stroke', 'red')
|
||||
.attr('opacity', '0.5')
|
||||
.attr('fill-opacity', '0.1')
|
||||
.attr('points',cobpolyline);
|
||||
.attr('points', cobpolyline);
|
||||
}
|
||||
|
||||
if (options.basal) {
|
||||
var toTempBasal = profile.getTempBasal(to.format('x'));
|
||||
|
||||
linedata.push( { d: to.format('x'), b: toTempBasal.totalbasal } );
|
||||
notemplinedata.push( { d: to.format('x'), b: toTempBasal.basal } );
|
||||
basalareadata.push( { d: to.format('x'), b: toTempBasal.basal } );
|
||||
tempbasalareadata.push( { d: to.format('x'), b: toTempBasal.totalbasal } );
|
||||
comboareadata.push( { d: to.format('x'), b: toTempBasal.totalbasal } );
|
||||
linedata.push({ d: to.format('x'), b: toTempBasal.totalbasal });
|
||||
notemplinedata.push({ d: to.format('x'), b: toTempBasal.basal });
|
||||
basalareadata.push({ d: to.format('x'), b: toTempBasal.basal });
|
||||
tempbasalareadata.push({ d: to.format('x'), b: toTempBasal.totalbasal });
|
||||
comboareadata.push({ d: to.format('x'), b: toTempBasal.totalbasal });
|
||||
|
||||
var basalMax = d3.max(linedata, function(d) { return d.b; });
|
||||
basalMax = Math.max(basalMax, d3.max(basalareadata, function(d) { return d.b; }));
|
||||
@@ -657,7 +653,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('stroke-width', 1)
|
||||
.attr('d', area);
|
||||
|
||||
datastorage.tempbasalTreatments.forEach(function (t) {
|
||||
datastorage.tempbasalTreatments.forEach(function(t) {
|
||||
// only if basal and focus interval overlap and there is a chance to fit
|
||||
if (t.mills < to.format('x') && t.mills + times.mins(t.duration).msecs > from.format('x')) {
|
||||
var text = g.append('text')
|
||||
@@ -667,9 +663,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('fill', '#0099ff')
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dy', '.35em')
|
||||
.attr('x', xScale2((Math.max(t.mills, from.format('x')) + Math.min(t.mills + times.mins(t.duration).msecs, to.format('x')))/2) + padding.left)
|
||||
.attr('x', xScale2((Math.max(t.mills, from.format('x')) + Math.min(t.mills + times.mins(t.duration).msecs, to.format('x'))) / 2) + padding.left)
|
||||
.attr('y', yScaleBasals(0) - 10 + padding.top)
|
||||
// .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (t.absolute ? Number(t.absolute).toFixed(2) + 'U' : ''));
|
||||
// .text((t.percent ? (t.percent > 0 ? '+' : '') + t.percent + '%' : '') + (t.absolute ? Number(t.absolute).toFixed(2) + 'U' : ''));
|
||||
// better hide if not fit
|
||||
if (text.node().getBBox().width > xScale2(t.mills + times.mins(t.duration).msecs) - xScale2(t.mills)) {
|
||||
text.attr('display', 'none');
|
||||
@@ -678,8 +674,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
data.treatments.forEach(function (treatment) {
|
||||
data.treatments.forEach(function(treatment) {
|
||||
// Calculate bolus stats
|
||||
if (treatment.insulin) {
|
||||
bolusInsulin += treatment.insulin;
|
||||
@@ -698,10 +693,10 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
var drawpointer = false;
|
||||
if (treatment.boluscalc && treatment.boluscalc.foods && treatment.boluscalc.foods.length > 0 && options.food) {
|
||||
var foods = treatment.boluscalc.foods;
|
||||
for (var fi=0; fi<foods.length; fi++) {
|
||||
for (var fi = 0; fi < foods.length; fi++) {
|
||||
var f = foods[fi];
|
||||
var text = ''+ f.name + ' ';
|
||||
text += ''+ (f.carbs*f.portions).toFixed(1) + ' g';
|
||||
var text = '' + f.name + ' ';
|
||||
text += '' + (f.carbs * f.portions).toFixed(1) + ' g';
|
||||
context.append('text')
|
||||
.style('font-size', '10px')
|
||||
.style('font-weight', 'normal')
|
||||
@@ -721,7 +716,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('y', foodtexts * 15 + padding.top)
|
||||
.attr('transform', 'translate(' + (xScale2(treatment.mills) + padding.left) + ',' + padding.top + ')')
|
||||
.html(treatment.notes);
|
||||
foodtexts = (foodtexts+1)%6;
|
||||
foodtexts = (foodtexts + 1) % 6;
|
||||
drawpointer = true;
|
||||
}
|
||||
if (drawpointer) {
|
||||
@@ -730,7 +725,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('x1', xScale2(treatment.mills) + padding.left)
|
||||
.attr('y1', lastfoodtext * 15 + padding.top)
|
||||
.attr('x2', xScale2(treatment.mills) + padding.left)
|
||||
.attr('y2', padding.top + treatment.carbs ? yCarbsScale(treatment.carbs) : ( treatment.insulin ? yInsulinScale(treatment.insulin) : chartHeight))
|
||||
.attr('y2', padding.top + treatment.carbs ? yCarbsScale(treatment.carbs) : (treatment.insulin ? yInsulinScale(treatment.insulin) : chartHeight))
|
||||
.style('stroke-dasharray', ('1, 7'))
|
||||
.attr('stroke', 'grey');
|
||||
}
|
||||
@@ -738,14 +733,14 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
if (treatment.carbs && options.carbs) {
|
||||
var ic = profile.getCarbRatio(new Date(treatment.mills));
|
||||
var label = ' ' + treatment.carbs +' g';
|
||||
if (treatment.protein) label += ' / ' + treatment.protein +' g';
|
||||
if (treatment.fat) label += ' / ' + treatment.fat +' g';
|
||||
label += ' ('+(treatment.carbs/ic).toFixed(2)+'U)';
|
||||
var label = ' ' + treatment.carbs + ' g';
|
||||
if (treatment.protein) label += ' / ' + treatment.protein + ' g';
|
||||
if (treatment.fat) label += ' / ' + treatment.fat + ' g';
|
||||
label += ' (' + (treatment.carbs / ic).toFixed(2) + 'U)';
|
||||
|
||||
context.append('rect')
|
||||
.attr('y',yCarbsScale(treatment.carbs))
|
||||
.attr('height', chartHeight-yCarbsScale(treatment.carbs))
|
||||
.attr('y', yCarbsScale(treatment.carbs))
|
||||
.attr('height', chartHeight - yCarbsScale(treatment.carbs))
|
||||
.attr('width', 5)
|
||||
.attr('stroke', 'red')
|
||||
.attr('opacity', '0.5')
|
||||
@@ -755,15 +750,15 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.style('font-size', '12px')
|
||||
.style('font-weight', 'bold')
|
||||
.attr('fill', 'red')
|
||||
.attr('transform', 'rotate(-45,' + (xScale2(treatment.mills) + padding.left) + ',' + (padding.top+yCarbsScale(treatment.carbs)) + ') ' +
|
||||
'translate(' + (xScale2(treatment.mills) + padding.left +10) + ',' + (padding.top+yCarbsScale(treatment.carbs)) + ')')
|
||||
.text(''+label);
|
||||
.attr('transform', 'rotate(-45,' + (xScale2(treatment.mills) + padding.left) + ',' + (padding.top + yCarbsScale(treatment.carbs)) + ') ' +
|
||||
'translate(' + (xScale2(treatment.mills) + padding.left + 10) + ',' + (padding.top + yCarbsScale(treatment.carbs)) + ')')
|
||||
.text('' + label);
|
||||
}
|
||||
|
||||
if (treatment.insulin && options.insulin) {
|
||||
context.append('rect')
|
||||
.attr('y',yInsulinScale(treatment.insulin))
|
||||
.attr('height', chartHeight-yInsulinScale(treatment.insulin))
|
||||
.attr('y', yInsulinScale(treatment.insulin))
|
||||
.attr('height', chartHeight - yInsulinScale(treatment.insulin))
|
||||
.attr('width', 5)
|
||||
.attr('stroke', 'blue')
|
||||
.attr('opacity', '0.5')
|
||||
@@ -774,9 +769,9 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.style('font-weight', 'bold')
|
||||
.attr('fill', 'blue')
|
||||
//.attr('y', yInsulinScale(treatment.insulin)-10)
|
||||
.attr('transform', 'rotate(-45,' + (xScale2(treatment.mills) + padding.left - 2) + ',' + (padding.top+yInsulinScale(treatment.insulin)) + ')' +
|
||||
'translate(' + (xScale2(treatment.mills) + padding.left + 10) + ',' + (padding.top+yInsulinScale(treatment.insulin)) + ')')
|
||||
.text(Number(treatment.insulin).toFixed(2)+'U');
|
||||
.attr('transform', 'rotate(-45,' + (xScale2(treatment.mills) + padding.left - 2) + ',' + (padding.top + yInsulinScale(treatment.insulin)) + ')' +
|
||||
'translate(' + (xScale2(treatment.mills) + padding.left + 10) + ',' + (padding.top + yInsulinScale(treatment.insulin)) + ')')
|
||||
.text(Number(treatment.insulin).toFixed(2) + 'U');
|
||||
}
|
||||
|
||||
// process the rest
|
||||
@@ -810,7 +805,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dy', '.35em')
|
||||
.attr('y', yScale2(client.utils.scaleMgdl(378)) + padding.top)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs/2) + padding.left)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs / 2) + padding.left)
|
||||
.text(treatment.notes);
|
||||
} else if (treatment.eventType === 'Note' && treatment.duration) {
|
||||
context.append('rect')
|
||||
@@ -829,7 +824,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dy', '.35em')
|
||||
.attr('y', yScale2(client.utils.scaleMgdl(342)) + padding.top)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs/2) + padding.left)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs / 2) + padding.left)
|
||||
.text(treatment.notes);
|
||||
} else if (treatment.eventType === 'OpenAPS Offline' && treatment.duration) {
|
||||
context.append('rect')
|
||||
@@ -848,13 +843,13 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dy', '.35em')
|
||||
.attr('y', yScale2(client.utils.scaleMgdl(306)) + padding.top)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs/2) + padding.left)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs / 2) + padding.left)
|
||||
.text(treatment.notes);
|
||||
} else if (!treatment.duration) {
|
||||
// other treatments without duration
|
||||
context.append('circle')
|
||||
.attr('cx', xScale2(treatment.mills) + padding.left)
|
||||
.attr('cy', yScale2(scaledTreatmentBG(treatment,data.sgv)) + padding.top)
|
||||
.attr('cy', yScale2(scaledTreatmentBG(treatment, data.sgv)) + padding.top)
|
||||
.attr('fill', 'purple')
|
||||
.style('opacity', 1)
|
||||
.attr('stroke-width', 1)
|
||||
@@ -864,7 +859,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.style('font-size', '12px')
|
||||
.style('font-weight', 'bold')
|
||||
.attr('fill', 'purple')
|
||||
.attr('y', yScale2(scaledTreatmentBG(treatment,data.sgv)) + padding.top -10)
|
||||
.attr('y', yScale2(scaledTreatmentBG(treatment, data.sgv)) + padding.top - 10)
|
||||
.attr('x', xScale2(treatment.mills) + padding.left + 10)
|
||||
.text(translate(client.careportal.resolveEventName(treatment.eventType)));
|
||||
} else if (treatment.duration) {
|
||||
@@ -885,7 +880,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.attr('text-anchor', 'middle')
|
||||
.attr('dy', '.35em')
|
||||
.attr('y', yScale2(client.utils.scaleMgdl(414)) + padding.top)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs/2) + padding.left)
|
||||
.attr('x', xScale2(treatment.mills + times.mins(treatment.duration).msecs / 2) + padding.left)
|
||||
.text(treatment.notes);
|
||||
} else {
|
||||
console.log("missed treatment", treatment);
|
||||
@@ -922,11 +917,11 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
|
||||
var chartData = [
|
||||
{
|
||||
label: translate('Basal'),
|
||||
count: totalBasalInsulin,
|
||||
pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0)
|
||||
},
|
||||
{label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0)}
|
||||
label: translate('Basal')
|
||||
, count: totalBasalInsulin
|
||||
, pct: (totalBasalInsulin / totalDailyInsulin * 100).toFixed(0)
|
||||
}
|
||||
, { label: translate('Bolus'), count: bolusInsulin, pct: (bolusInsulin / totalDailyInsulin * 100).toFixed(0) }
|
||||
];
|
||||
|
||||
// Insulin distribution chart
|
||||
@@ -952,7 +947,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.outerRadius(radius);
|
||||
|
||||
var pie = d3.layout.pie()
|
||||
.value(function (d) {
|
||||
.value(function(d) {
|
||||
return d.count;
|
||||
})
|
||||
.sort(null);
|
||||
@@ -966,18 +961,18 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
insulg.append('path')
|
||||
.attr('d', arc)
|
||||
.attr('opacity', '0.5')
|
||||
.attr('fill', function (d) {
|
||||
.attr('fill', function(d) {
|
||||
return color(d.data.label);
|
||||
});
|
||||
|
||||
insulg.append('text')
|
||||
.attr('transform', function (d) {
|
||||
.attr('transform', function(d) {
|
||||
return 'translate(' + labelArc.centroid(d) + ')';
|
||||
})
|
||||
.attr('dy', '.15em')
|
||||
.style('font-weight', 'bold')
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(function (d) {
|
||||
.text(function(d) {
|
||||
return d.data.pct + '%';
|
||||
});
|
||||
|
||||
@@ -986,7 +981,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
var carbscolor = d3.scale.ordinal().range(['red']);
|
||||
|
||||
var carbsData = [
|
||||
{label: translate('Carbs'), count: data.dailyCarbs}
|
||||
{ label: translate('Carbs'), count: data.dailyCarbs }
|
||||
];
|
||||
|
||||
var carbssvg = d3.select('#daytodaystatcarbspiechart-' + day)
|
||||
@@ -1001,7 +996,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
.outerRadius(radius * data.dailyCarbs / options.maxDailyCarbsValue);
|
||||
|
||||
var carbspie = d3.layout.pie()
|
||||
.value(function (d) {
|
||||
.value(function(d) {
|
||||
return d.count;
|
||||
})
|
||||
.sort(null);
|
||||
@@ -1015,18 +1010,18 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
carbsg.append('path')
|
||||
.attr('d', carbsarc)
|
||||
.attr('opacity', '0.5')
|
||||
.attr('fill', function (d) {
|
||||
.attr('fill', function(d) {
|
||||
return carbscolor(d.data.label);
|
||||
});
|
||||
|
||||
carbsg.append('text')
|
||||
.attr('transform', function () {
|
||||
.attr('transform', function() {
|
||||
return 'translate(0,0)';
|
||||
})
|
||||
.attr('dy', '.15em')
|
||||
.style('font-weight', 'bold')
|
||||
.attr('text-anchor', 'middle')
|
||||
.text(function (d) {
|
||||
.text(function(d) {
|
||||
return d.data.count + 'g';
|
||||
});
|
||||
}
|
||||
@@ -1043,7 +1038,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
, first: true
|
||||
});
|
||||
|
||||
function appendProfileSwitch(context, treatment) {
|
||||
function appendProfileSwitch (context, treatment) {
|
||||
|
||||
if (!treatment.cutting && !treatment.profile) { return; }
|
||||
|
||||
@@ -1068,7 +1063,7 @@ daytoday.report = function report_daytoday(datastorage,sorteddaystoshow,options)
|
||||
console.log("Rendering " + day, new Date().getTime() - timestart.getTime(), "msecs");
|
||||
}
|
||||
|
||||
function hideTooltip ( ) {
|
||||
function hideTooltip () {
|
||||
client.tooltip.transition()
|
||||
.duration(TOOLTIP_TRANS_MS)
|
||||
.style('opacity', 0);
|
||||
|
||||
@@ -6,13 +6,13 @@ var glucosedistribution = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return glucosedistribution;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
glucosedistribution.html = function html(client) {
|
||||
glucosedistribution.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' +
|
||||
@@ -65,8 +65,7 @@ glucosedistribution.html = function html(client) {
|
||||
'20<input type="checkbox" id="glucosedistribution-20" checked>' +
|
||||
'21<input type="checkbox" id="glucosedistribution-21" checked>' +
|
||||
'22<input type="checkbox" id="glucosedistribution-22" checked>' +
|
||||
'23<input type="checkbox" id="glucosedistribution-23" checked>'
|
||||
;
|
||||
'23<input type="checkbox" id="glucosedistribution-23" checked>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
@@ -83,7 +82,7 @@ glucosedistribution.css =
|
||||
' text-align:center;' +
|
||||
'}';
|
||||
|
||||
glucosedistribution.report = function report_glucosedistribution(datastorage, sorteddaystoshow, options) {
|
||||
glucosedistribution.report = function report_glucosedistribution (datastorage, sorteddaystoshow, options) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
var translate = client.translate;
|
||||
@@ -132,13 +131,13 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
|
||||
// Filter data for noise
|
||||
// data cleaning pass 0 - remove duplicates and non-sgv entries, sort
|
||||
var seen = {};
|
||||
var seen = [];
|
||||
data = data.filter(function(item) {
|
||||
if (!item.sgv || !item.bgValue || !item.displayTime || item.bgValue < 39) {
|
||||
if (!item.sgv || !item.bgValue || !item.displayTime || item.bgValue < 39) {
|
||||
console.log(item);
|
||||
return false;
|
||||
}
|
||||
return seen.hasOwnProperty(item.displayTime) ? false : (seen[item.displayTime] = true);
|
||||
return seen.includes(item.displayTime) ? false : (seen[item.displayTime] = true);
|
||||
});
|
||||
|
||||
data.sort(function(a, b) {
|
||||
@@ -148,7 +147,7 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
var glucose_data = [data[0]];
|
||||
|
||||
// data cleaning pass 1 - add interpolated missing points
|
||||
for (var i = 0; i <= data.length - 2; i++) {
|
||||
for (i = 0; i <= data.length - 2; i++) {
|
||||
var entry = data[i];
|
||||
var nextEntry = data[i + 1];
|
||||
|
||||
@@ -186,12 +185,12 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
|
||||
const maxGap = (5 * 60 * 1000) + 10000;
|
||||
|
||||
for (var i = 1; i <= glucose_data.length - 2; i++) {
|
||||
var entry = glucose_data[i];
|
||||
var nextEntry = glucose_data[i + 1];
|
||||
for (i = 1; i <= glucose_data.length - 2; i++) {
|
||||
let entry = glucose_data[i];
|
||||
let nextEntry = glucose_data[i + 1];
|
||||
|
||||
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
var timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime();
|
||||
let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
let timeDelta2 = entry.displayTime.getTime() - prevEntry.displayTime.getTime();
|
||||
|
||||
if (timeDelta > maxGap || timeDelta2 > maxGap) {
|
||||
glucose_data2.push(entry);
|
||||
@@ -212,8 +211,8 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
const d = (nextEntry.bgValue - prevEntry.bgValue) / 2;
|
||||
const interpolatedValue = prevEntry.bgValue + d;
|
||||
|
||||
var newEntry = {
|
||||
sgv: displayUnits === 'mmol' ? interpolatedValue/18 : interpolatedValue
|
||||
let newEntry = {
|
||||
sgv: displayUnits === 'mmol' ? interpolatedValue / 18 : interpolatedValue
|
||||
, bgValue: interpolatedValue
|
||||
, displayTime: entry.displayTime
|
||||
};
|
||||
@@ -237,10 +236,10 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
});
|
||||
|
||||
var timeTotal = 0;
|
||||
for (var i = 1; i <= glucose_data.length - 2; i++) {
|
||||
var entry = glucose_data[i];
|
||||
var nextEntry = glucose_data[i + 1];
|
||||
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
for (i = 1; i <= glucose_data.length - 2; i++) {
|
||||
let entry = glucose_data[i];
|
||||
let nextEntry = glucose_data[i + 1];
|
||||
let timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
if (timeDelta < maxGap) {
|
||||
timeTotal += timeDelta;
|
||||
}
|
||||
@@ -357,11 +356,10 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
var glucoseTotal = 0;
|
||||
var deltaTotal = 0;
|
||||
|
||||
for (var i = 0; i <= glucose_data.length - 2; i++) {
|
||||
var entry = glucose_data[i];
|
||||
var nextEntry = glucose_data[i + 1];
|
||||
|
||||
var timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
for (i = 0; i <= glucose_data.length - 2; i++) {
|
||||
const entry = glucose_data[i];
|
||||
const nextEntry = glucose_data[i + 1];
|
||||
const timeDelta = nextEntry.displayTime.getTime() - entry.displayTime.getTime();
|
||||
|
||||
// Use maxGap constant
|
||||
if (timeDelta == 0 || timeDelta > maxGap) { // 6 * 60 * 1000) {
|
||||
@@ -470,7 +468,7 @@ glucosedistribution.report = function report_glucosedistribution(datastorage, so
|
||||
);
|
||||
});
|
||||
|
||||
function onClick() {
|
||||
function onClick () {
|
||||
report_glucosedistribution(datastorage, sorteddaystoshow, options);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -8,34 +8,33 @@ var hourlystats = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return hourlystats;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
hourlystats.html = function html(client) {
|
||||
hourlystats.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Hourly stats') + '</h2>'
|
||||
+ '<div id="hourlystats-overviewchart"></div>'
|
||||
+ '<div id="hourlystats-report"></div>'
|
||||
;
|
||||
'<h2>' + translate('Hourly stats') + '</h2>' +
|
||||
'<div id="hourlystats-overviewchart"></div>' +
|
||||
'<div id="hourlystats-report"></div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
hourlystats.css =
|
||||
'#hourlystats-overviewchart {'
|
||||
+ ' width: 100%;'
|
||||
+ ' min-width: 6.5in;'
|
||||
+ ' height: 5in;'
|
||||
+ '}'
|
||||
+ '#hourlystats-placeholder td {'
|
||||
+ ' text-align:center;'
|
||||
+ '}';
|
||||
'#hourlystats-overviewchart {' +
|
||||
' width: 100%;' +
|
||||
' min-width: 6.5in;' +
|
||||
' height: 5in;' +
|
||||
'}' +
|
||||
'#hourlystats-placeholder td {' +
|
||||
' text-align:center;' +
|
||||
'}';
|
||||
|
||||
hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow, options) {
|
||||
//console.log(window);
|
||||
hourlystats.report = function report_hourlystats (datastorage, sorteddaystoshow, options) {
|
||||
//console.log(window);
|
||||
var ss = require('simple-statistics');
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
@@ -52,7 +51,7 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
|
||||
pivotedByHour[i] = [];
|
||||
}
|
||||
|
||||
data = data.filter(function(o) { return !isNaN(o.sgv);});
|
||||
data = data.filter(function(o) { return !isNaN(o.sgv); });
|
||||
|
||||
data.forEach(function(record) {
|
||||
|
||||
@@ -74,48 +73,51 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
|
||||
$('<th>' + translate('Standard Deviation') + '</th>').appendTo(thead);
|
||||
thead.appendTo(table);
|
||||
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function (hour) {
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) {
|
||||
var tr = $('<tr>');
|
||||
var display = new Date(0, 0, 1, hour, 0, 0, 0).toLocaleTimeString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3');
|
||||
|
||||
var avg = Math.floor(pivotedByHour[hour].map(function (r) {
|
||||
var avg = Math.floor(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}).reduce(function (o, v) {
|
||||
}).reduce(function(o, v) {
|
||||
return o + v;
|
||||
}, 0) / pivotedByHour[hour].length);
|
||||
var d = new Date(times.hours(hour).msecs);
|
||||
|
||||
var dev = ss.standard_deviation(pivotedByHour[hour].map(function (r) {
|
||||
var dev = ss.standard_deviation(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}));
|
||||
stats.push([
|
||||
new Date(d),
|
||||
ss.quantile(pivotedByHour[hour].map(function (r) {
|
||||
new Date(d)
|
||||
, ss.quantile(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}), 0.25),
|
||||
ss.quantile(pivotedByHour[hour].map(function (r) {
|
||||
}), 0.25)
|
||||
, ss.quantile(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}), 0.75),
|
||||
avg - dev,
|
||||
avg + dev
|
||||
}), 0.75)
|
||||
, avg - dev
|
||||
, avg + dev
|
||||
]);
|
||||
var tmp;
|
||||
$('<td>' + display + '</td>').appendTo(tr);
|
||||
$('<td>' + pivotedByHour[hour].length + ' (' + Math.floor(100 * pivotedByHour[hour].length / data.length) + '%)</td>').appendTo(tr);
|
||||
$('<td>' + avg + '</td>').appendTo(tr);
|
||||
$('<td>' + Math.min.apply(Math, pivotedByHour[hour].map(function (r) {
|
||||
$('<td>' + Math.min.apply(Math, pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
})) + '</td>').appendTo(tr);
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) {
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}), 0.25)) ? tmp.toFixed(1) : 0 ) + '</td>').appendTo(tr);
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) {
|
||||
}), 0.25)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}), 0.5)) ? tmp.toFixed(1) : 0 ) + '</td>').appendTo(tr);
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function (r) {
|
||||
}), 0.5)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
$('<td>' + ((tmp = ss.quantile(pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
}), 0.75)) ? tmp.toFixed(1) : 0 ) + '</td>').appendTo(tr);
|
||||
$('<td>' + Math.max.apply(Math, pivotedByHour[hour].map(function (r) {
|
||||
}), 0.75)) ? tmp.toFixed(1) : 0) + '</td>').appendTo(tr);
|
||||
$('<td>' + Math.max.apply(Math, pivotedByHour[hour].map(function(r) {
|
||||
return r.sgv;
|
||||
})) + '</td>').appendTo(tr);
|
||||
$('<td>' + Math.floor(dev * 10) / 10 + '</td>').appendTo(tr);
|
||||
@@ -126,28 +128,27 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
|
||||
report.append(table);
|
||||
|
||||
$.plot(
|
||||
'#hourlystats-overviewchart',
|
||||
[{
|
||||
data: stats,
|
||||
candle: true
|
||||
}],
|
||||
{
|
||||
'#hourlystats-overviewchart'
|
||||
, [{
|
||||
data: stats
|
||||
, candle: true
|
||||
}], {
|
||||
series: {
|
||||
candle: true,
|
||||
lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;)
|
||||
},
|
||||
xaxis: {
|
||||
mode: 'time',
|
||||
timeFormat: '%h:00',
|
||||
min: 0,
|
||||
max: times.hours(24).msecs - times.secs(1).msecs
|
||||
},
|
||||
yaxis: {
|
||||
min: 0,
|
||||
max: options.units === 'mmol' ? 22 : 400,
|
||||
show: true
|
||||
},
|
||||
grid: {
|
||||
candle: true
|
||||
, lines: false //Somehow it draws lines if you dont disable this. Should investigate and fix this ;)
|
||||
}
|
||||
, xaxis: {
|
||||
mode: 'time'
|
||||
, timeFormat: '%h:00'
|
||||
, min: 0
|
||||
, max: times.hours(24).msecs - times.secs(1).msecs
|
||||
}
|
||||
, yaxis: {
|
||||
min: 0
|
||||
, max: options.units === 'mmol' ? 22 : 400
|
||||
, show: true
|
||||
}
|
||||
, grid: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
@@ -161,7 +162,7 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
|
||||
var days = 0;
|
||||
table = $('<table width="100%" border="1">');
|
||||
thead = $('<tr/>');
|
||||
["", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function (hour) {
|
||||
["", 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23].forEach(function(hour) {
|
||||
$('<th>' + hour + '</th>').appendTo(thead);
|
||||
totalPositive[hour] = 0;
|
||||
totalNegative[hour] = 0;
|
||||
@@ -171,7 +172,7 @@ hourlystats.report = function report_hourlystats(datastorage, sorteddaystoshow,
|
||||
});
|
||||
thead.appendTo(table);
|
||||
|
||||
sorteddaystoshow.forEach(function (day) {
|
||||
sorteddaystoshow.forEach(function(day) {
|
||||
if (datastorage[day].netBasalPositive) {
|
||||
days++;
|
||||
var tr = $('<tr>');
|
||||
|
||||
+332
-327
File diff suppressed because it is too large
Load Diff
@@ -6,33 +6,32 @@ var profiles = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return profiles;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
profiles.html = function html(client) {
|
||||
profiles.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Profiles') + '</h2>'
|
||||
+ '<br>' + translate('Database records') + ' '
|
||||
+ '<br><select id="profiles-databaserecords"></select>'
|
||||
+ '<br><span id="profiles-default"></span>'
|
||||
+ '<div id="profiles-chart">'
|
||||
+ '</div>'
|
||||
;
|
||||
'<h2>' + translate('Profiles') + '</h2>' +
|
||||
'<br>' + translate('Database records') + ' ' +
|
||||
'<br><select id="profiles-databaserecords"></select>' +
|
||||
'<br><span id="profiles-default"></span>' +
|
||||
'<div id="profiles-chart">' +
|
||||
'</div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
profiles.css =
|
||||
'#profiles-chart {'
|
||||
+ ' width: 100%;'
|
||||
+ ' height: 100%;'
|
||||
+ '}'
|
||||
;
|
||||
'#profiles-chart {' +
|
||||
' width: 100%;' +
|
||||
' height: 100%;' +
|
||||
'}';
|
||||
|
||||
profiles.report = function report_profiles(datastorage, sorteddaystoshow, options) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
profiles.report = function report_profiles (datastorage, sorteddaystoshow, options) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
var translate = client.translate;
|
||||
@@ -41,10 +40,10 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option
|
||||
var databaseRecords = $('#profiles-databaserecords');
|
||||
|
||||
databaseRecords.empty();
|
||||
for (var r = 0; r < profileRecords.length; r++ ) {
|
||||
for (var r = 0; r < profileRecords.length; r++) {
|
||||
databaseRecords.append('<option value="' + r + '">' + translate('Valid from:') + ' ' + new Date(profileRecords[r].startDate).toLocaleString() + '</option>');
|
||||
}
|
||||
databaseRecords.unbind().bind('change',recordChange);
|
||||
databaseRecords.unbind().bind('change', recordChange);
|
||||
|
||||
recordChange();
|
||||
|
||||
@@ -58,11 +57,10 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option
|
||||
var tr = $('<tr>');
|
||||
|
||||
$('#profiles-default').val(currentrecord.defaultProfile);
|
||||
for (var key in currentrecord.store) {
|
||||
if (currentrecord.store.hasOwnProperty(key)) {
|
||||
tr.append(displayRecord(currentrecord.store[key], key))
|
||||
}
|
||||
}
|
||||
|
||||
Object.keys(currentrecord.store).forEach(key => {
|
||||
tr.append(displayRecord(currentrecord.store[key], key));
|
||||
});
|
||||
|
||||
table.append(tr);
|
||||
|
||||
@@ -73,7 +71,7 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option
|
||||
}
|
||||
}
|
||||
|
||||
function displayRecord(record, name) {
|
||||
function displayRecord (record, name) {
|
||||
var td = $('<td>');
|
||||
var table = $('<table>');
|
||||
|
||||
@@ -91,7 +89,7 @@ profiles.report = function report_profiles(datastorage, sorteddaystoshow, option
|
||||
return td;
|
||||
}
|
||||
|
||||
function displayRanges(array, array2) {
|
||||
function displayRanges (array, array2) {
|
||||
var text = '';
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
text += array[i].time + ' : ' + array[i].value + (array2 ? ' - ' + array2[i].value : '') + '<br>';
|
||||
|
||||
@@ -8,58 +8,52 @@ var success = {
|
||||
, pluginType: 'report'
|
||||
};
|
||||
|
||||
function init() {
|
||||
function init () {
|
||||
return success;
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
success.html = function html(client) {
|
||||
success.html = function html (client) {
|
||||
var translate = client.translate;
|
||||
var ret =
|
||||
'<h2>' + translate('Weekly Success') + '</h2>'
|
||||
+ '<div id="success-grid"></div>'
|
||||
;
|
||||
'<h2>' + translate('Weekly Success') + '</h2>' +
|
||||
'<div id="success-grid"></div>';
|
||||
return ret;
|
||||
};
|
||||
|
||||
success.css =
|
||||
'#success-placeholder td {'+
|
||||
' border: 1px #ccc solid;'+
|
||||
' margin: 0;'+
|
||||
' padding: 1px;'+
|
||||
' text-align:center;'+
|
||||
'}'+
|
||||
'#success-placeholder .bad {'+
|
||||
' background-color: #fcc;'+
|
||||
'}'+
|
||||
`#success-placeholder td {
|
||||
border: 1px #ccc solid;
|
||||
margin: 0;
|
||||
padding: 1px;
|
||||
text-align:center;
|
||||
}
|
||||
#success-placeholder .bad {
|
||||
background-color: #fcc;
|
||||
}
|
||||
#success-placeholder .good {
|
||||
background-color: #cfc;
|
||||
}
|
||||
#success-placeholder th:first-child {
|
||||
width: 30%;
|
||||
}
|
||||
#success-placeholder th {
|
||||
width: 10%;
|
||||
}
|
||||
#success-placeholder table {
|
||||
width: 100%;
|
||||
}`;
|
||||
|
||||
'#success-placeholder .good {'+
|
||||
' background-color: #cfc;'+
|
||||
'}'+
|
||||
|
||||
'#success-placeholder th:first-child {'+
|
||||
' width: 30%;'+
|
||||
'}'+
|
||||
'#success-placeholder th {'+
|
||||
' width: 10%;'+
|
||||
'}'+
|
||||
'#success-placeholder table {'+
|
||||
' width: 100%;'+
|
||||
'}'
|
||||
;
|
||||
|
||||
|
||||
|
||||
success.report = function report_success(datastorage, sorteddaystoshow, options) {
|
||||
success.report = function report_success (datastorage, sorteddaystoshow, options) {
|
||||
var Nightscout = window.Nightscout;
|
||||
var client = Nightscout.client;
|
||||
var translate = client.translate;
|
||||
|
||||
var ss = require('simple-statistics');
|
||||
|
||||
var low = options.targetLow,
|
||||
high = options.targetHigh;
|
||||
var low = options.targetLow
|
||||
, high = options.targetHigh;
|
||||
|
||||
var data = datastorage.allstatsrecords;
|
||||
|
||||
@@ -79,38 +73,38 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
|
||||
|
||||
if (quarters === 0) {
|
||||
// insufficent data
|
||||
grid.append('<p>'+translate('There is not sufficient data to run this report. Select more days.')+'</p>');
|
||||
grid.append('<p>' + translate('There is not sufficient data to run this report. Select more days.') + '</p>');
|
||||
return;
|
||||
}
|
||||
|
||||
var dim = function(n) {
|
||||
var a = [];
|
||||
for (var i = 0; i < n; i++) {
|
||||
a[i]=0;
|
||||
a[i] = 0;
|
||||
}
|
||||
return a;
|
||||
};
|
||||
var sum = function(a) {
|
||||
return a.reduce(function(sum,v) {
|
||||
return sum+v;
|
||||
return a.reduce(function(sum, v) {
|
||||
return sum + v;
|
||||
}, 0);
|
||||
};
|
||||
var averages = {
|
||||
percentLow: 0,
|
||||
percentInRange: 0,
|
||||
percentHigh: 0,
|
||||
standardDeviation: 0,
|
||||
lowerQuartile: 0,
|
||||
upperQuartile: 0,
|
||||
average: 0
|
||||
percentLow: 0
|
||||
, percentInRange: 0
|
||||
, percentHigh: 0
|
||||
, standardDeviation: 0
|
||||
, lowerQuartile: 0
|
||||
, upperQuartile: 0
|
||||
, average: 0
|
||||
};
|
||||
quarters = dim(quarters).map(function(blank, n) {
|
||||
var starting = new Date(now - (n+1) * period),
|
||||
ending = new Date(now - n * period);
|
||||
var starting = new Date(now - (n + 1) * period)
|
||||
, ending = new Date(now - n * period);
|
||||
return {
|
||||
starting: starting,
|
||||
ending: ending,
|
||||
records: data.filter(function(record) {
|
||||
starting: starting
|
||||
, ending: ending
|
||||
, records: data.filter(function(record) {
|
||||
return record.displayTime > starting && record.displayTime <= ending;
|
||||
})
|
||||
};
|
||||
@@ -121,7 +115,7 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
|
||||
return record.sgv;
|
||||
});
|
||||
quarter.standardDeviation = ss.standard_deviation(bgValues);
|
||||
quarter.average = bgValues.length > 0? (sum(bgValues) / bgValues.length): 'N/A';
|
||||
quarter.average = bgValues.length > 0 ? (sum(bgValues) / bgValues.length) : 'N/A';
|
||||
quarter.lowerQuartile = ss.quantile(bgValues, 0.25);
|
||||
quarter.upperQuartile = ss.quantile(bgValues, 0.75);
|
||||
quarter.numberLow = bgValues.filter(function(bg) {
|
||||
@@ -148,9 +142,9 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
|
||||
|
||||
var lowComparison = function(quarter, averages, field, invert) {
|
||||
if (quarter[field] < averages[field] * 0.8) {
|
||||
return (invert? 'bad': 'good');
|
||||
return (invert ? 'bad' : 'good');
|
||||
} else if (quarter[field] > averages[field] * 1.2) {
|
||||
return (invert? 'good': 'bad');
|
||||
return (invert ? 'good' : 'bad');
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
@@ -172,44 +166,44 @@ success.report = function report_success(datastorage, sorteddaystoshow, options)
|
||||
}
|
||||
};
|
||||
|
||||
table.append('<thead><tr><th>'+translate('Period')+'</th><th>'+translate('Low')+'</th><th>'+translate('In Range')+'</th><th>'+translate('High')+'</th><th>'+translate('Standard Deviation')+'</th><th>'+translate('Low Quartile')+'</th><th>'+translate('Average')+'</th><th>'+translate('Upper Quartile')+'</th></tr></thead>');
|
||||
table.append('<thead><tr><th>' + translate('Period') + '</th><th>' + translate('Low') + '</th><th>' + translate('In Range') + '</th><th>' + translate('High') + '</th><th>' + translate('Standard Deviation') + '</th><th>' + translate('Low Quartile') + '</th><th>' + translate('Average') + '</th><th>' + translate('Upper Quartile') + '</th></tr></thead>');
|
||||
table.append('<tbody>' + quarters.filter(function(quarter) {
|
||||
return quarter.records.length > 0;
|
||||
}).map(function(quarter) {
|
||||
var INVERT = true;
|
||||
return '<tr>' + [
|
||||
quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString(),
|
||||
{
|
||||
klass: lowComparison(quarter, averages, 'percentLow'),
|
||||
text: Math.round(quarter.percentLow) + '%'
|
||||
},
|
||||
{
|
||||
klass: lowComparison(quarter, averages, 'percentInRange', INVERT),
|
||||
text: Math.round(quarter.percentInRange) + '%'
|
||||
},
|
||||
{
|
||||
klass: lowComparison(quarter, averages, 'percentHigh'),
|
||||
text: Math.round(quarter.percentHigh) + '%'
|
||||
},
|
||||
{
|
||||
klass: lowComparison(quarter, averages, 'standardDeviation'),
|
||||
text: (quarter.standardDeviation > 10? Math.round(quarter.standardDeviation): quarter.standardDeviation.toFixed(1))
|
||||
},
|
||||
{
|
||||
klass: lowQuartileEvaluation(quarter, averages),
|
||||
text: quarter.lowerQuartile
|
||||
},
|
||||
{
|
||||
klass: lowComparison(quarter, averages, 'average'),
|
||||
text: quarter.average.toFixed(1)
|
||||
},
|
||||
{
|
||||
klass: upperQuartileEvaluation(quarter, averages),
|
||||
text: quarter.upperQuartile
|
||||
quarter.starting.toLocaleDateString() + ' - ' + quarter.ending.toLocaleDateString()
|
||||
, {
|
||||
klass: lowComparison(quarter, averages, 'percentLow')
|
||||
, text: Math.round(quarter.percentLow) + '%'
|
||||
}
|
||||
, {
|
||||
klass: lowComparison(quarter, averages, 'percentInRange', INVERT)
|
||||
, text: Math.round(quarter.percentInRange) + '%'
|
||||
}
|
||||
, {
|
||||
klass: lowComparison(quarter, averages, 'percentHigh')
|
||||
, text: Math.round(quarter.percentHigh) + '%'
|
||||
}
|
||||
, {
|
||||
klass: lowComparison(quarter, averages, 'standardDeviation')
|
||||
, text: (quarter.standardDeviation > 10 ? Math.round(quarter.standardDeviation) : quarter.standardDeviation.toFixed(1))
|
||||
}
|
||||
, {
|
||||
klass: lowQuartileEvaluation(quarter, averages)
|
||||
, text: quarter.lowerQuartile
|
||||
}
|
||||
, {
|
||||
klass: lowComparison(quarter, averages, 'average')
|
||||
, text: quarter.average.toFixed(1)
|
||||
}
|
||||
, {
|
||||
klass: upperQuartileEvaluation(quarter, averages)
|
||||
, text: quarter.upperQuartile
|
||||
}
|
||||
].map(function(v) {
|
||||
if (typeof v === 'object') {
|
||||
return '<td class=\"' + v.klass + '\">' + v.text + '</td>';
|
||||
return '<td class="' + v.klass + '">' + v.text + '</td>';
|
||||
} else {
|
||||
return '<td>' + v + '</td>';
|
||||
}
|
||||
|
||||
+21
-26
@@ -4,21 +4,21 @@ var _ = require('lodash');
|
||||
var units = require('./units')();
|
||||
var times = require('./times');
|
||||
|
||||
function init ( ) {
|
||||
function init () {
|
||||
var sbx = {};
|
||||
|
||||
function reset () {
|
||||
sbx.properties = { };
|
||||
sbx.properties = {};
|
||||
}
|
||||
|
||||
function extend ( ) {
|
||||
function extend () {
|
||||
sbx.unitsLabel = unitsLabel();
|
||||
sbx.data = sbx.data || {};
|
||||
//default to prevent adding checks everywhere
|
||||
sbx.extendedSettings = {empty: true};
|
||||
sbx.extendedSettings = { empty: true };
|
||||
}
|
||||
|
||||
function withExtendedSettings(plugin, allExtendedSettings, sbx) {
|
||||
function withExtendedSettings (plugin, allExtendedSettings, sbx) {
|
||||
var sbx2 = _.extend({}, sbx);
|
||||
sbx2.extendedSettings = allExtendedSettings && allExtendedSettings[plugin.name] || {};
|
||||
return sbx2;
|
||||
@@ -60,7 +60,7 @@ function init ( ) {
|
||||
sbx.data.profile = profile;
|
||||
delete sbx.data.profiles;
|
||||
|
||||
sbx.properties = { };
|
||||
sbx.properties = {};
|
||||
|
||||
sbx.withExtendedSettings = function getPluginExtendedSettingsOnly (plugin) {
|
||||
return withExtendedSettings(plugin, env.extendedSettings, sbx);
|
||||
@@ -99,7 +99,7 @@ function init ( ) {
|
||||
sbx.pluginBase.forecastPoints = [];
|
||||
}
|
||||
|
||||
sbx.extendedSettings = {empty: true};
|
||||
sbx.extendedSettings = { empty: true };
|
||||
sbx.withExtendedSettings = function getPluginExtendedSettingsOnly (plugin) {
|
||||
return withExtendedSettings(plugin, sbx.settings.extendedSettings, sbx);
|
||||
};
|
||||
@@ -116,7 +116,7 @@ function init ( ) {
|
||||
* @param setter
|
||||
*/
|
||||
sbx.offerProperty = function offerProperty (name, setter) {
|
||||
if (!sbx.properties.hasOwnProperty(name)) {
|
||||
if (!Object.keys(sbx.properties).includes(name)) {
|
||||
var value = setter();
|
||||
if (value) {
|
||||
sbx.properties[name] = value;
|
||||
@@ -124,7 +124,7 @@ function init ( ) {
|
||||
}
|
||||
};
|
||||
|
||||
sbx.isCurrent = function isCurrent(entry) {
|
||||
sbx.isCurrent = function isCurrent (entry) {
|
||||
return entry && sbx.time - entry.mills <= times.mins(15).msecs;
|
||||
};
|
||||
|
||||
@@ -137,7 +137,7 @@ function init ( ) {
|
||||
sbx.lastNEntries = function lastNEntries (entries, n) {
|
||||
var lastN = [];
|
||||
|
||||
_.takeRightWhile(entries, function (entry) {
|
||||
_.takeRightWhile(entries, function(entry) {
|
||||
if (sbx.entryMills(entry) <= sbx.time) {
|
||||
lastN.push(entry);
|
||||
}
|
||||
@@ -158,32 +158,32 @@ function init ( ) {
|
||||
return sbx.prevEntry(sbx.data.sgvs);
|
||||
};
|
||||
|
||||
sbx.lastSGVEntry = function lastSGVEntry ( ) {
|
||||
sbx.lastSGVEntry = function lastSGVEntry () {
|
||||
return sbx.lastEntry(sbx.data.sgvs);
|
||||
};
|
||||
|
||||
sbx.lastSGVMgdl = function lastSGVMgdl ( ) {
|
||||
sbx.lastSGVMgdl = function lastSGVMgdl () {
|
||||
var last = sbx.lastSGVEntry();
|
||||
return last && last.mgdl;
|
||||
};
|
||||
|
||||
sbx.lastSGVMills = function lastSGVMills ( ) {
|
||||
sbx.lastSGVMills = function lastSGVMills () {
|
||||
return sbx.entryMills(sbx.lastSGVEntry());
|
||||
};
|
||||
|
||||
sbx.entryMills = function entryMills(entry) {
|
||||
sbx.entryMills = function entryMills (entry) {
|
||||
return entry && entry.mills;
|
||||
};
|
||||
|
||||
sbx.lastScaledSGV = function lastScaledSVG ( ) {
|
||||
sbx.lastScaledSGV = function lastScaledSVG () {
|
||||
return sbx.scaleEntry(sbx.lastSGVEntry());
|
||||
};
|
||||
|
||||
sbx.lastDisplaySVG = function lastDisplaySVG ( ) {
|
||||
sbx.lastDisplaySVG = function lastDisplaySVG () {
|
||||
return sbx.displayBg(sbx.lastSGVEntry());
|
||||
};
|
||||
|
||||
sbx.buildBGNowLine = function buildBGNowLine ( ) {
|
||||
sbx.buildBGNowLine = function buildBGNowLine () {
|
||||
var line = 'BG Now: ' + sbx.lastDisplaySVG();
|
||||
|
||||
var delta = sbx.properties.delta && sbx.properties.delta.display;
|
||||
@@ -216,7 +216,7 @@ function init ( ) {
|
||||
return lines;
|
||||
};
|
||||
|
||||
sbx.prepareDefaultLines = function prepareDefaultLines() {
|
||||
sbx.prepareDefaultLines = function prepareDefaultLines () {
|
||||
var lines = [sbx.buildBGNowLine()];
|
||||
sbx.appendPropertyLine('rawbg', lines);
|
||||
sbx.appendPropertyLine('ar2', lines);
|
||||
@@ -227,7 +227,7 @@ function init ( ) {
|
||||
return lines;
|
||||
};
|
||||
|
||||
sbx.buildDefaultMessage = function buildDefaultMessage() {
|
||||
sbx.buildDefaultMessage = function buildDefaultMessage () {
|
||||
return sbx.prepareDefaultLines().join('\n');
|
||||
};
|
||||
|
||||
@@ -272,14 +272,10 @@ function init ( ) {
|
||||
if (sbx.properties.roundingStyle === 'medtronic') {
|
||||
var denominator = 0.1;
|
||||
var digits = 1;
|
||||
if (insulin > 0.5 && iob < 1) {
|
||||
if (insulin <= 0.5) {
|
||||
denominator = 0.05;
|
||||
digits = 2;
|
||||
}
|
||||
if (insulin <= 0.5) {
|
||||
denominator = 0.025;
|
||||
digits = 3;
|
||||
}
|
||||
return (Math.floor(insulin / denominator) * denominator).toFixed(digits);
|
||||
}
|
||||
|
||||
@@ -287,7 +283,7 @@ function init ( ) {
|
||||
|
||||
};
|
||||
|
||||
function unitsLabel ( ) {
|
||||
function unitsLabel () {
|
||||
return sbx.settings.units === 'mmol' ? 'mmol/L' : 'mg/dl';
|
||||
}
|
||||
|
||||
@@ -299,4 +295,3 @@ function init ( ) {
|
||||
}
|
||||
|
||||
module.exports = init;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ CACHE MANIFEST
|
||||
/css/main.css?v=<%= locals.cachebuster %>
|
||||
/bundle/js/bundle.app.js?v=<%= locals.cachebuster %>
|
||||
/bundle/js/bundle.clock.js?v=<%= locals.cachebuster %>
|
||||
/bundle/js/bundle.report.js?v=<%= locals.cachebuster %>
|
||||
/socket.io/socket.io.js?v=<%= locals.cachebuster %>
|
||||
/js/client.js?v=<%= locals.cachebuster %>
|
||||
/images/logo2.png
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ if (process.env.NODE_ENV == 'development') {
|
||||
rules.unshift({
|
||||
enforce: "pre",
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
exclude: [/node_modules/, /bundle/],
|
||||
loader: "eslint-loader",
|
||||
options: {
|
||||
emitWarning: true,
|
||||
|
||||
Reference in New Issue
Block a user