-
???
-
mg/dL
+
-
-
+
diff --git a/js/client.js b/js/client.js
index 8f788e34354..64b0b7b3c41 100644
--- a/js/client.js
+++ b/js/client.js
@@ -2,8 +2,8 @@
"use strict";
var treatments,
- padding = { top: 20, right: 10, bottom: 30, left: 10},
- opacity = {current: 1, DAY: 1, NIGHT: 0.5},
+ padding = {top: 20, right: 10, bottom: 80, left: 10},
+ opacity = {current: 1, DAY: 1, NIGHT: 0.8},
now = Date.now(),
data = [],
dateFn = function (d) { return new Date(d.date)},
@@ -19,7 +19,13 @@
brushTimer,
brushInProgress = false,
clip,
- FOCUS_DATA_RANGE_MS = 12600000; // 3.5 hours of actual data
+ FOCUS_DATA_RANGE_MS = 12600000, // 3.5 hours of actual data
+ audio = document.getElementById('audio'),
+ alarmInProgress = false,
+ currentAlarmType = null,
+ alarmSound = 'alarm.mp3',
+ urgentAlarmSound = 'alarm2.mp3';
+
// create svg and g to contain the chart contents
var charts = d3.select('#chartContainer').append('svg')
@@ -98,9 +104,9 @@
// get the desired opacity for context chart based on the brush extent
function highlightBrushPoints(data) {
if (data.date.getTime() >= brush.extent()[0].getTime() && data.date.getTime() <= brush.extent()[1].getTime()) {
- return 1
+ return 1;
} else {
- return 0.2
+ return 0.5;
}
}
@@ -574,8 +580,30 @@
if (d.length > 1) {
// change the next line so that it uses the prediction if the signal gets lost (max 1/2 hr)
if (d[0].length) {
- $('#currentBG').text(d[0][d[0].length - 1].y);
- $('#bgValue').text(d[0][d[0].length - 1].y);
+ var current = d[0][d[0].length - 1];
+ var secsSinceLast = (Date.now() - new Date(current.x).getTime()) / 1000;
+ var currentBG = current.y;
+
+ //TODO: currently these are filtered on the server
+ //TODO: use icons for these magic values
+ switch (current.y) {
+ case 0: currentBG = '??0'; break; //None
+ case 1: currentBG = '?SN'; break; //SENSOR_NOT_ACTIVE
+ case 2: currentBG = '??2'; break; //MINIMAL_DEVIATION
+ case 3: currentBG = '?NA'; break; //NO_ANTENNA
+ case 5: currentBG = '?NC'; break; //SENSOR_NOT_CALIBRATED
+ case 6: currentBG = '?CD'; break; //COUNTS_DEVIATION
+ case 7: currentBG = '??7'; break; //?
+ case 8: currentBG = '??8'; break; //?
+ case 9: currentBG = '?AD'; break; //ABSOLUTE_DEVIATION
+ case 10: currentBG = '?PD'; break; //POWER_DEVIATION
+ case 12: currentBG = '?RF'; break; //BAD_RF
+ }
+
+ $('#lastEntry').text(timeAgo(secsSinceLast)).toggleClass('current', secsSinceLast < 10 * 60);
+ $('.container .currentBG').text(currentBG);
+ $('.container .currentDirection').html(current.direction);
+ $('.container .current').toggleClass('high', current.y > 180).toggleClass('low', current.y < 70)
}
data = d[0].map(function (obj) { return { date: new Date(obj.x), sgv: obj.y, color: 'grey'} });
data = data.concat(d[1].map(function (obj) { return { date: new Date(obj.x), sgv: obj.y, color: 'blue'} }));
@@ -619,23 +647,26 @@
$('#watchers').text(watchers);
});
- // load alarms
- var alarmSound = document.getElementById('audio');
- var urgentAlarmSound = document.getElementById('audio2');
-
- // alarm state
- var alarmInProgress = false;
- var currentAlarmType = null;
+ $('#testAlarms').click(function(event) {
+ event.preventDefault();
+ audio.src = 'audio/alarm.mp3';
+ audio.load();
+ audio.play();
+ setTimeout(function() {
+ audio.pause();
+ }, 4000);
+ });
- function generateAlarm(alarmType) {
+ function generateAlarm(file) {
alarmInProgress = true;
- alarmType.load();
- alarmType.play();
+ audio.src = 'audio/' + file;
+ audio.load();
+ audio.play();
var element = document.getElementById('bgButton');
element.hidden = '';
var element1 = document.getElementById('noButton');
element1.hidden = 'true';
- $('#bgValue').text($('#currentBG').text());
+ $('.container .currentBG').text();
}
function stopAlarm(isClient, silenceTime) {
@@ -644,15 +675,39 @@
element.hidden = 'true';
element = document.getElementById('noButton');
element.hidden = '';
- alarmSound.pause();
- urgentAlarmSound.pause();
+ audio.pause();
// only emit ack if client invoke by button press
if (isClient) {
- socket.emit('ack', currentAlarmType, silenceTime);
+ socket.emit('ack', currentAlarmType || 'alarm', silenceTime);
}
}
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+ function timeAgo(offset) {
+ var parts = {},
+ MINUTE = 60,
+ HOUR = 3600,
+ DAY = 86400,
+ WEEK = 604800;
+
+ if (offset <= MINUTE) parts = { lablel: 'now' };
+ if (offset <= MINUTE * 2) parts = { label: '1 min ago' };
+ else if (offset < (MINUTE * 60)) parts = { value: Math.round(Math.abs(offset / MINUTE)), label: 'mins' };
+ else if (offset < (HOUR * 2)) parts = { label: '1 hr ago' };
+ else if (offset < (HOUR * 24)) parts = { value: Math.round(Math.abs(offset / HOUR)), label: 'hrs' };
+ else if (offset < DAY) parts = { label: '1 day ago' };
+ else if (offset < (DAY * 7)) parts = { value: Math.round(Math.abs(offset / DAY)), label: 'day' };
+ else if (offset < (WEEK * 52)) parts = { value: Math.round(Math.abs(offset / WEEK)), label: 'week' };
+ else parts = { label: 'a long time ago' };
+
+ if (parts.value)
+ return parts.value + ' ' + parts.label + ' ago';
+ else
+ return parts.label;
+
+ }
+
+ ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//draw a compact visualization of a treatment (carbs, insulin)
diff --git a/server.js b/server.js
index b99372ce933..e293b6aeea0 100644
--- a/server.js
+++ b/server.js
@@ -101,6 +101,23 @@ DB.collection = DB.collection || process.env.CUSTOMCONNSTR_mongo_collection;
var DB_URL = DB.url;
var DB_COLLECTION = DB.collection;
+var dir2Char = {
+ 'NONE': '⇼',
+ 'DoubleUp': '⇈',
+ 'SingleUp': '↑',
+ 'FortyFiveUp': '↗',
+ 'Flat': '→',
+ 'FortyFiveDown': '↘',
+ 'SingleDown': '↓',
+ 'DoubleDown': '⇊',
+ 'NOT COMPUTABLE': '-',
+ 'RATE OUT OF RANGE': '↮'
+};
+
+function directionToChar(direction) {
+ return dir2Char[direction] || '-';
+}
+
var Alarm = function(_typeName, _threshold) {
this.typeName = _typeName;
this.silenceTime = FORTY_MINUTES;
@@ -139,6 +156,7 @@ function update() {
obj.y = element.sgv;
obj.x = element.date;
obj.d = element.dateString;
+ obj.direction = directionToChar(element.direction);
cgmData.push(obj);
}
});
@@ -217,8 +235,9 @@ function loadData() {
// compute current loss
var avgLoss = 0;
- for (var i = 0; i <= 6; i++) {
- avgLoss += 1 / 6 * Math.pow(log10(predicted[i].y / 120), 2);
+ var size = Math.min(predicted.length - 1, 6);
+ for (var j = 0; j <= size; j++) {
+ avgLoss += 1 / size * Math.pow(log10(predicted[j].y / 120), 2);
}
if (avgLoss > alarms['urgent_alarm'].threshold) {
@@ -231,6 +250,8 @@ function loadData() {
// get data from database and setup to update every minute
function kickstart ( ) {
+ //TODO: test server to see how data is stored (timestamps, entry values, etc)
+ //TODO: check server settings to configure alerts, entry units, etc
update( );
return update;
}