diff --git a/README.md b/README.md
index bde990c..7b2f12d 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@ A Pebble watchface to view data from a continuous glucose monitor in graph forma

-To install, enable Developer Mode in the Pebble app on your phone, then open [this pbw file][pbw] in the Pebble app.
+To install, enable Developer Mode in the Pebble app on your phone, then download and open this pbw file https://github.com/woernsn/urchin-cgm/releases/download/v0.2.0/urchin-cgm.pbw in the Pebble app. For iPhone: Locate the downloaded .pwb file, and use the iPhone Share menu and pick the Pebble app to install Urchin.
Urchin CGM is an **U**nopinionated, **R**idiculously **C**onfigurable **H**uman **IN**nterface to your CGM. It's not released yet / in beta / a work-in-progress.
@@ -12,7 +12,7 @@ Urchin CGM is an **U**nopinionated, **R**idiculously **C**onfigurable **H**uman
* Open [the latest release][pbw] in your phone's browser, then open the file with the Pebble app to install.
* In the Pebble app on your phone, open the "Settings" screen for Urchin.
-* To view data from a [Nightscout][cgm-remote-monitor] site, enter your site's URL.
+* To view data from a [Nightscout][cgm-remote-monitor] site, enter your site's URL and token if authentication is enabled (see [Authentication Roles](http://www.nightscout.info/wiki/welcome/website-features/0-9-features/authentication-roles) for details).
* To view data from [Dexcom Share][dexcom-share], enter your username and password. (These credentials never leave your phone except to authorize with Dexcom's servers.)
* Optionally, personalize your watchface using the settings described below.
diff --git a/config/index.html b/config/index.html
index 8b2b39c..b8e2955 100644
--- a/config/index.html
+++ b/config/index.html
@@ -50,6 +50,17 @@
diff --git a/config/js/config.js b/config/js/config.js
index f91942e..f4f8ccc 100644
--- a/config/js/config.js
+++ b/config/js/config.js
@@ -627,6 +627,7 @@
function populateValues(current) {
$('[name=dataSource][value=' + current['dataSource'] + ']').addClass('active');
$('#ns-url').val(current['nightscout_url'] || '');
+ $('#ns-token').val(current['nightscout_token'] || '');
$('[name=dexcomUsername]').val(current['dexcomUsername'] || '');
$('[name=dexcomPassword]').val(current['dexcomPassword'] || '');
@@ -690,6 +691,7 @@
mmol: mmol,
dataSource: $('[name=dataSource].active').attr('value'),
nightscout_url: $('#ns-url').val().replace(/\/$/, ''),
+ nightscout_token: $('#ns-token').val(),
dexcomUsername: $('[name=dexcomUsername]').val(),
dexcomPassword: $('[name=dexcomPassword]').val(),
hGridlines: tryParseInt($('#hGridlines').val()),
@@ -752,6 +754,7 @@
// redact PII
var current = JSON.parse(JSON.stringify(phoneConfig));
delete current['nightscout_url'];
+ delete current['nightscout_token'];
delete current['dexcomUsername'];
delete current['dexcomPassword'];
delete current['statusText'];
diff --git a/package.json b/package.json
index 30798cf..27d7817 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "urchin-cgm",
"author": "Mark Wilson",
- "version": "0.1.0",
+ "version": "0.2.0",
"keywords": ["pebble-app"],
"private": true,
"devDependencies": {
@@ -41,7 +41,7 @@
"prediction2": 11,
"prediction3": 12,
"predictionRecency": 13,
-
+
"mmol": 1,
"topOfGraph": 2,
"topOfRange": 3,
diff --git a/src/js/app.js b/src/js/app.js
index 8167b16..663760f 100644
--- a/src/js/app.js
+++ b/src/js/app.js
@@ -278,6 +278,7 @@ function app(Pebble, c) {
var clearCache = (
config.dataSource !== oldConfig.dataSource ||
config.nightscout_url !== oldConfig.nightscout_url ||
+ config.nightscout_token !== oldConfig.nightscout_token ||
config.dexcomUsername !== oldConfig.dexcomUsername ||
config.dexcomPassword !== oldConfig.dexcomPassword ||
maxSGVs > computeMaxSGVs(oldConfig) ||
diff --git a/src/js/constants.json b/src/js/constants.json
index 567c152..7330be0 100644
--- a/src/js/constants.json
+++ b/src/js/constants.json
@@ -10,6 +10,7 @@
"DEFAULT_CONFIG" : {
"dataSource": "nightscout",
"nightscout_url" : "",
+ "nightscout_token" : "",
"dexcomUsername": "",
"dexcomPassword": "",
"mmol" : false,
diff --git a/src/js/data.js b/src/js/data.js
index 2d69bc6..1cb112d 100644
--- a/src/js/data.js
+++ b/src/js/data.js
@@ -133,8 +133,14 @@ var data = function(c, maxSGVCount) {
});
};
+ d.addTokenToUrl = function(url, token)
+ {
+ if (token != "")
+ return url + "&token=" + token;
+ }
+
d.getPebbleEndpoint = debounce(function(config) {
- return d.getJSON(config.nightscout_url + '/pebble').then(function(pebbleData) {
+ return d.getJSON(d.addTokenToUrl(config.nightscout_url + '/pebble'), config.nightscout_token).then(function(pebbleData) {
if (pebbleData['bgs'] !== undefined && pebbleData['bgs'].length) {
return pebbleData['bgs'][0];
} else {
@@ -734,7 +740,7 @@ var data = function(c, maxSGVCount) {
} else {
start = new Date() - sgvCache.maxSecondsOld * 1000;
}
- var url = config.nightscout_url + '/api/v1/entries/sgv.json?count=1000&find[date][$gt]=' + start;
+ var url = d.addTokenToUrl(config.nightscout_url + '/api/v1/entries/sgv.json?count=1000&find[date][$gt]=' + start, config.nightscout_token);
return d.getJSON(url).then(function(newEntries) {
return sgvCache.update(
filterKeys(newEntries, ['date', 'sgv', 'trend', 'direction', 'filtered', 'unfiltered', 'noise'])
@@ -744,7 +750,7 @@ var data = function(c, maxSGVCount) {
d.getTempBasals = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/treatments.json?find[eventType]=Temp+Basal&count=' + tempBasalCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/treatments.json?find[eventType]=Temp+Basal&count=' + tempBasalCache.maxSize, config.nightscout_token),
tempBasalCache,
'created_at',
['created_at', 'duration', 'absolute', 'percent']
@@ -753,7 +759,7 @@ var data = function(c, maxSGVCount) {
d.getLastUploaderBattery = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/devicestatus.json?find[$or][0][uploaderBattery][$exists]=true&find[$or][1][uploader][$exists]=true&count=' + uploaderBatteryCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/devicestatus.json?find[$or][0][uploaderBattery][$exists]=true&find[$or][1][uploader][$exists]=true&count=' + uploaderBatteryCache.maxSize, config.nightscout_token),
uploaderBatteryCache,
'created_at'
);
@@ -761,7 +767,7 @@ var data = function(c, maxSGVCount) {
d.getLastCalibration = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/entries/cal.json?count=' + calibrationCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/entries/cal.json?count=' + calibrationCache.maxSize, config.nightscout_token),
calibrationCache,
'date'
);
@@ -769,7 +775,7 @@ var data = function(c, maxSGVCount) {
d.getBolusHistory = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/treatments.json?find[insulin][$exists]=true&count=' + bolusCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/treatments.json?find[insulin][$exists]=true&count=' + bolusCache.maxSize, config.nightscout_token),
bolusCache,
'created_at',
['created_at', 'insulin']
@@ -778,7 +784,7 @@ var data = function(c, maxSGVCount) {
d.getOpenAPSStatusHistory = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/devicestatus.json?find[openaps][$exists]=true&count=' + openAPSStatusCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/devicestatus.json?find[openaps][$exists]=true&count=' + openAPSStatusCache.maxSize, config.nightscout_token),
openAPSStatusCache,
'created_at'
);
@@ -786,7 +792,7 @@ var data = function(c, maxSGVCount) {
d.getLastLoopStatus = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/devicestatus.json?find[loop][$exists]=true&find[loop.failureReason][$not][$exists]=true&count=' + loopStatusCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/devicestatus.json?find[loop][$exists]=true&find[loop.failureReason][$not][$exists]=true&count=' + loopStatusCache.maxSize, config.nightscout_token),
loopStatusCache,
'created_at'
);
@@ -794,7 +800,7 @@ var data = function(c, maxSGVCount) {
d.getLastLoopEnacted = debounce(function(config) {
return getUsingCache(
- config.nightscout_url + '/api/v1/devicestatus.json?find[loop.enacted][$exists]=true&count=' + loopEnactedCache.maxSize,
+ d.addTokenToUrl(config.nightscout_url + '/api/v1/devicestatus.json?find[loop.enacted][$exists]=true&count=' + loopEnactedCache.maxSize, config.nightscout_token),
loopEnactedCache,
'created_at'
);
@@ -806,7 +812,7 @@ var data = function(c, maxSGVCount) {
// changes so infrequently that we can simply request it once per app load.
// (If the user updates their profile, they should restart the watchface.)
if (profileCache === undefined) {
- profileCache = d.getJSON(config.nightscout_url + '/api/v1/profile.json');
+ profileCache = d.getJSON(d.addTokenToUrl(config.nightscout_url + '/api/v1/profile.json', config.nightscout_token));
}
return profileCache;
};
diff --git a/src/js/ga.js b/src/js/ga.js
index 505a883..4e7a473 100644
--- a/src/js/ga.js
+++ b/src/js/ga.js
@@ -4,6 +4,7 @@ function track(data, trackingId, watchInfo, config) {
// redact PII
var current = JSON.parse(JSON.stringify(config));
delete current['nightscout_url'];
+ delete current['nightscout_token'];
delete current['dexcomUsername'];
delete current['dexcomPassword'];
delete current['statusText'];