Skip to content

Commit

Permalink
Merge pull request #1296 from nightscout/dev
Browse files Browse the repository at this point in the history
0.8.2 (Funnel Cake)
  • Loading branch information
jasoncalabrese committed Nov 1, 2015
2 parents 63283e8 + 806f0c7 commit 24b674e
Show file tree
Hide file tree
Showing 56 changed files with 2,509 additions and 342 deletions.
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,11 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm
* `ALARM_TIMEAGO_URGENT` (`on`) - possible values `on` or `off`
* `ALARM_TIMEAGO_URGENT_MINS` (`30`) - minutes since the last reading to trigger a urgent alarm
* `SHOW_PLUGINS` - enabled plugins that should have their visualizations shown, defaults to all enabled
* `LANGUAGE` (`en`) - language of Nighscout. If not available english is used
* `LANGUAGE` (`en`) - language of Nightscout. If not available english is used
* `SCALE_Y` (`log`) - The type of scaling used for the Y axis of the charts system wide.
* The default `log` (logarithmic) option will let you see more detail towards the lower range, while still showing the full CGM range.
* The `linear` option has equidistant tick marks, the range used is dynamic so that space at the top of chart isn't wasted.
* The `log-dynamic` is similar to the default `log` options, but uses the same dynamic range and the `linear` scale.

### Plugins

Expand Down Expand Up @@ -241,7 +245,8 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm
* `CAGE_WARN` (`48`) - If time since last `Site Change` matches `CAGE_WARN`, user will be alarmed to to change the cannula
* `CAGE_URGENT` (`72`) - If time since last `Site Change` matches `CAGE_URGENT`, user will be issued a persistent warning of overdue change.
* `treatmentnotify` (Treatment Notifications) - Generates notifications when a treatment has been entered and snoozes alarms minutes after a treatment. Default snooze is 10 minutes, and can be set using the `TREATMENTNOTIFY_SNOOZE_MINS` [extended setting](#extended-settings).
* `basal` (Basal Profile) - Adds the Basal pill visualization to display the basal rate for the current time. Also enables the `bwp` plugin to calculate correction temp basal suggestions. Uses the `basal` field from the [treatment profile](#treatment-profile).
* `basal` (Basal Profile) - Adds the Basal pill visualization to display the basal rate for the current time. Also enables the `bwp` plugin to calculate correction temp basal suggestions. Uses the `basal` field from the [treatment profile](#treatment-profile). Also uses the extended setting:
* `BASAL_RENDER` (`none`) - Possible values are `none`, `default`, or `icicle` (inverted)
* `bridge` (Share2Nightscout bridge) - Glucose reading directly from the Share service, uses these extended settings:
* `BRIDGE_USER_NAME` - Your user name for the Share service.
* `BRIDGE_PASSWORD` - Your password for the Share service.
Expand All @@ -250,6 +255,14 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs.htm
* `BRIDGE_FIRST_FETCH_COUNT` (`3`) - Changes max count during the very first update only.
* `BRIDGE_MAX_FAILURES` (`3`) - How many failures before giving up.
* `BRIDGE_MINUTES` (`1400`) - The time window to search for new data per update (default is one day in minutes).
* `mmconnect` (MiniMed Connect bridge) - Transfer real-time MiniMed Connect data from the Medtronic CareLink server into Nightscout ([read more](https://github.com/mddub/minimed-connect-to-nightscout))
* `MMCONNECT_USER_NAME` - Your user name for CareLink Connect.
* `MMCONNECT_PASSWORD` - Your password for CareLink Connect.
* `MMCONNECT_INTERVAL` (`60000` *1 minute*) - Number of milliseconds to wait between requests to the CareLink server.
* `MMCONNECT_MAX_RETRY_DURATION` (`32`) - Maximum number of total seconds to spend retrying failed requests before giving up.
* `MMCONNECT_SGV_LIMIT` (`24`) - Maximum number of recent sensor glucose values to send to Nightscout on each request.
* `MMCONNECT_VERBOSE` - Set this to "true" to log CareLink request information to the console.
* `MMCONNECT_STORE_RAW_DATA` - Set this to "true" to store raw data returned from CareLink as `type: "carelink_raw"` database entries (useful for development).

Also see [Pushover](#pushover) and [IFTTT Maker](#ifttt-maker).

Expand Down
4 changes: 3 additions & 1 deletion app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

var express = require('express');
var compression = require('compression');
var bodyParser = require('body-parser');
function create (env, ctx) {
///////////////////////////////////////////////////
// api and json object variables
Expand All @@ -17,11 +18,12 @@ function create (env, ctx) {
// fallback to standard filter function
return compression.filter(req, res);
}}));
// app.use(bodyParser({limit: 1048576 * 50, extended: true }));

//if (env.api_secret) {
// console.log("API_SECRET", env.api_secret);
//}
app.use('/api/v1', api);
app.use('/api/v1', bodyParser({limit: 1048576 * 50 }), api);


// pebble data
Expand Down
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nightscout",
"version": "0.8.1",
"version": "0.8.2",
"dependencies": {
"jquery": "2.1.0",
"jQuery-Storage-API": "~1.7.2",
Expand Down
1 change: 1 addition & 0 deletions bundle/bundle.source.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
, units: require('../lib/units')()
, plugins: require('../lib/plugins/')().registerClientDefaults()
, report_plugins: require('../lib/report_plugins/')()
, admin_plugins: require('../lib/admin_plugins/')()
};

console.info('Nightscout bundle ready');
Expand Down
70 changes: 70 additions & 0 deletions lib/admin_plugins/cleanstatusdb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
'use strict';

var cleanstatusdb = {
name: 'cleanstatusdb'
, label: 'Clean Mongo status database'
, pluginType: 'admin'
};

function init() {
return cleanstatusdb;
}

module.exports = init;

cleanstatusdb.actions = [
{
name: 'Delete all documents from devicestatus collection'
, description: 'This task removes all documents from devicestatus collection. Useful when uploader battery status is not properly updated.'
, buttonLabel: 'Delete all documents'
, confirmText: 'Delete all documents from devicestatus collection?'
}
];

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', {
success: function (records) {
var recs = (records.length === 500 ? '500+' : records.length);
$status.hide().text(translate('Database contains %1 records',{ params: [recs] })).fadeIn('slow');
},
error: function () {
$status.hide().text(translate('Error loading database')).fadeIn('slow');
}
}).done(function () { if (callback) { callback(); } });
};

cleanstatusdb.actions[0].code = function deleteRecords(client, callback) {
var translate = client.translate;
var $status = $('#admin_' + cleanstatusdb.name + '_0_status');

if (!client.hashauth.isAuthenticated()) {
alert(translate('Your device is not authenticated yet'));
if (callback) {
callback();
}
return;
};

$status.hide().text(translate('Deleting records ...')).fadeIn('slow');
$.ajax({
method: 'DELETE'
, url: '/api/v1/devicestatus/*'
, headers: {
'api-secret': client.hashauth.hash()
}
}).done(function success () {
$status.hide().text(translate('All records removed ...')).fadeIn('slow');
if (callback) {
callback();
}
}).fail(function fail() {
$status.hide().text(translate('Error')).fadeIn('slow');
if (callback) {
callback();
}
});
};
172 changes: 172 additions & 0 deletions lib/admin_plugins/futureitems.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
'use strict';

var futureitems = {
name: 'futureitems'
, label: 'Remove future items from mongo database'
, pluginType: 'admin'
};

function init() {
return futureitems;
}

module.exports = init;

futureitems.actions = [
{
name: 'Find and remove treatments in the future'
, 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.'
, buttonLabel: 'Remove entries in the future'
}
];

futureitems.actions[0].init = function init(client, callback) {
var translate = client.translate;
var $status = $('#admin_' + futureitems.name + '_0_status');

function valueOrEmpty (value) {
return value ? value : '';
}

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)))
);
}

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);
}
};

$status.hide().text(translate('Loading database ...')).fadeIn('slow');
var nowiso = new Date().toISOString();
$.ajax('/api/v1/treatments.json?&find[created_at][$gte]=' + nowiso, {
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');
$('#admin_' + futureitems.name + '_0_html').append(table);
showTreatments(records, table);
futureitems.actions[0].confirmText = translate('Remove %1 selected records?', { params: [records.length] });
},
error: function () {
$status.hide().text(translate('Error loading database')).fadeIn('slow');
futureitems.treatmentrecords = [];
}
}).done(function () { if (callback) { callback(); } });
};

futureitems.actions[0].code = function deleteRecords(client, callback) {
var translate = client.translate;
var $status = $('#admin_' + futureitems.name + '_0_status');

if (!client.hashauth.isAuthenticated()) {
alert(translate('Your device is not authenticated yet'));
if (callback) {
callback();
}
return;
};

function deleteRecordById (_id) {
$.ajax({
method: 'DELETE'
, url: '/api/v1/treatments/' + _id
, headers: {
'api-secret': client.hashauth.hash()
}
}).done(function success () {
$status.text(translate('Record %1 removed ...', { params: [_id] }));
}).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.treatmentrecords.length; i++) {
deleteRecordById(futureitems.treatmentrecords[i]._id);
}
$('#admin_' + futureitems.name + '_0_html').html('');

if (callback) {
callback();
}
};

futureitems.actions[1].init = function init(client, callback) {
var translate = client.translate;
var $status = $('#admin_' + futureitems.name + '_1_status');

$status.hide().text(translate('Loading database ...')).fadeIn('slow');
var now = new Date().getTime();
$.ajax('/api/v1/entries.json?&find[date][$gte]=' + now, {
success: function (records) {
futureitems.entriesrecords = records;
$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 () {
$status.hide().text(translate('Error loading database')).fadeIn('slow');
futureitems.entriesrecords = [];
}
}).done(function () { if (callback) { callback(); } });
};

futureitems.actions[1].code = function deleteRecords(client, callback) {
var translate = client.translate;
var $status = $('#admin_' + futureitems.name + '_1_status');

if (!client.hashauth.isAuthenticated()) {
alert(translate('Your device is not authenticated yet'));
if (callback) {
callback();
}
return;
};

function deteleteRecordById (_id) {
$.ajax({
method: 'DELETE'
, url: '/api/v1/entries/' + _id
, headers: {
'api-secret': client.hashauth.hash()
}
}).done(function success () {
$status.text(translate('Record %1 removed ...', { params: [_id] }));
}).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);
}

if (callback) {
callback();
}
};
Loading

0 comments on commit 24b674e

Please sign in to comment.