From 395a1ea51638a5bbf49e18e3fad15ee53276f729 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Tue, 11 Oct 2016 23:50:48 -0700 Subject: [PATCH 001/303] add a .nvmrc targeting 4.6.0 and upgrade almost everything in package.json --- .nvmrc | 1 + package.json | 62 ++++++++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 31 deletions(-) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..6016e8addc4 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +4.6.0 diff --git a/package.json b/package.json index 340f7197f52..d6dbd6ef484 100644 --- a/package.json +++ b/package.json @@ -44,51 +44,51 @@ } }, "engines": { - "node": "0.10.x" + "node": "4.6.x" }, "dependencies": { - "async": "^0.9.0", - "body-parser": "^1.14.1", + "async": "^2.0.1", + "body-parser": "^1.15.2", "bootevent": "0.0.1", - "bower": "^1.3.8", + "bower": "^1.7.9", "browserify-express": "^0.1.4", - "compression": "^1.4.2", + "compression": "^1.6.2", "crossfilter": "^1.3.12", - "d3": "^3.5.6", - "errorhandler": "^1.1.1", - "event-stream": "~3.1.5", - "expand-braces": "^0.1.1", - "express": "^4.6.1", + "d3": "^3.5.17", + "errorhandler": "^1.4.3", + "event-stream": "~3.3.4", + "expand-braces": "^0.1.2", + "express": "^4.14.0", "express-extension-to-accept": "0.0.2", - "forever": "~0.13.0", + "forever": "~0.15.2", "git-rev": "git://github.com/bewest/git-rev.git", - "jquery": "^2.1.4", - "jsonwebtoken": "^7.1.7", - "lodash": "^4.0.0", - "long": "~2.2.3", + "jquery": "^3.1.1", + "jsonwebtoken": "^7.1.9", + "lodash": "^4.16.4", + "long": "~3.2.0", "mfb": "^0.12.0", "minimed-connect-to-nightscout": "git://github.com/mddub/minimed-connect-to-nightscout#v1.1.0", - "moment": "2.10.6", - "moment-timezone": "^0.4.0", - "mongodb": "2.1.18", - "mqtt": "~0.3.11", - "node-cache": "^3.0.0", + "moment": "2.15.1", + "moment-timezone": "^0.5.6", + "mongodb": "2.2.10", + "mqtt": "~2.0.1", + "node-cache": "^4.1.0", "parse-duration": "^0.1.1", - "pushover-notifications": "0.2.0", - "request": "^2.58.0", + "pushover-notifications": "0.2.3", + "request": "^2.75.0", "sgvdata": "git://github.com/ktind/sgvdata.git#wip/protobuf", "share2nightscout-bridge": "git://github.com/bewest/share2nightscout-bridge.git#wip/generalize", - "shiro-trie": "^0.3.7", - "simple-statistics": "~0.7.0", - "socket.io": "^1.3.5", - "sugar": "^1.4.1", + "shiro-trie": "^0.3.8", + "simple-statistics": "~2.1.0", + "socket.io": "^1.5.0", + "sugar": "^2.0.1", "traverse": "^0.6.6" }, "devDependencies": { - "istanbul": "~0.3.5", - "mocha": "~1.20.1", - "should": "~4.0.4", - "supertest": "~0.13.0", - "benv": "^1.1.0" + "istanbul": "~0.4.5", + "mocha": "~3.1.2", + "should": "~11.1.1", + "supertest": "~2.0.0", + "benv": "3.1.0" } } From 0a8e62018cd91de4ddf6035cee3291d2a5d2b57e Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Fri, 28 Oct 2016 17:41:15 -0700 Subject: [PATCH 002/303] higher test timeouts, only test with node 4 --- .travis.yml | 6 ------ tests/admintools.test.js | 2 +- tests/reports.test.js | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index c7b9ed5a57e..2cc93a767e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,9 @@ language: node_js sudo: false node_js: - - 0.10 - - 0.12 - 4 - - 5 matrix: fast_finish: true - allow_failures: - - node_js: 4 - - node_js: 5 services: mongodb script: make travis after_script: make report diff --git a/tests/admintools.test.js b/tests/admintools.test.js index 59230ff71a2..3c80e33f4c7 100644 --- a/tests/admintools.test.js +++ b/tests/admintools.test.js @@ -57,7 +57,7 @@ var someData = { describe('admintools', function ( ) { var self = this; - + this.timeout(5000); before(function (done) { benv.setup(function() { self.$ = require('jquery'); diff --git a/tests/reports.test.js b/tests/reports.test.js index 2ac66814eb2..f768844e35b 100644 --- a/tests/reports.test.js +++ b/tests/reports.test.js @@ -174,7 +174,7 @@ exampleProfile[0].startDate.setMilliseconds(0); describe('reports', function ( ) { var self = this; var headless = require('./fixtures/headless')(benv, this); - this.timeout(20000); + this.timeout(30000); before(function (done) { done( ); }); From 00d7630e483ee558e28433a50e018d299ac3134c Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Fri, 28 Oct 2016 17:46:42 -0700 Subject: [PATCH 003/303] shouldn't need the g++ addon now --- .travis.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2cc93a767e2..db5a77b1262 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,3 @@ matrix: services: mongodb script: make travis after_script: make report -env: - - CXX=g++-4.8 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 From 3800212f9d3b9e5b7441dc22d28e6f65ea0ada30 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Fri, 28 Oct 2016 17:52:11 -0700 Subject: [PATCH 004/303] bump timeouts more to prevent intermitent failures with benv tests --- tests/admintools.test.js | 2 +- tests/api.treatments.test.js | 2 +- tests/profileeditor.test.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/admintools.test.js b/tests/admintools.test.js index 3c80e33f4c7..d7204c687af 100644 --- a/tests/admintools.test.js +++ b/tests/admintools.test.js @@ -57,7 +57,7 @@ var someData = { describe('admintools', function ( ) { var self = this; - this.timeout(5000); + this.timeout(10000); before(function (done) { benv.setup(function() { self.$ = require('jquery'); diff --git a/tests/api.treatments.test.js b/tests/api.treatments.test.js index 6a1608158c4..5e8e8f7434c 100644 --- a/tests/api.treatments.test.js +++ b/tests/api.treatments.test.js @@ -5,7 +5,7 @@ var should = require('should'); var language = require('../lib/language')(); describe('Treatment API', function ( ) { - this.timeout(2000); + this.timeout(10000); var self = this; var api = require('../lib/api/'); diff --git a/tests/profileeditor.test.js b/tests/profileeditor.test.js index 1c470e37a8d..12a030a4171 100644 --- a/tests/profileeditor.test.js +++ b/tests/profileeditor.test.js @@ -71,7 +71,7 @@ var someData = { describe('Profile editor', function ( ) { - this.timeout(5000); + this.timeout(10000); var headless = require('./fixtures/headless')(benv, this); before(function (done) { From 1190ad73865c319f25d635bd05b95f97023206b3 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Thu, 3 Nov 2016 19:51:38 -0700 Subject: [PATCH 005/303] fix reports by rolling back jquery; also rollback mqtt since I don't have a good way to test; remove unused sugar dep --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c114b6d25b6..a440c7a9e29 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "express-extension-to-accept": "0.0.2", "forever": "~0.15.2", "git-rev": "git://github.com/bewest/git-rev.git", - "jquery": "^3.1.1", + "jquery": "^2.1.4", "jsonwebtoken": "^7.1.9", "lodash": "^4.16.4", "long": "~3.2.0", @@ -72,7 +72,7 @@ "moment-timezone": "^0.5.6", "mongodb": "2.2.10", "mongomock": "^0.1.2", - "mqtt": "~2.0.1", + "mqtt": "~0.3.11", "node-cache": "^4.1.0", "parse-duration": "^0.1.1", "pushover-notifications": "0.2.3", @@ -82,7 +82,6 @@ "shiro-trie": "^0.3.8", "simple-statistics": "~0.7.0", "socket.io": "^1.5.0", - "sugar": "^2.0.1", "traverse": "^0.6.6" }, "devDependencies": { From b21dd4ff273f876c579d9acd9cb94305ff066d47 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Thu, 3 Nov 2016 19:57:23 -0700 Subject: [PATCH 006/303] sugar does seem to be needed, using the previous version --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index a440c7a9e29..7a2f54659c4 100644 --- a/package.json +++ b/package.json @@ -82,6 +82,7 @@ "shiro-trie": "^0.3.8", "simple-statistics": "~0.7.0", "socket.io": "^1.5.0", + "sugar": "^1.4.1", "traverse": "^0.6.6" }, "devDependencies": { From 7556419dd8e33f37f8c89015eb458310941a73d5 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Thu, 3 Nov 2016 20:08:47 -0700 Subject: [PATCH 007/303] use ^version for mongodb and moment --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7a2f54659c4..954aa013c1d 100644 --- a/package.json +++ b/package.json @@ -68,9 +68,9 @@ "long": "~3.2.0", "mfb": "^0.12.0", "minimed-connect-to-nightscout": "git://github.com/mddub/minimed-connect-to-nightscout#v1.1.0", - "moment": "2.15.1", + "moment": "^2.15.1", "moment-timezone": "^0.5.6", - "mongodb": "2.2.10", + "mongodb": "^2.2.10", "mongomock": "^0.1.2", "mqtt": "~0.3.11", "node-cache": "^4.1.0", From 6bbf32cde7457e8764ef904b4adb7bc1500808c9 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Thu, 3 Nov 2016 20:14:23 -0700 Subject: [PATCH 008/303] bump up report test timeout some more --- tests/reports.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/reports.test.js b/tests/reports.test.js index f768844e35b..dbb3298722e 100644 --- a/tests/reports.test.js +++ b/tests/reports.test.js @@ -174,7 +174,7 @@ exampleProfile[0].startDate.setMilliseconds(0); describe('reports', function ( ) { var self = this; var headless = require('./fixtures/headless')(benv, this); - this.timeout(30000); + this.timeout(40000); before(function (done) { done( ); }); From 37241b5a3748acdf2a748cf6188b7fdbd7c81cfa Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sun, 11 Dec 2016 10:18:43 -0800 Subject: [PATCH 009/303] Show extra info when there are multiple devices uploading cgm data --- lib/plugins/bgnow.js | 78 +++++++++++++++++++++++++++++++++++++++++++- tests/bgnow.test.js | 6 ++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index a930f3893a1..4b53ff56d18 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -1,6 +1,7 @@ 'use strict'; var _ = require('lodash'); +var moment = require('moment'); var times = require('../times'); var offset = times.mins(2.5).msecs; @@ -9,6 +10,7 @@ var bucketFields = ['index', 'fromMills', 'toMills']; function init (ctx) { var translate = ctx.language.translate; + var timeago = require('./timeago')(ctx); var bgnow = { name: 'bgnow' @@ -177,6 +179,7 @@ function init (ctx) { }; bgnow.updateVisualisation = function updateVisualisation (sbx) { + var prop = sbx.properties.bgnow; var delta = sbx.properties.delta; var info = []; @@ -189,6 +192,57 @@ function init (ctx) { info.push({label: translate('Interpolated'), value: sbx.roundBGToDisplayFormat(sbx.scaleMgdl(delta.mean5MinsAgo)) + ' ' + sbx.unitsLabel}); } + var deviceInfos = { }; + + if (prop.sgvs) { + _.forEach(prop.sgvs, function deviceAndValue(entry) { + var device = deviceName(entry.device); + deviceInfos[device] = { + name: device + , time: timeFormat(moment(entry.mills), sbx) + , value: sbx.scaleEntry(entry) + , recent: entry + }; + }); + } + + if (delta.previous && delta.previous.sgvs) { + _.forEach(delta.previous.sgvs, function deviceAndValue(entry) { + var device = deviceName(entry.device); + var deviceInfo = deviceInfos[device]; + if (deviceInfo) { + var deviceDelta = bgnow.calcDelta( + { mills: deviceInfo.recent.mills , mean: deviceInfo.recent.mgdl} + , { mills: entry.mills, mean: entry.mgdl} + , sbx + ); + + if (deviceDelta) { + deviceInfo.delta = deviceDelta.display + } + } else { + deviceInfos[device] = { + name: device + , time: timeFormat(moment(entry.mills), sbx) + , value: sbx.scaleEntry(entry) + }; + } + }); + + if (deviceInfos.length > 0) { + _.forEach(deviceInfos, function addInfo (deviceInfo) { + var display = deviceInfo.value; + if (deviceInfo.delta) { + display += ' ' + deviceInfo.delta; + } + + display += ' (' + deviceInfo.time + ')'; + + info.push({label: deviceInfo.name, value: display}); + }); + } + } + sbx.pluginBase.updatePillText({ name: 'delta' , label: translate('BG Delta') @@ -197,10 +251,32 @@ function init (ctx) { }, { value: display , label: sbx.unitsLabel - , info: info + , info: _.isEmpty(info) ? null : info }); }; + function deviceName (device) { + var last = device ? _.last(device.split('://')) : 'unknown'; + return _.first(last.split('/')); + } + + function timeFormat (m, sbx) { + var when; + if (m && sbx.data.inRetroMode) { + when = m.format('LT'); + } else if (m) { + when = formatAgo(m, sbx.time); + } else { + when = 'unknown'; + } + + return when; + } + + function formatAgo (m, nowMills) { + var ago = timeago.calcDisplay({mills: m.valueOf()}, nowMills); + return translate('%1' + ago.shortLabel + (ago.shortLabel.length === 1 ? ' ago' : ''), { params: [(ago.value ? ago.value : '')]}); + } return bgnow; diff --git a/tests/bgnow.test.js b/tests/bgnow.test.js index 7a21da64acc..233f1c13dbc 100644 --- a/tests/bgnow.test.js +++ b/tests/bgnow.test.js @@ -1,7 +1,7 @@ 'use strict'; -require('should'); -var _ =require('lodash'); +var should = require('should'); +var _ = require('lodash'); var FIVE_MINS = 300000; var SIX_MINS = 360000; @@ -23,7 +23,7 @@ describe('BG Now', function ( ) { updatePillText: function mockedUpdatePillText (plugin, options) { options.label.should.equal(ctx.settings.units); options.value.should.equal('+5'); - options.info.length.should.equal(0); + should.not.exist(options.info); done(); } , language: { translate: function(text) { return text; } } From c2e3ec4d0c26d9100ebe1802e81be1691286dca2 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sun, 11 Dec 2016 10:35:18 -0800 Subject: [PATCH 010/303] use _.forIn, remove name field, fix bug --- lib/plugins/bgnow.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index 4b53ff56d18..1e52382daef 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -198,8 +198,7 @@ function init (ctx) { _.forEach(prop.sgvs, function deviceAndValue(entry) { var device = deviceName(entry.device); deviceInfos[device] = { - name: device - , time: timeFormat(moment(entry.mills), sbx) + time: timeFormat(moment(entry.mills), sbx) , value: sbx.scaleEntry(entry) , recent: entry }; @@ -222,25 +221,22 @@ function init (ctx) { } } else { deviceInfos[device] = { - name: device - , time: timeFormat(moment(entry.mills), sbx) + time: timeFormat(moment(entry.mills), sbx) , value: sbx.scaleEntry(entry) }; } }); - if (deviceInfos.length > 0) { - _.forEach(deviceInfos, function addInfo (deviceInfo) { - var display = deviceInfo.value; - if (deviceInfo.delta) { - display += ' ' + deviceInfo.delta; - } + _.forIn(deviceInfos, function addInfo (deviceInfo, name) { + var display = deviceInfo.value; + if (deviceInfo.delta) { + display += ' ' + deviceInfo.delta; + } - display += ' (' + deviceInfo.time + ')'; + display += ' (' + deviceInfo.time + ')'; - info.push({label: deviceInfo.name, value: display}); - }); - } + info.push({label: name, value: display}); + }); } sbx.pluginBase.updatePillText({ From 103fce06af27128d35af776aec7b1903ff5f6a00 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sun, 11 Dec 2016 10:46:17 -0800 Subject: [PATCH 011/303] bump version to 0.9.3-dev-20161211 --- bower.json | 2 +- package.json | 2 +- static/index.html | 8 ++++---- static/report/index.html | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 79e5006b11a..43b35a68b6d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.9.2", + "version": "0.9.3-dev-20161211", "dependencies": { "colorbrewer": "~1.0.0", "jQuery-Storage-API": "~1.7.2", diff --git a/package.json b/package.json index 8c977db3391..3b24206b17c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Nightscout", - "version": "0.9.2", + "version": "0.9.3-dev-20161211", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", diff --git a/static/index.html b/static/index.html index e868d0cbe05..961bee5214b 100644 --- a/static/index.html +++ b/static/index.html @@ -25,10 +25,10 @@ - - + + - + @@ -590,7 +590,7 @@ - + diff --git a/static/report/index.html b/static/report/index.html index bb67dd1520a..41cd575abd4 100644 --- a/static/report/index.html +++ b/static/report/index.html @@ -23,7 +23,7 @@ - + @@ -116,7 +116,7 @@

Nightscout reporting Authentication status: - + @@ -125,7 +125,7 @@

Nightscout reporting - + From 4d1aadc2c98957cb1668bdc942ea91bf935e372a Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sun, 11 Dec 2016 10:52:49 -0800 Subject: [PATCH 012/303] don't forget to check the length --- lib/plugins/bgnow.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index 1e52382daef..a211b947576 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -194,7 +194,7 @@ function init (ctx) { var deviceInfos = { }; - if (prop.sgvs) { + if (prop.sgvs && prop.sgvs.length > 1) { _.forEach(prop.sgvs, function deviceAndValue(entry) { var device = deviceName(entry.device); deviceInfos[device] = { @@ -205,7 +205,7 @@ function init (ctx) { }); } - if (delta.previous && delta.previous.sgvs) { + if (delta.previous && delta.previous.sgvs && delta.previous.sgvs.length > 1) { _.forEach(delta.previous.sgvs, function deviceAndValue(entry) { var device = deviceName(entry.device); var deviceInfo = deviceInfos[device]; From 830b7b082c40fb9d1a91e625e73c057f90f60060 Mon Sep 17 00:00:00 2001 From: Darrell Wright Date: Sun, 11 Dec 2016 21:32:56 -0500 Subject: [PATCH 013/303] Fixed reference of undefined error Was seeing errors in js console about delta being undefined. Put check in --- lib/plugins/bgnow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index a211b947576..845a92f612f 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -205,7 +205,7 @@ function init (ctx) { }); } - if (delta.previous && delta.previous.sgvs && delta.previous.sgvs.length > 1) { + if (delta && delta.previous && delta.previous.sgvs && delta.previous.sgvs.length > 1) { _.forEach(delta.previous.sgvs, function deviceAndValue(entry) { var device = deviceName(entry.device); var deviceInfo = deviceInfos[device]; From 8c8b881674521003502a6cfc019e7164a40b4456 Mon Sep 17 00:00:00 2001 From: Darrell Wright Date: Sun, 11 Dec 2016 22:20:44 -0500 Subject: [PATCH 014/303] Added proper display of metre bg reads The main client window did not scale bg reads to reflect client's unit choice --- lib/client/renderer.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client/renderer.js b/lib/client/renderer.js index 078d762e361..340e15a2ab2 100644 --- a/lib/client/renderer.js +++ b/lib/client/renderer.js @@ -146,7 +146,7 @@ function init (client, d3) { var rawbgInfo = getRawbgInfo(); client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); - client.tooltip.html('' + translate('BG')+ ': ' + client.sbx.scaleEntry(d) + + client.tooltip.html('' + translate('BG')+ ': ' + client.sbx.scaleMgdl( d ) + (d.type === 'mbg' ? '
' + translate('Device') + ': ' + d.device : '') + (rawbgInfo.value ? '
' + translate('Raw BG') + ': ' + rawbgInfo.value : '') + (rawbgInfo.noise ? '
' + translate('Noise') + ': ' + rawbgInfo.noise : '') + @@ -174,7 +174,7 @@ function init (client, d3) { return ''+translate('Time')+': ' + client.formatTime(new Date(d.mills)) + '
' + (d.eventType ? ''+translate('Treatment type')+': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + (d.reason ? ''+translate('Reason')+': ' + translate(d.reason) + '
' : '') + - (d.glucose ? ''+translate('BG')+': ' + d.glucose + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')': '') + '
' : '') + + (d.glucose ? ''+translate('BG')+': ' + client.sbx.scaleMgdl(d.glucose) + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')': '') + '
' : '') + (d.enteredBy ? ''+translate('Entered By')+': ' + d.enteredBy + '
' : '') + (d.targetTop ? ''+translate('Target Top')+': ' + d.targetTop + '
' : '') + (d.targetBottom ? ''+translate('Target Bottom')+': ' + d.targetBottom + '
' : '') + @@ -493,7 +493,7 @@ function init (client, d3) { (treatment.carbs ? '' + translate('Carbs') + ': ' + treatment.carbs + '
' : '') + (treatment.insulin ? '' + translate('Insulin') + ': ' + treatment.insulin + '
' : '') + (treatment.enteredinsulin ? '' + translate('Combo Bolus') + ': ' + treatment.enteredinsulin + 'U, ' + treatment.splitNow + '% : ' + treatment.splitExt + '%, ' + translate('Duration') + ': ' + treatment.duration + '
' : '') + - (treatment.glucose ? '' + translate('BG') + ': ' + treatment.glucose + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + + (treatment.glucose ? '' + translate('BG') + ': ' + client.sbx.scaleMgdl(treatment.glucose) + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + (treatment.enteredBy ? '' + translate('Entered By') + ': ' + treatment.enteredBy + '
' : '') + (treatment.notes ? '' + translate('Notes') + ': ' + treatment.notes : '') + boluscalcTooltip(treatment) From e72d5e13352884c7b9283c535432a3eb7b477207 Mon Sep 17 00:00:00 2001 From: Darrell Wright Date: Sun, 11 Dec 2016 23:04:29 -0500 Subject: [PATCH 015/303] Added proper units on glucose In treatments report, the unit did not scale to clients chosen unit --- lib/report_plugins/treatments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/report_plugins/treatments.js b/lib/report_plugins/treatments.js index f4743592427..a447478663d 100644 --- a/lib/report_plugins/treatments.js +++ b/lib/report_plugins/treatments.js @@ -306,7 +306,7 @@ treatments.report = function report_treatments(datastorage, sorteddaystoshow, op ) .append($('').append(new Date(tr.created_at).toLocaleTimeString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3'))) .append($('').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : '')) - .append($('').attr('align','center').append(tr.glucose ? tr.glucose + ' ('+translate(tr.glucoseType)+')' : '')) + .append($('').attr('align','center').append(tr.glucose ? client.sbx.scaleMgdl(tr.glucose) + ' ('+translate(tr.glucoseType)+')' : '')) .append($('').attr('align','center').append(tr.insulin ? tr.insulin.toFixed(2) : '')) .append($('').attr('align','center').append(tr.carbs ? tr.carbs : '')) .append($('').attr('align','center').append(tr.duration ? tr.duration : '')) From efe69e5095d706fdc8d14d9dedab2de329c507c7 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sun, 11 Dec 2016 23:57:48 -0800 Subject: [PATCH 016/303] refactoring: move deviceName, timeFormat, formatAgo, timeAt to utils --- lib/client/browser-settings.js | 2 +- lib/client/index.js | 5 ++++- lib/plugins/bgnow.js | 33 +++++------------------------- lib/plugins/iob.js | 6 +++--- lib/plugins/loop.js | 30 ++++----------------------- lib/plugins/openaps.js | 33 +++++------------------------- lib/report_plugins/index.js | 9 +++++++-- lib/utils.js | 37 ++++++++++++++++++++++++++++++++-- tests/utils.test.js | 13 ++++++------ 9 files changed, 71 insertions(+), 97 deletions(-) diff --git a/lib/client/browser-settings.js b/lib/client/browser-settings.js index 910214c4b63..0281ea4a28c 100644 --- a/lib/client/browser-settings.js +++ b/lib/client/browser-settings.js @@ -13,7 +13,7 @@ function init (client, serverSettings, $) { var settings = require('../settings')(); function loadForm ( ) { - var utils = require('../utils')(settings); + var utils = client.utils; var language = require('../language')(); language.set(settings.language); var translate = language.translate; diff --git a/lib/client/index.js b/lib/client/index.js index 864d9fa35ce..841dedd7e22 100644 --- a/lib/client/index.js +++ b/lib/client/index.js @@ -149,7 +149,10 @@ client.load = function load(serverSettings, callback) { , pluginBase: client.plugins.base(majorPills, minorPills, statusPills, bgStatus, client.tooltip, $.localStorage) }; - client.utils = require('../utils')(client.ctx.settings); + client.utils = require('../utils')({ + settings: client.settings + , language: language + }); client.sbx = sandbox.clientInit(client.ctx, client.now); client.renderer = require('./renderer')(client, d3, $); diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index 845a92f612f..429ea006334 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -10,7 +10,7 @@ var bucketFields = ['index', 'fromMills', 'toMills']; function init (ctx) { var translate = ctx.language.translate; - var timeago = require('./timeago')(ctx); + var utils = require('../utils')(ctx); var bgnow = { name: 'bgnow' @@ -196,9 +196,9 @@ function init (ctx) { if (prop.sgvs && prop.sgvs.length > 1) { _.forEach(prop.sgvs, function deviceAndValue(entry) { - var device = deviceName(entry.device); + var device = utils.deviceName(entry.device); deviceInfos[device] = { - time: timeFormat(moment(entry.mills), sbx) + time: utils.timeFormat(moment(entry.mills), sbx) , value: sbx.scaleEntry(entry) , recent: entry }; @@ -207,7 +207,7 @@ function init (ctx) { if (delta && delta.previous && delta.previous.sgvs && delta.previous.sgvs.length > 1) { _.forEach(delta.previous.sgvs, function deviceAndValue(entry) { - var device = deviceName(entry.device); + var device = utils.deviceName(entry.device); var deviceInfo = deviceInfos[device]; if (deviceInfo) { var deviceDelta = bgnow.calcDelta( @@ -221,7 +221,7 @@ function init (ctx) { } } else { deviceInfos[device] = { - time: timeFormat(moment(entry.mills), sbx) + time: utils.timeFormat(moment(entry.mills), sbx) , value: sbx.scaleEntry(entry) }; } @@ -251,29 +251,6 @@ function init (ctx) { }); }; - function deviceName (device) { - var last = device ? _.last(device.split('://')) : 'unknown'; - return _.first(last.split('/')); - } - - function timeFormat (m, sbx) { - var when; - if (m && sbx.data.inRetroMode) { - when = m.format('LT'); - } else if (m) { - when = formatAgo(m, sbx.time); - } else { - when = 'unknown'; - } - - return when; - } - - function formatAgo (m, nowMills) { - var ago = timeago.calcDisplay({mills: m.valueOf()}, nowMills); - return translate('%1' + ago.shortLabel + (ago.shortLabel.length === 1 ? ' ago' : ''), { params: [(ago.value ? ago.value : '')]}); - } - return bgnow; } diff --git a/lib/plugins/iob.js b/lib/plugins/iob.js index 8ee20b518ca..dde41184fd0 100644 --- a/lib/plugins/iob.js +++ b/lib/plugins/iob.js @@ -2,12 +2,12 @@ var _ = require('lodash') , moment = require('moment') - , times = require('../times') - , utils = require('../utils')(); + , times = require('../times'); function init(ctx) { var translate = ctx.language.translate; - + var utils = require('../utils')(ctx); + var iob = { name: 'iob' , label: 'Insulin-on-Board' diff --git a/lib/plugins/loop.js b/lib/plugins/loop.js index 0bd75255c28..70947a3b12a 100644 --- a/lib/plugins/loop.js +++ b/lib/plugins/loop.js @@ -9,6 +9,7 @@ var levels = require('../levels'); function init(ctx) { var timeago = require('./timeago')(ctx); + var utils = require('../utils')(ctx); var loop = { name: 'loop' @@ -153,7 +154,7 @@ function init(ctx) { sbx.notifications.requestNotify({ level: level , title: 'Loop isn\'t looping' - , message: 'Last Loop: ' + formatAgo(prop.lastLoop.moment, now.valueOf()) + , message: 'Last Loop: ' + utils.formatAgo(prop.lastLoop.moment, now.valueOf()) , pushoverSound: 'echo' , group: 'Loop' , plugin: loop @@ -291,7 +292,7 @@ function init(ctx) { var info = _.map(sorted, function eventToInfo (event) { return { - label: timeAt(false, sbx) + timeFormat(event.time, sbx) + label: utils.timeAt(false, sbx) + utils.timeFormat(event.time, sbx) , value: event.value }; }); @@ -307,7 +308,7 @@ function init(ctx) { var lastLoopMoment = prop.lastLoop ? prop.lastLoop.moment : null; sbx.pluginBase.updatePillText(loop, { - value: timeFormat(lastLoopMoment, sbx) + value: utils.timeFormat(lastLoopMoment, sbx) , label: label , info: info , pillClass: statusClass(prop, prefs, sbx) @@ -402,29 +403,6 @@ function init(ctx) { return level; } - function timeFormat (m, sbx) { - - var when; - if (m && sbx.data.inRetroMode) { - when = m.format('LT'); - } else if (m) { - when = formatAgo(m, sbx.time); - } else { - when = 'unknown'; - } - - return when; - } - - function formatAgo (m, nowMills) { - var ago = timeago.calcDisplay({mills: m.valueOf()}, nowMills); - return (ago.value ? ago.value : '') + ago.shortLabel + (ago.shortLabel.length === 1 ? ' ago' : ''); - } - - function timeAt (prefix, sbx) { - return sbx.data.inRetroMode ? (prefix ? ' ' : '') + '@ ' : (prefix ? ', ' : ''); - } - return loop; } diff --git a/lib/plugins/openaps.js b/lib/plugins/openaps.js index 99431611326..b5cf55aec3c 100644 --- a/lib/plugins/openaps.js +++ b/lib/plugins/openaps.js @@ -9,7 +9,7 @@ var levels = require('../levels'); function init(ctx) { var timeago = require('./timeago')(ctx); - var translate = ctx.language.translate; + var utils = require('../utils')(ctx); var openaps = { name: 'openaps' @@ -96,7 +96,7 @@ function init(ctx) { if (!device) { device = { - name: uri.indexOf('openaps://') === 0 ? uri.substring('openaps://'.length) : uri + name: utils.deviceName(uri) , uri: uri }; @@ -264,7 +264,7 @@ function init(ctx) { sbx.notifications.requestNotify({ level: level , title: 'OpenAPS isn\'t looping' - , message: 'Last Loop: ' + formatAgo(prop.lastLoopMoment, now.valueOf()) + , message: 'Last Loop: ' + utils.formatAgo(prop.lastLoopMoment, now.valueOf()) , pushoverSound: 'echo' , group: 'OpenAPS' , plugin: openaps @@ -420,7 +420,7 @@ function init(ctx) { var info = _.map(sorted, function eventToInfo (event) { return { - label: timeAt(false, sbx) + timeFormat(event.time, sbx) + label: utils.timeAt(false, sbx) + utils.timeFormat(event.time, sbx) , value: event.value }; }); @@ -431,7 +431,7 @@ function init(ctx) { } sbx.pluginBase.updatePillText(openaps, { - value: timeFormat(prop.lastLoopMoment, sbx) + value: utils.timeFormat(prop.lastLoopMoment, sbx) , label: label , info: info , pillClass: statusClass(prop, prefs, sbx) @@ -493,29 +493,6 @@ function init(ctx) { return level; } - function timeFormat (m, sbx) { - - var when; - if (m && sbx.data.inRetroMode) { - when = m.format('LT'); - } else if (m) { - when = formatAgo(m, sbx.time); - } else { - when = 'unknown'; - } - - return when; - } - - function formatAgo (m, nowMills) { - var ago = timeago.calcDisplay({mills: m.valueOf()}, nowMills); - return translate('%1' + ago.shortLabel + (ago.shortLabel.length === 1 ? ' ago' : ''), { params: [(ago.value ? ago.value : '')]}); - } - - function timeAt (prefix, sbx) { - return sbx.data.inRetroMode ? (prefix ? ' ' : '') + '@ ' : (prefix ? ', ' : ''); - } - return openaps; } diff --git a/lib/report_plugins/index.js b/lib/report_plugins/index.js index b9566913b5c..d8c41096656 100644 --- a/lib/report_plugins/index.js +++ b/lib/report_plugins/index.js @@ -38,8 +38,13 @@ function init() { plugins.consts = consts; - plugins.utils = require('./utils')(); - + plugins.utils = require('./utils')({ + //TODO: refactor so all this happens after init somehow + // until then use some defaults so things don't blow up + language: require('../language')() + , settings: {} + }); + plugins.addHtmlFromPlugins = function addHtmlFromPlugins(client) { plugins.eachPlugin(function addHtml(p) { // add main plugin html diff --git a/lib/utils.js b/lib/utils.js index 509208ddfc6..da53e700294 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,10 +1,15 @@ 'use strict'; +var _ = require('lodash'); var moment = require('moment-timezone'); var units = require('./units')(); -function init(settings) { +function init(ctx) { + + var settings = ctx.settings; + var translate = ctx.language.translate; + var timeago = require('./plugins/timeago')(ctx); var utils = { }; @@ -34,7 +39,35 @@ function init(settings) { return moment(datestring + ' ' + timestring, 'YYYY-MM-D HH:mm'); }; - return utils; + + utils.deviceName = function deviceName (device) { + var last = device ? _.last(device.split('://')) : 'unknown'; + return _.first(last.split('/')); + }; + + utils.timeFormat = function timeFormat (m, sbx) { + var when; + if (m && sbx.data.inRetroMode) { + when = m.format('LT'); + } else if (m) { + when = utils.formatAgo(m, sbx.time); + } else { + when = 'unknown'; + } + + return when; + }; + + utils.formatAgo = function formatAgo (m, nowMills) { + var ago = timeago.calcDisplay({mills: m.valueOf()}, nowMills); + return translate('%1' + ago.shortLabel + (ago.shortLabel.length === 1 ? ' ago' : ''), { params: [(ago.value ? ago.value : '')]}); + }; + + utils.timeAt = function timeAt (prefix, sbx) { + return sbx.data.inRetroMode ? (prefix ? ' ' : '') + '@ ' : (prefix ? ', ' : ''); + }; + + return utils; } module.exports = init; \ No newline at end of file diff --git a/tests/utils.test.js b/tests/utils.test.js index 86ea7ea12a0..be0b298290d 100644 --- a/tests/utils.test.js +++ b/tests/utils.test.js @@ -3,12 +3,13 @@ require('should'); describe('utils', function ( ) { - var settings = { - alarmTimeagoUrgentMins: 30 - , alarmTimeagoWarnMins: 15 - }; - - var utils = require('../lib/utils')(settings); + var utils = require('../lib/utils')({ + language: require('../lib/language')() + , settings: { + alarmTimeagoUrgentMins: 30 + , alarmTimeagoWarnMins: 15 + } + }); it('format numbers', function () { utils.toFixed(5.499999999).should.equal('5.50'); From 6032c8f8cd179638e5c0424183d2367c553f64d6 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 12 Dec 2016 00:08:21 -0800 Subject: [PATCH 017/303] wait till all deviceInfos are collected before checking length --- lib/plugins/bgnow.js | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/plugins/bgnow.js b/lib/plugins/bgnow.js index 429ea006334..2f9b39b5e82 100644 --- a/lib/plugins/bgnow.js +++ b/lib/plugins/bgnow.js @@ -194,7 +194,7 @@ function init (ctx) { var deviceInfos = { }; - if (prop.sgvs && prop.sgvs.length > 1) { + if (prop.sgvs) { _.forEach(prop.sgvs, function deviceAndValue(entry) { var device = utils.deviceName(entry.device); deviceInfos[device] = { @@ -205,7 +205,7 @@ function init (ctx) { }); } - if (delta && delta.previous && delta.previous.sgvs && delta.previous.sgvs.length > 1) { + if (delta && delta.previous && delta.previous.sgvs) { _.forEach(delta.previous.sgvs, function deviceAndValue(entry) { var device = utils.deviceName(entry.device); var deviceInfo = deviceInfos[device]; @@ -227,16 +227,18 @@ function init (ctx) { } }); - _.forIn(deviceInfos, function addInfo (deviceInfo, name) { - var display = deviceInfo.value; - if (deviceInfo.delta) { - display += ' ' + deviceInfo.delta; - } + if (_.keys(deviceInfos).length > 1) { + _.forIn(deviceInfos, function addInfo(deviceInfo, name) { + var display = deviceInfo.value; + if (deviceInfo.delta) { + display += ' ' + deviceInfo.delta; + } - display += ' (' + deviceInfo.time + ')'; + display += ' (' + deviceInfo.time + ')'; - info.push({label: name, value: display}); - }); + info.push({label: name, value: display}); + }); + } } sbx.pluginBase.updatePillText({ From 5e6f136e98e93ab307125260b836b91771c56908 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 12 Dec 2016 00:09:40 -0800 Subject: [PATCH 018/303] bump version to 0.9.3-dev-20161212 --- bower.json | 2 +- package.json | 2 +- static/index.html | 8 ++++---- static/report/index.html | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 43b35a68b6d..9fd50616f02 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.9.3-dev-20161211", + "version": "0.9.3-dev-20161212", "dependencies": { "colorbrewer": "~1.0.0", "jQuery-Storage-API": "~1.7.2", diff --git a/package.json b/package.json index 3b24206b17c..9f16b45be0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Nightscout", - "version": "0.9.3-dev-20161211", + "version": "0.9.3-dev-20161212", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", diff --git a/static/index.html b/static/index.html index 961bee5214b..b84d91fe51e 100644 --- a/static/index.html +++ b/static/index.html @@ -25,10 +25,10 @@ - - + + - + @@ -590,7 +590,7 @@ - + diff --git a/static/report/index.html b/static/report/index.html index 41cd575abd4..6d1e32c283b 100644 --- a/static/report/index.html +++ b/static/report/index.html @@ -23,7 +23,7 @@ - + @@ -116,7 +116,7 @@

Nightscout reporting Authentication status: - + @@ -125,7 +125,7 @@

Nightscout reporting - + From bc5d5d9f0b8b01ad621f5a5d4b09a99445d67422 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 12 Dec 2016 18:05:23 -0800 Subject: [PATCH 019/303] go back to using scaleEntry instead of scaleMgdl --- lib/client/renderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/client/renderer.js b/lib/client/renderer.js index 340e15a2ab2..fab5ee7f6cc 100644 --- a/lib/client/renderer.js +++ b/lib/client/renderer.js @@ -146,7 +146,7 @@ function init (client, d3) { var rawbgInfo = getRawbgInfo(); client.tooltip.transition().duration(TOOLTIP_TRANS_MS).style('opacity', .9); - client.tooltip.html('' + translate('BG')+ ': ' + client.sbx.scaleMgdl( d ) + + client.tooltip.html('' + translate('BG')+ ': ' + client.sbx.scaleEntry( d ) + (d.type === 'mbg' ? '
' + translate('Device') + ': ' + d.device : '') + (rawbgInfo.value ? '
' + translate('Raw BG') + ': ' + rawbgInfo.value : '') + (rawbgInfo.noise ? '
' + translate('Noise') + ': ' + rawbgInfo.noise : '') + From 25e5af5390d0ac7c4beff89ada710aacfcd40624 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 12 Dec 2016 18:20:38 -0800 Subject: [PATCH 020/303] bump version to 0.9.3-dev-20161212b --- bower.json | 2 +- package.json | 2 +- static/index.html | 8 ++++---- static/report/index.html | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index 9fd50616f02..b86ff455a1d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.9.3-dev-20161212", + "version": "0.9.3-dev-20161212b", "dependencies": { "colorbrewer": "~1.0.0", "jQuery-Storage-API": "~1.7.2", diff --git a/package.json b/package.json index 9f16b45be0b..f4862587818 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Nightscout", - "version": "0.9.3-dev-20161212", + "version": "0.9.3-dev-20161212b", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", diff --git a/static/index.html b/static/index.html index b84d91fe51e..0e484dc1369 100644 --- a/static/index.html +++ b/static/index.html @@ -25,10 +25,10 @@ - - + + - + @@ -590,7 +590,7 @@ - + diff --git a/static/report/index.html b/static/report/index.html index 6d1e32c283b..1aaab8c9c4f 100644 --- a/static/report/index.html +++ b/static/report/index.html @@ -23,7 +23,7 @@ - + @@ -116,7 +116,7 @@

Nightscout reporting Authentication status: - + @@ -125,7 +125,7 @@

Nightscout reporting - + From 5e8d15cac5a5cc497ddfcf4c917e136352a0f392 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 19:54:41 -0800 Subject: [PATCH 021/303] add option to disable bundle minification --- README.md | 1 + app.js | 2 +- bundle/index.js | 5 +++-- env.js | 3 +++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index eca17071558..1ffb9af6247 100644 --- a/README.md +++ b/README.md @@ -218,6 +218,7 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm * `SSL_CERT` - Path to your ssl cert file, so that ssl(https) can be enabled directly in node.js * `SSL_CA` - Path to your ssl ca file, so that ssl(https) can be enabled directly in node.js * `HEARTBEAT` (`60`) - Number of seconds to wait in between database checks + * `DEBUG_MINIFY` (`true`) - Debug option, setting to `false` will disable bundle minification to help tracking down error and speed up development ### Predefined values for your browser settings (optional) diff --git a/app.js b/app.js index 45c78b2fc0d..f845de13435 100644 --- a/app.js +++ b/app.js @@ -72,7 +72,7 @@ function create (env, ctx) { // serve the static content app.use(staticFiles); - var bundle = require('./bundle')(); + var bundle = require('./bundle')(env); app.use(bundle); // Handle errors with express's errorhandler, to display more readable error messages. diff --git a/bundle/index.js b/bundle/index.js index cb22a5ebcfa..e99e3fdf1e1 100644 --- a/bundle/index.js +++ b/bundle/index.js @@ -2,13 +2,14 @@ var browserify_express = require('browserify-express'); -function bundle() { +function bundle(env) { + console.info('>>>debug', env.debug); return browserify_express({ entry: __dirname + '/bundle.source.js', watch: __dirname + '/../lib/', mount: '/public/js/bundle.js', verbose: true, - minify: true, + minify: env.debug.minify, bundle_opts: { debug: true }, // enable inline sourcemap on js files write_file: __dirname + '/bundle.out.js' }); diff --git a/env.js b/env.js index 73d3ce58a25..6527d0750f0 100644 --- a/env.js +++ b/env.js @@ -20,6 +20,9 @@ function config ( ) { env.HOSTNAME = readENV('HOSTNAME', null); env.IMPORT_CONFIG = readENV('IMPORT_CONFIG', null); env.static_files = readENV('NIGHTSCOUT_STATIC_FILES', __dirname + '/static/'); + env.debug = { + minify: readENVTruthy('DEBUG_MINIFY', true) + }; if (env.err) { delete env.err; From fc6a936d6a884d1e04a176fdac642579b73233b9 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 20:00:02 -0800 Subject: [PATCH 022/303] use utils.scaleMgdl since there are times where client.sbx hasn't been defined yet --- lib/client/renderer.js | 4 ++-- lib/report_plugins/treatments.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client/renderer.js b/lib/client/renderer.js index fab5ee7f6cc..5ae282e7bd4 100644 --- a/lib/client/renderer.js +++ b/lib/client/renderer.js @@ -174,7 +174,7 @@ function init (client, d3) { return ''+translate('Time')+': ' + client.formatTime(new Date(d.mills)) + '
' + (d.eventType ? ''+translate('Treatment type')+': ' + translate(client.careportal.resolveEventName(d.eventType)) + '
' : '') + (d.reason ? ''+translate('Reason')+': ' + translate(d.reason) + '
' : '') + - (d.glucose ? ''+translate('BG')+': ' + client.sbx.scaleMgdl(d.glucose) + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')': '') + '
' : '') + + (d.glucose ? ''+translate('BG')+': ' + utils.scaleMgdl(d.glucose) + (d.glucoseType ? ' (' + translate(d.glucoseType) + ')': '') + '
' : '') + (d.enteredBy ? ''+translate('Entered By')+': ' + d.enteredBy + '
' : '') + (d.targetTop ? ''+translate('Target Top')+': ' + d.targetTop + '
' : '') + (d.targetBottom ? ''+translate('Target Bottom')+': ' + d.targetBottom + '
' : '') + @@ -493,7 +493,7 @@ function init (client, d3) { (treatment.carbs ? '' + translate('Carbs') + ': ' + treatment.carbs + '
' : '') + (treatment.insulin ? '' + translate('Insulin') + ': ' + treatment.insulin + '
' : '') + (treatment.enteredinsulin ? '' + translate('Combo Bolus') + ': ' + treatment.enteredinsulin + 'U, ' + treatment.splitNow + '% : ' + treatment.splitExt + '%, ' + translate('Duration') + ': ' + treatment.duration + '
' : '') + - (treatment.glucose ? '' + translate('BG') + ': ' + client.sbx.scaleMgdl(treatment.glucose) + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + + (treatment.glucose ? '' + translate('BG') + ': ' + utils.scaleMgdl(treatment.glucose) + (treatment.glucoseType ? ' (' + translate(treatment.glucoseType) + ')' : '') + '
' : '') + (treatment.enteredBy ? '' + translate('Entered By') + ': ' + treatment.enteredBy + '
' : '') + (treatment.notes ? '' + translate('Notes') + ': ' + treatment.notes : '') + boluscalcTooltip(treatment) diff --git a/lib/report_plugins/treatments.js b/lib/report_plugins/treatments.js index a447478663d..a5c57f8843f 100644 --- a/lib/report_plugins/treatments.js +++ b/lib/report_plugins/treatments.js @@ -306,7 +306,7 @@ treatments.report = function report_treatments(datastorage, sorteddaystoshow, op ) .append($('').append(new Date(tr.created_at).toLocaleTimeString().replace(/([\d]+:[\d]{2})(:[\d]{2})(.*)/, '$1$3'))) .append($('').append(tr.eventType ? translate(client.careportal.resolveEventName(tr.eventType)) : '')) - .append($('').attr('align','center').append(tr.glucose ? client.sbx.scaleMgdl(tr.glucose) + ' ('+translate(tr.glucoseType)+')' : '')) + .append($('').attr('align','center').append(tr.glucose ? client.utils.scaleMgdl(tr.glucose) + ' ('+translate(tr.glucoseType)+')' : '')) .append($('').attr('align','center').append(tr.insulin ? tr.insulin.toFixed(2) : '')) .append($('').attr('align','center').append(tr.carbs ? tr.carbs : '')) .append($('').attr('align','center').append(tr.duration ? tr.duration : '')) From 0dbfcfb3e53d6989bfd7993a334efc349a138cbb Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 20:28:24 -0800 Subject: [PATCH 023/303] clean up --- bundle/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bundle/index.js b/bundle/index.js index e99e3fdf1e1..2b37869c95b 100644 --- a/bundle/index.js +++ b/bundle/index.js @@ -3,7 +3,6 @@ var browserify_express = require('browserify-express'); function bundle(env) { - console.info('>>>debug', env.debug); return browserify_express({ entry: __dirname + '/bundle.source.js', watch: __dirname + '/../lib/', From 3172c82b2dd4859cad86d55b0f7894cb4d22f2f8 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 20:29:15 -0800 Subject: [PATCH 024/303] make sure old pill tooltips aren't shown if there isn't a new tooltip --- lib/plugins/pluginbase.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/plugins/pluginbase.js b/lib/plugins/pluginbase.js index adb59a7644f..e3f0f66b8e7 100644 --- a/lib/plugins/pluginbase.js +++ b/lib/plugins/pluginbase.js @@ -97,6 +97,8 @@ function init (majorPills, minorPills, statusPills, bgStatus, tooltip) { .duration(200) .style('opacity', 0); }); + } else { + pill.off('mouseover'); } }; From d49319b14773e19f4389d4c9409ce014269a8539 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 20:50:05 -0800 Subject: [PATCH 025/303] show last carbs even if careportal cob is 0 --- lib/plugins/cob.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/plugins/cob.js b/lib/plugins/cob.js index e1bd8c4660e..f0161067657 100644 --- a/lib/plugins/cob.js +++ b/lib/plugins/cob.js @@ -48,7 +48,7 @@ function init(ctx) { if (_.isEmpty(result)) { result = treatmentCOB; result.source = 'Care Portal'; - } else if (treatmentCOB.cob) { + } else if (treatmentCOB) { result.treatmentCOB = treatmentCOB; } @@ -252,16 +252,16 @@ function init(ctx) { var displayCob = Math.round(prop.cob * 10) / 10; - var info = null; - if (prop.treatmentCOB !== undefined) { - info = [ ]; + var info = [ ]; + if (prop.treatmentCOB !== undefined && prop.treatmentCOB.cob) { info.push({label: translate('Careportal COB'), value: Math.round(prop.treatmentCOB.cob * 10) / 10}); + } - if (prop.treatmentCOB.lastCarbs) { - var when = new Date(prop.treatmentCOB.lastCarbs.mills).toLocaleString(); - var amount = prop.treatmentCOB.lastCarbs.carbs + 'g'; - info.push({label: translate('Last Carbs'), value: amount + ' @ ' + when}); - } + 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}); } sbx.pluginBase.updatePillText(sbx, { From 2001107b31da0a8712326502d6fd24c4f3028888 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Mon, 19 Dec 2016 20:57:08 -0800 Subject: [PATCH 026/303] bump version to 0.9.3-dev-20161219 --- bower.json | 2 +- package.json | 2 +- static/index.html | 8 ++++---- static/report/index.html | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bower.json b/bower.json index b86ff455a1d..98b0f42ed7b 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.9.3-dev-20161212b", + "version": "0.9.3-dev-20161219", "dependencies": { "colorbrewer": "~1.0.0", "jQuery-Storage-API": "~1.7.2", diff --git a/package.json b/package.json index f4862587818..610b49a9837 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Nightscout", - "version": "0.9.3-dev-20161212b", + "version": "0.9.3-dev-20161219", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", diff --git a/static/index.html b/static/index.html index 0e484dc1369..45cc7f79689 100644 --- a/static/index.html +++ b/static/index.html @@ -25,10 +25,10 @@ - - + + - + @@ -590,7 +590,7 @@ - + diff --git a/static/report/index.html b/static/report/index.html index 1aaab8c9c4f..15f73f4f064 100644 --- a/static/report/index.html +++ b/static/report/index.html @@ -23,7 +23,7 @@ - + @@ -116,7 +116,7 @@

Nightscout reporting Authentication status: - + @@ -125,7 +125,7 @@

Nightscout reporting - + From eee2baa12e35a169db60d6671de63de713b0fcf6 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Fri, 23 Dec 2016 00:00:49 -0800 Subject: [PATCH 027/303] fix bug with null value for openaps.iob --- lib/plugins/iob.js | 36 ++++++++++++++++++------------------ tests/iob.test.js | 8 ++++++++ 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/lib/plugins/iob.js b/lib/plugins/iob.js index dde41184fd0..e16f70d4049 100644 --- a/lib/plugins/iob.js +++ b/lib/plugins/iob.js @@ -77,42 +77,42 @@ function init(ctx) { }; iob.fromDeviceStatus = function fromDeviceStatus(devicestatusEntry) { - var iobObj; - if (_.get(devicestatusEntry, 'openaps.iob') !== undefined) { + var iobOpenAPS = _.get(devicestatusEntry, 'openaps.iob'); + var iobLoop = _.get(devicestatusEntry, 'loop.iob'); + var iobPump = _.get(devicestatusEntry, 'pump.iob'); + + if (_.isObject(iobOpenAPS)) { //hacks to support AMA iob array with time fields instead of timestamp fields - iobObj = _.isArray(devicestatusEntry.openaps.iob) ? devicestatusEntry.openaps.iob[0] : devicestatusEntry.openaps.iob; + iobOpenAPS = _.isArray(iobOpenAPS) ? iobOpenAPS[0] : iobOpenAPS; // array could still be empty, handle as null - if (_.isEmpty(iobObj)) { + if (_.isEmpty(iobOpenAPS)) { return {}; } - if (iobObj.time) { - iobObj.timestamp = iobObj.time; + if (iobOpenAPS.time) { + iobOpenAPS.timestamp = iobOpenAPS.time; } return { - iob: iobObj.iob - , basaliob: iobObj.basaliob - , activity: iobObj.activity + iob: iobOpenAPS.iob + , basaliob: iobOpenAPS.basaliob + , activity: iobOpenAPS.activity , source: 'OpenAPS' , device: devicestatusEntry.device - , mills: moment(iobObj.timestamp).valueOf( ) + , mills: moment(iobOpenAPS.timestamp).valueOf( ) }; - } else if (_.get(devicestatusEntry, 'loop.iob') !== undefined) { - iobObj = devicestatusEntry.loop.iob; + } else if (_.isObject(iobLoop)) { return { - iob: iobObj.iob + iob: iobLoop.iob , source: 'Loop' , device: devicestatusEntry.device - , mills: moment(iobObj.timestamp).valueOf( ) + , mills: moment(iobLoop.timestamp).valueOf( ) }; - } else if (_.get(devicestatusEntry, 'pump.iob') !== undefined) { - iobObj = devicestatusEntry.pump.iob.iob; - iobObj = iobObj !== undefined ? iobObj : devicestatusEntry.pump.iob.bolusiob; + } else if (_.isObject(iobPump)) { return { - iob: iobObj + iob: iobPump.iob || iobPump.bolusiob , source: devicestatusEntry.connect !== undefined ? 'MM Connect' : undefined , device: devicestatusEntry.device , mills: devicestatusEntry.mills diff --git a/tests/iob.test.js b/tests/iob.test.js index 39968f25f4d..e9ec18664b0 100644 --- a/tests/iob.test.js +++ b/tests/iob.test.js @@ -191,6 +191,14 @@ describe('IOB', function() { }); }); + it('should not blow up with null IOB data from openaps', function () { + var devicestatus = [_.merge(OPENAPS_DEVICESTATUS, { mills: time - 1, openaps: {iob: null } })]; + iob.calcTotal(treatments, devicestatus, profile, time).should.containEql({ + source: 'Care Portal', + display: '3.00' + }); + }); + it('should return IOB data from openaps post AMA (an array)', function () { var devicestatus = [_.merge(OPENAPS_DEVICESTATUS, { mills: time - 1, openaps: {iob: [{ iob: 0.047, From 1e81aadfedac0365d80a51cd8bfde744d806922d Mon Sep 17 00:00:00 2001 From: tynbendad Date: Sat, 24 Dec 2016 11:11:09 -0700 Subject: [PATCH 028/303] add bgclock.html (#2367) * identify branch in my version - do not merge * revert my local change * Create bgclock.html * Update bgclock.html * Update bgclock.html --- static/bgclock.html | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 static/bgclock.html diff --git a/static/bgclock.html b/static/bgclock.html new file mode 100644 index 00000000000..37b06e0bc4a --- /dev/null +++ b/static/bgclock.html @@ -0,0 +1,81 @@ + + + + + Nightscout BG NOW + + + + + +
+

+

+
+ + + + + + + From 192c4d05331499b5bc9d8cd9ba46377b0429952b Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sat, 24 Dec 2016 10:34:34 -0800 Subject: [PATCH 029/303] stop using uniq for SGVs since we use buckets (#2370) * stop using uniq for SGVs since we use buckets also enables more detailed monitoring when there is data from multiple devices with the same mills * clean up * bump version to 0.9.3-dev-20161224 --- bower.json | 2 +- lib/data/dataloader.js | 5 ++++- package.json | 2 +- static/index.html | 8 ++++---- static/report/index.html | 6 +++--- tests/openaps-storage.test.js | 2 -- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/bower.json b/bower.json index 98b0f42ed7b..17b4ad4b386 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "0.9.3-dev-20161219", + "version": "0.9.3-dev-20161224", "dependencies": { "colorbrewer": "~1.0.0", "jQuery-Storage-API": "~1.7.2", diff --git a/lib/data/dataloader.js b/lib/data/dataloader.js index dd48d41395a..09da5b16ef1 100644 --- a/lib/data/dataloader.js +++ b/lib/data/dataloader.js @@ -111,8 +111,11 @@ function loadEntries (ddata, ctx, callback) { } } }); + + //stop using uniq for SGVs since we use buckets, also enables more detailed monitoring + ddata.sgvs = sgvs; + ddata.mbgs = uniq(mbgs); - ddata.sgvs = uniq(sgvs); ddata.cals = uniq(cals); } callback(); diff --git a/package.json b/package.json index 610b49a9837..0273035b699 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Nightscout", - "version": "0.9.3-dev-20161219", + "version": "0.9.3-dev-20161224", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", diff --git a/static/index.html b/static/index.html index 45cc7f79689..c3b659f2372 100644 --- a/static/index.html +++ b/static/index.html @@ -25,10 +25,10 @@ - - + + - + @@ -590,7 +590,7 @@ - + diff --git a/static/report/index.html b/static/report/index.html index 15f73f4f064..ce1f3209b69 100644 --- a/static/report/index.html +++ b/static/report/index.html @@ -23,7 +23,7 @@ - + @@ -116,7 +116,7 @@

Nightscout reporting Authentication status: - + @@ -125,7 +125,7 @@

Nightscout reporting - + diff --git a/tests/openaps-storage.test.js b/tests/openaps-storage.test.js index d40a034b836..48c2eb7764d 100644 --- a/tests/openaps-storage.test.js +++ b/tests/openaps-storage.test.js @@ -65,8 +65,6 @@ describe('openaps storage', function () { should.not.exist(err); should.exist(results); - console.info('>>>devicestatus results', results); - results.length.should.equal(1); results[0].openaps.enacted.eventualBG.should.equal(82); From 2e9ccf359a870a2559dd210dccac8a6d99a9e675 Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sat, 31 Dec 2016 11:33:07 -0700 Subject: [PATCH 030/303] load and wire settings form after utils and sbx are created --- lib/client/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client/index.js b/lib/client/index.js index 841dedd7e22..5792daa9b2e 100644 --- a/lib/client/index.js +++ b/lib/client/index.js @@ -132,9 +132,6 @@ client.load = function load(serverSettings, callback) { , language: language }).registerClientDefaults(); - //After plugins are initialized with browser settings; - browserSettings.loadAndWireForm(); - client.rawbg = client.plugins('rawbg'); client.delta = client.plugins('delta'); client.timeago = client.plugins('timeago'); @@ -156,6 +153,9 @@ client.load = function load(serverSettings, callback) { client.sbx = sandbox.clientInit(client.ctx, client.now); client.renderer = require('./renderer')(client, d3, $); + //After plugins are initialized with browser settings; + browserSettings.loadAndWireForm(); + if (serverSettings && serverSettings.authorized) { client.authorized = serverSettings.authorized; client.authorized.lat = Date.now(); From dc857cee863de9b237b0ac7faed75a26a52bff1e Mon Sep 17 00:00:00 2001 From: Jason Calabrese Date: Sat, 31 Dec 2016 11:33:41 -0700 Subject: [PATCH 031/303] avoid since it doesn't work on old versions of mongo or in openaps offline mode --- lib/data/dataloader.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/data/dataloader.js b/lib/data/dataloader.js index 09da5b16ef1..7d6bc1670f0 100644 --- a/lib/data/dataloader.js +++ b/lib/data/dataloader.js @@ -176,9 +176,7 @@ function loadProfileSwitchTreatments (ddata, ctx, callback) { var tq = { find: { - eventType: { - $eq: 'Profile Switch' - } + eventType: 'Profile Switch' , created_at: dateRange } , sort: {created_at: -1} From 2e84a5d6affb4f12375be279066cabbe1bab4f3b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 1 Jan 2017 11:00:21 +0100 Subject: [PATCH 032/303] Update azuredeploy.json by iob, food --- azuredeploy.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azuredeploy.json b/azuredeploy.json index 4e43137b850..4a0b2003558 100644 --- a/azuredeploy.json +++ b/azuredeploy.json @@ -173,7 +173,7 @@ }, "enable": { "type": "string", - "defaultValue": "basal bwp cage careportal cob rawbg sage iage treatmentnotify boluscalc profile", + "defaultValue": "basal bwp cage careportal iob cob rawbg sage iage treatmentnotify boluscalc profile food", }, "night_mode": { "type": "string", From ef71db0f1e8d8c4e620d5251a98844a95edc575d Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 1 Jan 2017 11:11:55 +0100 Subject: [PATCH 033/303] add AUTH_DEFAULT_ROLES to azuredeply.jon --- azuredeploy.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/azuredeploy.json b/azuredeploy.json index 4a0b2003558..31f9b84c9a6 100644 --- a/azuredeploy.json +++ b/azuredeploy.json @@ -211,6 +211,10 @@ "off" ], "defaultValue": "off", + }, + "auth_default_roles": { + "type": "string", + "defaultValue": "readable devicestatus-upload", } }, "resources": [{ @@ -304,6 +308,9 @@ }, { "name": "PROFILE_MULTIPLE", "value": "[parameters('profile_multiple')]" + }, { + "name": "AUTH_DEFAULT_ROLES", + "value": "[parameters('auth_default_roles')]" } ] } From 59e76708ef4dc0111f8e04d74bff377734cb8dc7 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 1 Jan 2017 11:16:52 +0100 Subject: [PATCH 034/303] fix duplicate in language.js --- lib/language.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/language.js b/lib/language.js index fee8a33ede2..68a9d088513 100644 --- a/lib/language.js +++ b/lib/language.js @@ -23,7 +23,6 @@ function init() { , { code: 'it', language: 'Italiano' } , { code: 'nl', language: 'Nederlands' } , { code: 'nb', language: 'Norsk (Bokmål)' } - , { code: 'nl', language: 'Nederlands' } , { code: 'pl', language: 'Polski' } , { code: 'pt', language: 'Português (Brasil)' } , { code: 'ro', language: 'Română' } From 012ba198d18659d754b44ef44b2ccb209050bf97 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 16:34:58 +0200 Subject: [PATCH 035/303] If-Modified-Since header support for the /entries and /treatments API --- lib/api/entries/index.js | 23 ++++++++++++++++++++--- lib/api/treatments/index.js | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/api/entries/index.js b/lib/api/entries/index.js index cfd43b2d112..9236d6559eb 100644 --- a/lib/api/entries/index.js +++ b/lib/api/entries/index.js @@ -71,6 +71,23 @@ function configure (app, wares, ctx) { return es.map(sync); } + function ifModifiedSince (req, res, next) { + + var lastEntryDate = new Date(_.last(res.entries).dateString); + res.setHeader('Last-Modified', lastEntryDate.toUTCString()); + + var ifModifiedSince = req.get('If-Modified-Since'); + + if (!ifModifiedSince) { return next(); } + + if (lastEntryDate <= new Date(ifModifiedSince)) { + res.status(304).send({status:304, message: 'Not modified', type:'internal'}); + return; + } + + return next(); + } + /** * @method format_entries * A final middleware to send payloads assembled by previous middlewares @@ -248,7 +265,7 @@ function configure (app, wares, ctx) { res.entries_err = err; return next( ); }); - }, format_entries); + }, ifModifiedSince, format_entries); /** * @module get#/entries/:spec @@ -280,7 +297,7 @@ function configure (app, wares, ctx) { prepReqModel(req, req.params.model); query_models(req, res, next); } - }, format_entries); + }, ifModifiedSince, format_entries); /** @@ -292,7 +309,7 @@ function configure (app, wares, ctx) { * `find[date]`. * */ - api.get('/entries', query_models, format_entries); + api.get('/entries', query_models, [ifModifiedSince, format_entries]); /** * @function echo_query diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index dc3d6337af1..960c4901208 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -22,9 +22,23 @@ function configure (app, wares, ctx) { // List treatments available api.get('/treatments', function(req, res) { + var ifModifiedSince = req.get('If-Modified-Since'); ctx.treatments.list(req.query, function (err, results) { - _.forEach(results, function clean(t) { t.carbs = Number(t.carbs); t.insulin = Number(t.insulin); }); - return res.json(results); + var d1 = null; + _.forEach(results, function clean(t) { + t.carbs = Number(t.carbs); + t.insulin = Number(t.insulin); + var d2 = new Date(t.timestamp); + if (d2 > d1) { d1 = d2; } + }); + res.setHeader('Last-Modified', d1.toUTCString()); + + if (ifModifiedSince && d1 <= new Date(ifModifiedSince)) { + res.status(304).send({status:304, message: 'Not modified', type:'internal'}); + return; + } else { + return res.json(results); + } }); }); @@ -32,6 +46,18 @@ function configure (app, wares, ctx) { function post_response(req, res) { var treatment = req.body; + + if (_.isNil(t.timestamp) || _.isNil(t.eventType)) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Event type or timestamp missing', err); + }; + + var dupeFound = false; + + _.foreach(ctx.treatments, function findDupe(t) { + if (t.timestamp == treatment.timestamp && t.eventType = + + }); + ctx.treatments.create(treatment, function (err, created) { if (err) { console.log('Error adding treatment', err); @@ -42,7 +68,9 @@ function configure (app, wares, ctx) { } }); } + api.post('/treatments/', wares.bodyParser({limit: 1048576 * 50 }), ctx.authorization.isPermitted('api:treatments:create'), post_response); + api.delete('/treatments/:_id', ctx.authorization.isPermitted('api:treatments:delete'), function(req, res) { ctx.treatments.remove(req.params._id, function ( ) { res.json({ }); From 14fa83c017ce07114ddf68d906fa31c39cda216c Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 18:08:05 +0200 Subject: [PATCH 036/303] Dedupe treatments against in-memory objects on upload --- lib/api/treatments/index.js | 226 +++++++++++++++++++++--------------- 1 file changed, 135 insertions(+), 91 deletions(-) diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index 960c4901208..2a6c16dac59 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -3,102 +3,146 @@ var _ = require('lodash'); var consts = require('../../constants'); -function configure (app, wares, ctx) { - var express = require('express'), - api = express.Router( ); - - api.use(wares.compression( )); - api.use(wares.bodyParser({limit: 1048576 * 50})); - // text body types get handled as raw buffer stream - api.use(wares.bodyParser.raw({limit: 1048576 })); - // json body types get handled as parsed json - api.use(wares.bodyParser.json({limit: 1048576 })); - // also support url-encoded content-type - api.use(wares.bodyParser.urlencoded({limit: 1048576 , extended: true })); - // invoke common middleware - api.use(wares.sendJSONStatus); - - api.use(ctx.authorization.isPermitted('api:treatments:read')); - - // List treatments available - api.get('/treatments', function(req, res) { - var ifModifiedSince = req.get('If-Modified-Since'); - ctx.treatments.list(req.query, function (err, results) { - var d1 = null; - _.forEach(results, function clean(t) { - t.carbs = Number(t.carbs); - t.insulin = Number(t.insulin); - var d2 = new Date(t.timestamp); - if (d2 > d1) { d1 = d2; } - }); - res.setHeader('Last-Modified', d1.toUTCString()); - - if (ifModifiedSince && d1 <= new Date(ifModifiedSince)) { - res.status(304).send({status:304, message: 'Not modified', type:'internal'}); - return; - } else { - return res.json(results); - } - }); - }); - - function config_authed (app, api, wares, ctx) { - - function post_response(req, res) { - var treatment = req.body; - - if (_.isNil(t.timestamp) || _.isNil(t.eventType)) { - res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Event type or timestamp missing', err); - }; - - var dupeFound = false; - - _.foreach(ctx.treatments, function findDupe(t) { - if (t.timestamp == treatment.timestamp && t.eventType = - +function configure(app, wares, ctx) { + var express = require('express') + , api = express.Router(); + + api.use(wares.compression()); + api.use(wares.bodyParser({ + limit: 1048576 * 50 + })); + // text body types get handled as raw buffer stream + api.use(wares.bodyParser.raw({ + limit: 1048576 + })); + // json body types get handled as parsed json + api.use(wares.bodyParser.json({ + limit: 1048576 + })); + // also support url-encoded content-type + api.use(wares.bodyParser.urlencoded({ + limit: 1048576 + , extended: true + })); + // invoke common middleware + api.use(wares.sendJSONStatus); + + api.use(ctx.authorization.isPermitted('api:treatments:read')); + + // List treatments available + api.get('/treatments', function(req, res) { + var ifModifiedSince = req.get('If-Modified-Since'); + ctx.treatments.list(req.query, function(err, results) { + var d1 = null; + _.forEach(results, function clean(t) { + t.carbs = Number(t.carbs); + t.insulin = Number(t.insulin); + var d2 = new Date(t.timestamp); + if (d2 > d1) { + d1 = d2; + } + }); + res.setHeader('Last-Modified', d1.toUTCString()); + + if (ifModifiedSince && d1 <= new Date(ifModifiedSince)) { + res.status(304).send({ + status: 304 + , message: 'Not modified' + , type: 'internal' + }); + return; + } else { + return res.json(results); + } }); - - ctx.treatments.create(treatment, function (err, created) { - if (err) { - console.log('Error adding treatment', err); - res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); - } else { - console.log('Treatment created'); - res.json(created); - } - }); - } - - api.post('/treatments/', wares.bodyParser({limit: 1048576 * 50 }), ctx.authorization.isPermitted('api:treatments:create'), post_response); - - api.delete('/treatments/:_id', ctx.authorization.isPermitted('api:treatments:delete'), function(req, res) { - ctx.treatments.remove(req.params._id, function ( ) { - res.json({ }); - }); }); - // update record - api.put('/treatments/', ctx.authorization.isPermitted('api:treatments:update'), function(req, res) { - var data = req.body; - ctx.treatments.save(data, function (err, created) { - if (err) { - res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); - console.log('Error saving treatment'); - console.log(err); - } else { - res.json(created); - console.log('Treatment saved', data); + function config_authed(app, api, wares, ctx) { + + function post_response(req, res) { + var treatments = req.body; + + if (!_.isArray(treatments)) { + treatments = [treatments]; + }; + + var insertTreatments = []; + + var inMemoryTreatments = _.concat(ctx.ddata.treatments + , ctx.ddata.tempTargetTreatments + , ctx.ddata.tempbasalTreatments + , ctx.ddata.profileTreatments + , ctx.ddata.insulinchangeTreatments + , ctx.ddata.sensorTreatments + , ctx.ddata.sitechangeTreatments); + + _.forEach(treatments, function checkForDupes(treatment) { + + var dupeFound = false; + + if (_.isNil(treatment.timestamp) ||  _.isNil(treatment.eventType)) { + console.log(treatment); + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Event type or timestamp missing from a record'); + } + + _.forEach(inMemoryTreatments, function findDupe(t) { + if (t.timestamp == treatment.timestamp && t.eventType == treatment.eventType) { + dupeFound = true; + return false; + } + }); + + if (!dupeFound) { + insertTreatments.push(treatment); + } + }); + + if (insertTreatments.length == 0) { + return res.sendJSONStatus(res, 409, '409 Conflict - Uploaded Record(s) Already Exist(s)'); + } + + ctx.treatments.create(insertTreatments, function(err, created) { + if (err) { + console.log('Error adding treatment', err); + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + } else { + console.log('Treatment created'); + res.json(created); + } + }); } - }); - }); - } - if (app.enabled('api') && app.enabled('careportal')) { - config_authed(app, api, wares, ctx); - } + api.post('/treatments/', wares.bodyParser({ + limit: 1048576 * 50 + }), ctx.authorization.isPermitted('api:treatments:create'), post_response); - return api; -} + api.delete('/treatments/:_id', ctx.authorization.isPermitted('api:treatments:delete'), function(req, res) { + ctx.treatments.remove(req.params._id, function() { + res.json({}); + }); + }); -module.exports = configure; + // update record + api.put('/treatments/', ctx.authorization.isPermitted('api:treatments:update'), function(req, res) { + var data = req.body; + ctx.treatments.save(data, function(err, created) { + if (err) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + console.log('Error saving treatment'); + console.log(err); + } else { + res.json(created); + console.log('Treatment saved', data); + } + }); + }); + } + + if (app.enabled('api') && app.enabled('careportal')) { + config_authed(app, api, wares, ctx); + } + + return api; +} +module.exports = configure; \ No newline at end of file From 2afa166a9318385864b659f112fbf8640a2a3bd9 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 20:01:46 +0200 Subject: [PATCH 037/303] Oops, already using upsets to dedupe further down the line --- lib/api/treatments/index.js | 31 ++++--------------------------- 1 file changed, 4 insertions(+), 27 deletions(-) diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index 2a6c16dac59..1e14b35d168 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -67,38 +67,15 @@ function configure(app, wares, ctx) { }; var insertTreatments = []; - - var inMemoryTreatments = _.concat(ctx.ddata.treatments - , ctx.ddata.tempTargetTreatments - , ctx.ddata.tempbasalTreatments - , ctx.ddata.profileTreatments - , ctx.ddata.insulinchangeTreatments - , ctx.ddata.sensorTreatments - , ctx.ddata.sitechangeTreatments); - - _.forEach(treatments, function checkForDupes(treatment) { - - var dupeFound = false; - - if (_.isNil(treatment.timestamp) ||  _.isNil(treatment.eventType)) { - console.log(treatment); - res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Event type or timestamp missing from a record'); - } - - _.forEach(inMemoryTreatments, function findDupe(t) { - if (t.timestamp == treatment.timestamp && t.eventType == treatment.eventType) { - dupeFound = true; - return false; - } - }); - - if (!dupeFound) { + + _.forEach(treatments, function checkRequireFields(treatment) { + if (!_.isNil(treatment.timestamp) && !_.isNil(treatment.eventType)) { insertTreatments.push(treatment); } }); if (insertTreatments.length == 0) { - return res.sendJSONStatus(res, 409, '409 Conflict - Uploaded Record(s) Already Exist(s)'); + return res.sendJSONStatus(res, 409, '409 Conflict - No valid treatments found'); } ctx.treatments.create(insertTreatments, function(err, created) { From e963f28b44f79bea288d2c09013c72c378ff6d02 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 22:48:47 +0200 Subject: [PATCH 038/303] Add null check to treatment loads that don't find anything --- lib/api/treatments/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index 1e14b35d168..5917555e19f 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -34,15 +34,18 @@ function configure(app, wares, ctx) { var ifModifiedSince = req.get('If-Modified-Since'); ctx.treatments.list(req.query, function(err, results) { var d1 = null; + _.forEach(results, function clean(t) { t.carbs = Number(t.carbs); t.insulin = Number(t.insulin); var d2 = new Date(t.timestamp); + if (d2 > d1) { d1 = d2; } }); - res.setHeader('Last-Modified', d1.toUTCString()); + + if (!_.isNil(d1)) res.setHeader('Last-Modified', d1.toUTCString()); if (ifModifiedSince && d1 <= new Date(ifModifiedSince)) { res.status(304).send({ From 44863f9806ef9dfe1f074ae9ee0275d84b20cfa0 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 22:51:35 +0200 Subject: [PATCH 039/303] One more null check --- lib/api/treatments/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index 5917555e19f..c9099879cbb 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -38,9 +38,10 @@ function configure(app, wares, ctx) { _.forEach(results, function clean(t) { t.carbs = Number(t.carbs); t.insulin = Number(t.insulin); + var d2 = new Date(t.timestamp); - if (d2 > d1) { + if (d1 == null || d2 > d1) { d1 = d2; } }); From 437965d67be229370155047f0d3337abceadaee8 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 1 Jan 2017 23:46:39 +0200 Subject: [PATCH 040/303] Now comparing to in-memory data --- lib/api/entries/index.js | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/lib/api/entries/index.js b/lib/api/entries/index.js index 9236d6559eb..94245c762a5 100644 --- a/lib/api/entries/index.js +++ b/lib/api/entries/index.js @@ -71,6 +71,28 @@ function configure (app, wares, ctx) { return es.map(sync); } + // check for last modified from in-memory data + + function ifModifiedSinceCTX (req, res, next) { + + var lastEntryDate = new Date(_.last(ctx.ddata.sgvs).mills); + + res.setHeader('Last-Modified', lastEntryDate.toUTCString()); + + var ifModifiedSince = req.get('If-Modified-Since'); + + if (!ifModifiedSince) { return next(); } + + if (lastEntryDate <= new Date(ifModifiedSince)) { + res.status(304).send({status:304, message: 'Not modified', type:'internal'}); + return; + } + + return next(); + } + + // check for last modified from query results + function ifModifiedSince (req, res, next) { var lastEntryDate = new Date(_.last(res.entries).dateString); @@ -257,7 +279,7 @@ function configure (app, wares, ctx) { * Get last entry. * @response /definitions/Entries */ - api.get('/entries/current', function(req, res, next) { + api.get('/entries/current', ifModifiedSinceCTX, function(req, res, next) { //assume sgv req.params.model = 'sgv'; entries.list({count: 1}, function(err, records) { @@ -265,7 +287,7 @@ function configure (app, wares, ctx) { res.entries_err = err; return next( ); }); - }, ifModifiedSince, format_entries); + }, format_entries); /** * @module get#/entries/:spec @@ -278,7 +300,7 @@ function configure (app, wares, ctx) { * usual query logic is performed biased towards that model type. * Useful for filtering by type. */ - api.get('/entries/:spec', function(req, res, next) { + api.get('/entries/:spec', ifModifiedSinceCTX, function(req, res, next) { if (isId(req.params.spec)) { entries.getEntry(req.params.spec, function(err, entry) { if (err) { return next(err); } @@ -297,7 +319,7 @@ function configure (app, wares, ctx) { prepReqModel(req, req.params.model); query_models(req, res, next); } - }, ifModifiedSince, format_entries); + }, format_entries); /** @@ -309,7 +331,7 @@ function configure (app, wares, ctx) { * `find[date]`. * */ - api.get('/entries', query_models, [ifModifiedSince, format_entries]); + api.get('/entries', ifModifiedSinceCTX, query_models, format_entries); /** * @function echo_query From 6018df9c265a532111b7d433c8c2b13101518f5c Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Mon, 2 Jan 2017 00:12:28 +0200 Subject: [PATCH 041/303] Fixing tests --- lib/api/entries/index.js | 9 ++++++--- lib/api/treatments/index.js | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/api/entries/index.js b/lib/api/entries/index.js index 94245c762a5..ca857818f90 100644 --- a/lib/api/entries/index.js +++ b/lib/api/entries/index.js @@ -75,12 +75,15 @@ function configure (app, wares, ctx) { function ifModifiedSinceCTX (req, res, next) { - var lastEntryDate = new Date(_.last(ctx.ddata.sgvs).mills); + var lastEntry = _.last(ctx.ddata.sgvs); + var lastEntryDate = null; - res.setHeader('Last-Modified', lastEntryDate.toUTCString()); + if (!_.isNil(lastEntry)) { + lastEntryDate = new Date(_.last(ctx.ddata.sgvs).mills); + res.setHeader('Last-Modified', lastEntryDate.toUTCString()); + } var ifModifiedSince = req.get('If-Modified-Since'); - if (!ifModifiedSince) { return next(); } if (lastEntryDate <= new Date(ifModifiedSince)) { diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index c9099879cbb..1de94be09c0 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -79,7 +79,8 @@ function configure(app, wares, ctx) { }); if (insertTreatments.length == 0) { - return res.sendJSONStatus(res, 409, '409 Conflict - No valid treatments found'); + return res.sendJSONStatus(res, 200, '200 OK - No valid treatments found, skipping insert'); + //return res.sendJSONStatus(res, 409, '409 Conflict - No valid treatments found'); } ctx.treatments.create(insertTreatments, function(err, created) { From 5cf195d1258cab92fddad4482bf1b1cc14d3afe7 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Wed, 4 Jan 2017 22:38:58 +0200 Subject: [PATCH 042/303] Removing the validation due to client fragmentation in terms of how this works --- lib/api/treatments/index.js | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/api/treatments/index.js b/lib/api/treatments/index.js index 1de94be09c0..1acbd1a3462 100644 --- a/lib/api/treatments/index.js +++ b/lib/api/treatments/index.js @@ -70,20 +70,7 @@ function configure(app, wares, ctx) { treatments = [treatments]; }; - var insertTreatments = []; - - _.forEach(treatments, function checkRequireFields(treatment) { - if (!_.isNil(treatment.timestamp) && !_.isNil(treatment.eventType)) { - insertTreatments.push(treatment); - } - }); - - if (insertTreatments.length == 0) { - return res.sendJSONStatus(res, 200, '200 OK - No valid treatments found, skipping insert'); - //return res.sendJSONStatus(res, 409, '409 Conflict - No valid treatments found'); - } - - ctx.treatments.create(insertTreatments, function(err, created) { + ctx.treatments.create(treatments, function(err, created) { if (err) { console.log('Error adding treatment', err); res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); From 5858ccd868c1e3c3f59994f0870155ad2ee24138 Mon Sep 17 00:00:00 2001 From: Sulka Haro Date: Sun, 8 Jan 2017 00:14:19 +0200 Subject: [PATCH 043/303] Added ability to issue w WARNING on pump suspend event --- README.md | 1 + lib/plugins/pump.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/README.md b/README.md index 1ffb9af6247..2515d08eb41 100644 --- a/README.md +++ b/README.md @@ -375,6 +375,7 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm Generic Pump Monitoring for OpenAPS, MiniMed Connect, RileyLink, t:slim, with more on the way * Requires `DEVICESTATUS_ADVANCED="true"` to be set * `PUMP_ENABLE_ALERTS` (`false`) - Set to `true` to enable notifications for Pump battery and reservoir. + * `PUMP_WARNONSUSPEND` (`false`) - Set to `true` to get an alarm when the pump is suspended. * `PUMP_FIELDS` (`reservoir battery`) - The fields to display by default. Any of the following fields: `reservoir`, `battery`, `clock`, `status`, and `device` * `PUMP_RETRO_FIELDS` (`reservoir battery clock`) - The fields to display in retro mode. Any of the above fields. * `PUMP_WARN_CLOCK` (`30`) - The number of minutes ago that needs to be exceed before an alert is triggered. diff --git a/lib/plugins/pump.js b/lib/plugins/pump.js index bf278a575b8..94fceea78d0 100644 --- a/lib/plugins/pump.js +++ b/lib/plugins/pump.js @@ -45,6 +45,7 @@ function init (ctx) { , urgentBattV: sbx.extendedSettings.urgentBattV || 1.3 , warnBattP: sbx.extendedSettings.warnBattP || 30 , urgentBattP: sbx.extendedSettings.urgentBattP || 20 + , warnOnSuspend: sbx.extendedSettings.warnOnSuspend || false , enableAlerts: sbx.extendedSettings.enableAlerts || false }; }; @@ -249,6 +250,10 @@ function init (ctx) { status = 'bolusing'; } else if (pump.status.suspended) { status = 'suspended'; + if (prefs.warnOnSuspend && pump.status.suspended) { + result.status.level = levels.WARN; + result.status.message = 'Pump Suspended'; + }; } result.status = { value: status, display: status, label: translate('Status') }; } From 1d4a05fc41035812942d045977c257647cca3553 Mon Sep 17 00:00:00 2001 From: fedor apanasenko Date: Tue, 10 Jan 2017 13:18:51 +0300 Subject: [PATCH 044/303] rus lang update --- lib/language.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/language.js b/lib/language.js index 68a9d088513..68ae5d9f47e 100644 --- a/lib/language.js +++ b/lib/language.js @@ -9162,6 +9162,7 @@ function init() { ,'Insulin reservoir age %1 hours' : { cs:'Stáří zásobníku %1 hodin' ,ro: 'Vârsta reservorului de insulină %1 ore' + ,ru: 'Картридж инсулина отработал %1часов' ,bg: 'Резервоарът е на %1 часа' ,sv: 'Insulinreservoarsålder %1 timmar' ,nb: 'Insulinreservoaralder %1 timer' @@ -9174,6 +9175,7 @@ function init() { ,'Changed' : { cs:'Vyměněno' ,ro: 'Schimbat' + ,ru: 'Замена произведена' ,bg: 'Сменен' ,sv: 'Bytt' ,nb: 'Byttet' @@ -9187,6 +9189,7 @@ function init() { ,'IOB' : { cs:'IOB' ,ro: 'IOB' + ,ru: 'Активный Инсулин' ,bg: 'АИ' ,sv: 'IOB' ,nb: 'Aktivt insulin' @@ -9199,6 +9202,7 @@ function init() { ,'Careportal IOB' : { cs:'IOB z ošetření' ,ro: 'IOB în Careportal' + ,ru: 'Активн Инс на портале назначений' ,bg: 'АИ от Кеърпортал' ,sv: 'IOB i Careportal' ,nb: 'Aktivt insulin i Careportal' @@ -9211,6 +9215,7 @@ function init() { ,'Last Bolus' : { cs:'Poslední bolus' ,ro: 'Ultimul bolus' + ,ru: 'Прошлый болюс' ,bg: 'Последен болус' ,sv: 'Senaste Bolus' ,nb: 'Siste Bolus' @@ -9223,6 +9228,7 @@ function init() { ,'Basal IOB' : { cs:'IOB z bazálů' ,ro: 'IOB bazală' + ,ru: 'Активн Базал' ,bg: 'Базален АИ' ,sv: 'Basal IOB' ,nb: 'Basal Aktivt Insulin' @@ -9235,6 +9241,7 @@ function init() { ,'Source' : { cs:'Zdroj' ,ro: 'Sursă' + ,ru: 'Источник' ,bg: 'Източник' ,sv: 'Källa' ,nb: 'Kilde' @@ -9247,6 +9254,7 @@ function init() { ,'Stale data, check rig?' : { cs:'Zastaralá data, zkontrolovat mobil?' ,ro: 'Date învechite, verificați uploaderul!' + ,ru: 'Устаревшие данные, проверьте загрузчик' ,bg: 'Стари данни, провери телефона' ,sv: 'Gammal data, kontrollera rigg?' ,nb: 'Gamle data, sjekk rigg?' @@ -9259,6 +9267,7 @@ function init() { ,'Last received:' : { cs:'Naposledy přijato:' ,ro: 'Ultimile date:' + ,ru: 'Предыдущий полученный' ,bg: 'Последно получени' ,sv: 'Senast mottagen:' ,nb: 'Sist mottatt:' @@ -9271,6 +9280,7 @@ function init() { ,'%1m ago' : { cs:'%1m zpět' ,ro: 'acum %1 minute' + ,ru: 'мин назад' ,bg: 'преди %1 мин.' ,sv: '%1m sedan' ,nb: '%1m siden' @@ -9283,6 +9293,7 @@ function init() { ,'%1h ago' : { cs:'%1h zpět' ,ro: 'acum %1 ore' + ,ru: 'час назад' ,bg: 'преди %1 час' ,sv: '%1h sedan' ,nb: '%1h siden' @@ -9295,6 +9306,7 @@ function init() { ,'%1d ago' : { cs:'%1d zpět' ,ro: 'acum %1 zile' + ,ru: 'дн назад' ,bg: 'преди %1 ден' ,sv: '%1d sedan' ,nb: '%1d siden' @@ -9307,6 +9319,7 @@ function init() { ,'RETRO' : { cs:'RETRO' ,ro: 'VECHI' + ,ru: 'РЕТРО' ,bg: 'РЕТРО' ,sv: 'RETRO' ,nb: 'GAMMELT' @@ -9319,6 +9332,7 @@ function init() { ,'SAGE' : { cs:'SENZ' ,ro: 'VS' + ,ru: 'Сенсор проработал' ,bg: 'ВС' ,sv: 'Sensor' ,nb: 'Sensoralder' @@ -9331,6 +9345,7 @@ function init() { ,'Sensor change/restart overdue!' : { cs:'Čas na výměnu senzoru vypršel!' ,ro: 'Depășire termen schimbare/restart senzor!' + ,ru: 'Рестарт сенсора просрочен' ,bg: 'Смяната/рестартът на сензора са пресрочени' ,sv: 'Sensor byte/omstart överskriden!' ,nb: 'Sensor bytte/omstart overskredet!' @@ -9343,6 +9358,7 @@ function init() { ,'Time to change/restart sensor' : { cs:'Čas na výměnu senzoru' ,ro: 'Este timpul pentru schimbarea senzorului' + ,ru: 'Время замены/рестарта сенсора' ,bg: 'Време за смяна/рестарт на сензора' ,sv: 'Dags att byta/starta om sensorn' ,nb: 'På tide å bytte/restarte sensoren' @@ -9355,6 +9371,7 @@ function init() { ,'Change/restart sensor soon' : { cs:'Blíží se čas na výměnu senzoru' ,ro: 'Schimbați/restartați senzorul în curând' + ,ru: 'Приближается срок замены/рестарта сенсора' ,bg: 'Смени/рестартирай сензора скоро' ,sv: 'Byt/starta om sensorn snart' ,nb: 'Bytt/restarta sensoren snart' @@ -9368,6 +9385,7 @@ function init() { ,'Sensor age %1 days %2 hours' : { cs:'Stáří senzoru %1 dní %2 hodin' ,ro: 'Senzori vechi de %1 zile și %2 ore' + ,ru: 'Сенсор проработал % дн % час' ,bg: 'Сензорът е на %1 дни %2 часа ' ,sv: 'Sensorålder %1 dagar %2 timmar' ,nb: 'Sensoralder %1 dag %2 timer' @@ -9380,6 +9398,7 @@ function init() { ,'Sensor Insert' : { cs: 'Výměna sensoru' ,ro: 'Inserția senzorului' + ,ru: 'Установка сенсора' ,bg: 'Поставяне на сензора' ,sv: 'Sensor insättning' ,nb: 'Sensor satt inn' @@ -9392,6 +9411,7 @@ function init() { ,'Sensor Start' : { cs: 'Znovuspuštění sensoru' ,ro: 'Pornirea senzorului' + ,ru: 'Запуск сенсора' ,bg: 'Стартиране на сензора' ,sv: 'Sensorstart' ,nb: 'Sensorstart' @@ -9404,6 +9424,7 @@ function init() { ,'days' : { cs: 'dní' ,ro: 'zile' + ,ru: 'дн' ,bg: 'дни' ,sv: 'dagar' ,nb: 'dager' From ae2b4ed6c3f9612c4ca1189f132434670a157d13 Mon Sep 17 00:00:00 2001 From: Chris O Date: Fri, 20 Jan 2017 18:53:06 +0000 Subject: [PATCH 045/303] Add temperature support for upbat plugin --- lib/plugins/upbat.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/plugins/upbat.js b/lib/plugins/upbat.js index d1491f7b6e1..7ac466ff86b 100644 --- a/lib/plugins/upbat.js +++ b/lib/plugins/upbat.js @@ -73,7 +73,8 @@ function init() { var battery = uploaderStatus.battery; var voltage = uploaderStatus.batteryVoltage; var voltageDisplay; - + + console.log("analyze", uploaderStatus); if (voltage) { if (voltage > 1000) { voltage = voltage / 1000; @@ -198,10 +199,18 @@ function init() { info.value += ' (' + device.min.voltageDisplay + ')'; } + if (device.min && device.min.temperature) { + info.value += ' ' + device.min.temperature; + } return info; }); - } else if (prop.min && prop.min.battery && prop.min.voltageDisplay) { - infos = [{label: 'Voltage', value: prop.min.voltageDisplay}]; + } else { + if (prop.min && prop.min.battery && prop.min.voltageDisplay) { + infos = [{label: 'Voltage', value: prop.min.voltageDisplay}]; + } + if (prop.min && prop.min.temperature) { + infos.push({label: 'Temp', value : prop.min.temperature}); + } } sbx.pluginBase.updatePillText(upbat, { From c4a6f941b4989e2aa7ac278a8fd3b0ad56fae8e6 Mon Sep 17 00:00:00 2001 From: Chris O Date: Fri, 20 Jan 2017 18:54:48 +0000 Subject: [PATCH 046/303] Remove debugging console.log --- lib/plugins/upbat.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/plugins/upbat.js b/lib/plugins/upbat.js index 7ac466ff86b..a3ffbe1a9ef 100644 --- a/lib/plugins/upbat.js +++ b/lib/plugins/upbat.js @@ -74,7 +74,6 @@ function init() { var voltage = uploaderStatus.batteryVoltage; var voltageDisplay; - console.log("analyze", uploaderStatus); if (voltage) { if (voltage > 1000) { voltage = voltage / 1000; From 6db4ea2abbc8104e8f94ada0b3afc4e23c3a2dfb Mon Sep 17 00:00:00 2001 From: Chris O Date: Fri, 20 Jan 2017 18:59:10 +0000 Subject: [PATCH 047/303] Fix whitespace --- lib/plugins/upbat.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/plugins/upbat.js b/lib/plugins/upbat.js index a3ffbe1a9ef..eda42a3901f 100644 --- a/lib/plugins/upbat.js +++ b/lib/plugins/upbat.js @@ -73,7 +73,7 @@ function init() { var battery = uploaderStatus.battery; var voltage = uploaderStatus.batteryVoltage; var voltageDisplay; - + if (voltage) { if (voltage > 1000) { voltage = voltage / 1000; @@ -198,18 +198,18 @@ function init() { info.value += ' (' + device.min.voltageDisplay + ')'; } - if (device.min && device.min.temperature) { - info.value += ' ' + device.min.temperature; - } + if (device.min && device.min.temperature) { + info.value += ' ' + device.min.temperature; + } return info; }); } else { - if (prop.min && prop.min.battery && prop.min.voltageDisplay) { - infos = [{label: 'Voltage', value: prop.min.voltageDisplay}]; - } - if (prop.min && prop.min.temperature) { - infos.push({label: 'Temp', value : prop.min.temperature}); - } + if (prop.min && prop.min.battery && prop.min.voltageDisplay) { + infos = [{label: 'Voltage', value: prop.min.voltageDisplay}]; + } + if (prop.min && prop.min.temperature) { + infos.push({label: 'Temp', value : prop.min.temperature}); + } } sbx.pluginBase.updatePillText(upbat, { From 2a52b7167618e2155220431ca7d87893ba04bb4e Mon Sep 17 00:00:00 2001 From: Kevin Oliver Date: Sat, 21 Jan 2017 22:54:16 -0800 Subject: [PATCH 048/303] prefer number inputs with a pattern for a better experience on iOS --- static/index.html | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/static/index.html b/static/index.html index c3b659f2372..0a8d85a86de 100644 --- a/static/index.html +++ b/static/index.html @@ -228,7 +228,7 @@
Glucose Reading - +