diff --git a/lib/carelink/getDeviceInfo.js b/lib/carelink/getDeviceInfo.js new file mode 100644 index 0000000000..5540b2fb96 --- /dev/null +++ b/lib/carelink/getDeviceInfo.js @@ -0,0 +1,64 @@ +/* + * == BSD2 LICENSE == + * Copyright (c) 2014, Tidepool Project + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the associated License, which is identical to the BSD 2-Clause + * License as published by the Open Source Initiative at opensource.org. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the License for more details. + * + * You should have received a copy of the License along with this program; if + * not, you can obtain one from Tidepool Project at tidepool.org. + * == BSD2 LICENSE == + */ + +var _ = require('lodash'); + +var common = require('./common.js'); +var parsing = require('./parsing.js'); + +module.exports = function(rows, type) { + var serials = [], multiple = false; + for (var i = 0; i < rows.length; ++i) { + if (rows[i][0].search(type) != -1) { + var model = rows[i][1].replace(' -', ''); + var serial = rows[i][2].replace('#', ''); + serials.push({ + deviceModel: model, + deviceSerialNumber: serial + }); + } + } + if (serials.length > 1) { + multiple = true; + } + return { + getDeviceModel: function() { + if (serials.length === 1) { + return serials[0].deviceModel; + } + else if (serials.length > 1) { + return 'multiple'; + } + else { + throw new Error('No devices! Cannot retrieve deviceModel :('); + } + }, + getDeviceSerialNumber: function() { + if (serials.length === 1) { + return serials[0].deviceSerialNumber; + } + else if (serials.length > 1) { + return 'multiple'; + } + else { + throw new Error('No devices! Cannot retrieve deviceSerialNumber :('); + } + }, + hasMultiple: function() { return multiple; }, + getPayload: function() { return {devices: serials}; } + }; +}; diff --git a/lib/core/api.js b/lib/core/api.js index cf3943170d..e083ebe8ab 100644 --- a/lib/core/api.js +++ b/lib/core/api.js @@ -15,8 +15,10 @@ var _ = require('lodash'); var async = require('async'); +var md5 = require('blueimp-md5'); var bows = require('../bows'); +var builder = require('../objectBuilder')(); var localStore = require('./localStore'); // Wrapper around the Tidepool client library @@ -169,27 +171,38 @@ api.upload.toPlatform = function(data, sessionInfo, progress, cb) { return postBlockToPlatform(data, callback); }; - var decorate_uploadid = function (data, uploadSessionMeta) { + var decorate_uploadid = function (data, uploadItem) { var deviceRecords = _.map(data, function(item) { - return _.extend({}, item, {uploadId: uploadSessionMeta.uploadId}); + return _.extend({}, item, {uploadId: uploadItem.uploadId}); }); - deviceRecords.unshift(uploadSessionMeta); + deviceRecords.unshift(uploadItem); return deviceRecords; }; - tidepool.startUploadSession(sessionInfo, function(err, uploadSessionMeta){ - if (err) { - return cb(err); - } - data = decorate_uploadid(data, uploadSessionMeta); - - for (var i = 0; i < data.length; i += BLOCKSIZE) { - blocks.push(data.slice(i, i + BLOCKSIZE)); - } + var uploadId = 'upid_' + md5(sessionInfo.deviceId + '_' + sessionInfo.start).slice(0, 12); + var uploadItem = builder.makeUpload() + .with_time(sessionInfo.start) + .with_timezone(sessionInfo.tzName) + .with_version(sessionInfo.version) + .with_uploadId(uploadId) + .with_source(sessionInfo.source) + .with_byUser(tidepool.getUserId()) + .with_deviceTags(sessionInfo.deviceTags) + .with_deviceManufacturers(sessionInfo.deviceManufacturers) + .with_deviceModel(sessionInfo.deviceModel) + .with_deviceSerialNumber(sessionInfo.deviceSerialNumber) + .with_deviceId(sessionInfo.deviceId) + .with_payload(sessionInfo.payload) + .done(); + + data = decorate_uploadid(data, uploadItem); + + for (var i = 0; i < data.length; i += BLOCKSIZE) { + blocks.push(data.slice(i, i + BLOCKSIZE)); + } - async.mapSeries(blocks, post_and_progress, cb); + async.mapSeries(blocks, post_and_progress, cb); - }); }; // `payload` contains: diff --git a/lib/drivers/abbottFreeStyle.js b/lib/drivers/abbottFreeStyle.js index af87b25df4..d86e93a4e1 100644 --- a/lib/drivers/abbottFreeStyle.js +++ b/lib/drivers/abbottFreeStyle.js @@ -372,7 +372,7 @@ module.exports = function (config) { _.assign(obj, _.pick(result, 'serialNumber', 'softwareVersion', 'deviceTime')); // we should add a serial number identification routine // that returns a better model ID (when we generalize this driver) - obj.model = 'Abbott Freestyle Precision Xtra'; + obj.model = 'AbbFreePrecXtra'; obj.id = obj.model + ' ' + obj.serialNumber; cb(null, obj); } @@ -493,6 +493,10 @@ module.exports = function (config) { uploadData: function (progress, data, cb) { progress(0); var sessionInfo = { + deviceTags: ['bgm'], + deviceManufacturers: ['Abbott'], + deviceModel: 'FreeStyle Precision Xtra', + deviceSerialNumber: data.serialNumber, deviceId: data.id, start: sundial.utcDateString(), tzName : cfg.timezone, diff --git a/lib/drivers/carelinkDriver.js b/lib/drivers/carelinkDriver.js index 9b58a51c09..6965660896 100644 --- a/lib/drivers/carelinkDriver.js +++ b/lib/drivers/carelinkDriver.js @@ -25,6 +25,7 @@ var sundial = require('sundial'); var common = require('../carelink/common'); var debug = require('../bows')('CarelinkDriver'); var removeOverlaps = require('../carelink/removeOverlapping'); +var getDeviceInfo = require('../carelink/getDeviceInfo'); var CARELINK_TS_FORMAT = 'MM/DD/YY HH:mm:ss'; function convertRawValues(e) { @@ -163,6 +164,7 @@ module.exports = function(simulatorMaker, api){ var endOfPreamble = cfg.fileData.indexOf('Index'); // Setup the preamble to have everything up to the header line payload.preamble = csv.parse(cfg.fileData.substr(0, endOfPreamble), {}); + cfg.deviceInfo = getDeviceInfo(payload.preamble.data, /Pump/); // Store the rest of the data payload.theData = csv.parse(cfg.fileData.substr(endOfPreamble), { header: true, @@ -209,7 +211,7 @@ module.exports = function(simulatorMaker, api){ device.simulator = simulatorMaker.make( { autoGenScheduleds: common.autoGenModels[key] ? true : false, - defaults: { } + defaults: { source: 'carelink' } }); device.processors = initializeProcessors(cfg.timezone, key); @@ -241,11 +243,24 @@ module.exports = function(simulatorMaker, api){ debug('Carelink UploadData!'); payload.post_records = []; async.map(Object.keys(payload.devices), function(key, done) { - var deviceRecords = payload.devices[key].simulator.getEvents(); + var deviceIds = _.uniq(_.pluck(deviceRecords, 'deviceId')); + var sessionInfo = { + deviceTags: ['insulin-pump'], + deviceManufacturers: ['Medtronic'], + deviceModel: cfg.deviceInfo.getDeviceModel(), + deviceSerialNumber: cfg.deviceInfo.getDeviceSerialNumber(), + deviceId: deviceIds.length > 1 ? 'multiple': deviceIds[0], + start: sundial.utcDateString(), + tzName : cfg.timezone, + version: cfg.version + }; + if (cfg.deviceInfo.hasMultiple()) { + sessionInfo.payload = cfg.deviceInfo.getPayload(); + } api.upload.toPlatform( deviceRecords, - {deviceId: Object.keys(payload.devices).toString(), start: sundial.utcDateString(), tzName : cfg.timezone, version: cfg.version}, + sessionInfo, progress, function (err, result) { if (err) { diff --git a/lib/drivers/dexcomDriver.js b/lib/drivers/dexcomDriver.js index f58ac18035..42d72780b6 100644 --- a/lib/drivers/dexcomDriver.js +++ b/lib/drivers/dexcomDriver.js @@ -572,13 +572,16 @@ module.exports = function (config) { }; var getDeviceId = function (data) { - return data.firmwareHeader.attrs.ProductName + ' ' + data.manufacturing_data.attrs.SerialNumber; + var names = data.firmwareHeader.attrs.ProductName.split(' '); + var shortname = _.map(names, function(name) { return name.slice(0,3); }).join(''); + return shortname + '_' + data.manufacturing_data.attrs.SerialNumber; }; var prepCBGData = function (data) { dexcomDeviceId = getDeviceId(data); cfg.builder.setDefaults({ deviceId: dexcomDeviceId }); + var dataToPost = []; for (var i = 0; i < data.cbg_data.length; ++i) { var datum = data.cbg_data[i]; @@ -691,7 +694,8 @@ module.exports = function (config) { fetchManufacturingData(0, function (err, result) { data.manufacturing_data = result; data.serialNumber = result.attrs.SerialNumber; - data.id = data.model + ' ' + data.serialNumber; + dexcomDeviceId = getDeviceId(data); + data.id = dexcomDeviceId; progress(100); data.getConfigInfo = true; cb(null, data); @@ -752,6 +756,10 @@ module.exports = function (config) { debug('STEP: uploadData'); progress(0); var sessionInfo = { + deviceTags: ['cgm'], + deviceManufacturers: ['Dexcom'], + deviceModel: data.model, + deviceSerialNumber: data.SerialNumber, deviceId: dexcomDeviceId, start: sundial.utcDateString(), tzName : cfg.timezone, diff --git a/lib/objectBuilder.js b/lib/objectBuilder.js index 5dea366449..6220f2b5e4 100644 --- a/lib/objectBuilder.js +++ b/lib/objectBuilder.js @@ -65,7 +65,7 @@ module.exports = function () { set: function set(k, v) { if (v == null && this[k]) { delete this[k]; - } else { + } else if (v != null) { this[k] = v; } return this; @@ -218,6 +218,7 @@ module.exports = function () { type: 'deviceMeta', subType: 'calibration', value: REQUIRED, + units: REQUIRED }); rec._bindProps(); return rec; @@ -284,6 +285,25 @@ module.exports = function () { return rec; } + function makeUpload() { + var rec = _.assign(_createObject(), { + type: 'upload', + time: REQUIRED, + timezone: REQUIRED, + version: REQUIRED, + source: OPTIONAL, + uploadId: REQUIRED, + byUser: REQUIRED, + deviceTags: REQUIRED, + deviceManufacturers: OPTIONAL, + deviceModel: OPTIONAL, + deviceSerialNumber: OPTIONAL, + deviceId: REQUIRED, + payload: OPTIONAL + }); + rec._bindProps(); + return rec; + } return { makeCBG: makeCBG, @@ -300,6 +320,7 @@ module.exports = function () { makeSquareBolus: makeSquareBolus, makeSuspendBasal: makeSuspendBasal, makeTempBasal: makeTempBasal, + makeUpload: makeUpload, makeWizard: makeWizard, setDefaults: setDefaults }; diff --git a/manifest.json b/manifest.json index 4bff872480..6bcc981cfb 100644 --- a/manifest.json +++ b/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Tidepool Uploader", "short_name": "Uploader", - "version": "0.100.0", + "version": "0.102.0", "description": "The Tidepool Uploader helps you get your data from insulin pumps, CGMs and BG meters into Tidepool’s secure cloud platform.", "minimum_chrome_version": "38", "icons": { diff --git a/package.json b/package.json index 113fbd34f9..9691f70b6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "tidepool-uploader", - "version": "0.100.0", + "version": "0.102.0", "description": "Tidepool Project Universal Uploader", "private": true, "main": "main.js", @@ -18,12 +18,13 @@ "dependencies": { "async": "0.9.0", "babyparse": "0.2.1", + "blueimp-md5": "1.1.0", "commander": "2.5.0", "lodash": "2.4.1", "moment-timezone": "0.2.4", "react": "0.12.0", "sundial": "1.1.1", - "tidepool-platform-client": "0.15.0" + "tidepool-platform-client": "0.16.1" }, "devDependencies": { "css-loader": "0.7.1", diff --git a/test/carelink/basal/scheduled/normal/output.json b/test/carelink/basal/scheduled/normal/output.json index ee18196173..f204334844 100644 --- a/test/carelink/basal/scheduled/normal/output.json +++ b/test/carelink/basal/scheduled/normal/output.json @@ -5,6 +5,7 @@ "rate": 0.8, "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:29:03", + "source": "carelink", "time": "2014-03-13T10:29:03.000Z", "timezoneOffset": -600, "type": "basal-scheduled", @@ -16,6 +17,7 @@ "rate": 0.9, "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T05:27:15", + "source": "carelink", "time": "2014-03-13T15:27:15.000Z", "timezoneOffset": -600, "type": "basal-scheduled", @@ -27,6 +29,7 @@ "rate": 0.65, "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-14T02:00:00", + "source": "carelink", "time": "2014-03-14T12:00:00.000Z", "timezoneOffset": -600, "type": "basal-scheduled", diff --git a/test/carelink/basal/scheduled/outOfSeq/output.json b/test/carelink/basal/scheduled/outOfSeq/output.json index b358cab586..17cf463ef9 100644 --- a/test/carelink/basal/scheduled/outOfSeq/output.json +++ b/test/carelink/basal/scheduled/outOfSeq/output.json @@ -1,6 +1,7 @@ [ { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-24T11:09:57", "time": "2014-11-24T21:09:57.000Z", "timezoneOffset": -600, @@ -12,6 +13,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-24T11:12:27", "time": "2014-11-24T21:12:27.000Z", "timezoneOffset": -600, @@ -23,6 +25,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-24T12:00:00", "time": "2014-11-24T22:00:00.000Z", "timezoneOffset": -600, diff --git a/test/carelink/basal/temp/percent/output.json b/test/carelink/basal/temp/percent/output.json index 1eb19c78ac..a64738a8f7 100644 --- a/test/carelink/basal/temp/percent/output.json +++ b/test/carelink/basal/temp/percent/output.json @@ -4,6 +4,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:00:00", "scheduleName": "standard", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:00:00.000Z", "type": "basal-scheduled", @@ -16,6 +17,7 @@ "deviceTime": "2014-03-13T00:28:56", "duration": 7200000, "percent": 0.7, + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:28:56.000Z", "type": "basal-temp" @@ -25,6 +27,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:29:03", "scheduleName": "standard", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:29:03.000Z", "type": "basal-scheduled", diff --git a/test/carelink/basal/temp/rate/output.json b/test/carelink/basal/temp/rate/output.json index a8c5d267bd..8b44c78537 100644 --- a/test/carelink/basal/temp/rate/output.json +++ b/test/carelink/basal/temp/rate/output.json @@ -4,6 +4,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:00:00", "scheduleName": "standard", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:00:00.000Z", "type": "basal-scheduled", @@ -16,6 +17,7 @@ "deviceTime": "2014-03-13T00:28:56", "duration": 7200000, "rate": 0.55, + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:28:56.000Z", "type": "basal-temp" @@ -25,6 +27,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:29:03", "scheduleName": "standard", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:29:03.000Z", "type": "basal-scheduled", diff --git a/test/carelink/bolus/22-series/dual/withWizard/output.json b/test/carelink/bolus/22-series/dual/withWizard/output.json index 5d3ccb40e3..ce4c85a998 100644 --- a/test/carelink/bolus/22-series/dual/withWizard/output.json +++ b/test/carelink/bolus/22-series/dual/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-05-18T18:24:10", "time": "2014-05-19T04:24:10.000Z", "timezoneOffset": -600, @@ -35,6 +36,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-05-18T18:24:10", "time": "2014-05-19T04:24:10.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/22-series/normal/noWizard/output.json b/test/carelink/bolus/22-series/normal/noWizard/output.json index 3416e67ba7..b78f492683 100644 --- a/test/carelink/bolus/22-series/normal/noWizard/output.json +++ b/test/carelink/bolus/22-series/normal/noWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-05-17T22:15:59", "time": "2014-05-18T08:15:59.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/22-series/normal/withWizard/output.json b/test/carelink/bolus/22-series/normal/withWizard/output.json index 1616f8d3a7..7ef681c914 100644 --- a/test/carelink/bolus/22-series/normal/withWizard/output.json +++ b/test/carelink/bolus/22-series/normal/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-05-17T19:47:58", "time": "2014-05-18T05:47:58.000Z", "timezoneOffset": -600, @@ -33,6 +34,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-05-17T19:47:58", "time": "2014-05-18T05:47:58.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/22-series/square/withWizard/output.json b/test/carelink/bolus/22-series/square/withWizard/output.json index cd3aee4aed..a24e61f1f4 100644 --- a/test/carelink/bolus/22-series/square/withWizard/output.json +++ b/test/carelink/bolus/22-series/square/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-06-01T18:10:42", "time": "2014-06-02T04:10:42.000Z", "timezoneOffset": -600, @@ -34,6 +35,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-06-01T18:10:42", "time": "2014-06-02T04:10:42.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/noWizard/output.json b/test/carelink/bolus/dual/noWizard/output.json index 7d84e32aa6..02b13a06cf 100644 --- a/test/carelink/bolus/dual/noWizard/output.json +++ b/test/carelink/bolus/dual/noWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T11:35:29", "time": "2014-11-14T21:35:29.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/noWizardNoNormal/output.json b/test/carelink/bolus/dual/noWizardNoNormal/output.json index e8bc43f16d..ce773f7cbd 100644 --- a/test/carelink/bolus/dual/noWizardNoNormal/output.json +++ b/test/carelink/bolus/dual/noWizardNoNormal/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T10:39:03", "time": "2014-11-14T20:39:03.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withMultiWizardOutOfSequence/output.json b/test/carelink/bolus/dual/withMultiWizardOutOfSequence/output.json index 1a83364b0c..3172cb2235 100644 --- a/test/carelink/bolus/dual/withMultiWizardOutOfSequence/output.json +++ b/test/carelink/bolus/dual/withMultiWizardOutOfSequence/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-09-18T18:59:37", "time": "2014-09-19T04:59:37.000Z", "timezoneOffset": -600, @@ -40,6 +41,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-09-18T18:59:38", "time": "2014-09-19T04:59:38.000Z", "timezoneOffset": -600, @@ -56,6 +58,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-09-18T19:00:00", "time": "2014-09-19T05:00:00.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withWizard/output.json b/test/carelink/bolus/dual/withWizard/output.json index 1229834001..6b61047c1d 100644 --- a/test/carelink/bolus/dual/withWizard/output.json +++ b/test/carelink/bolus/dual/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-14T17:36:13", "time": "2014-11-15T03:36:13.000Z", "timezoneOffset": -600, @@ -35,6 +36,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T17:36:13", "time": "2014-11-15T03:36:13.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withWizardInterruptedWithOverride/output.json b/test/carelink/bolus/dual/withWizardInterruptedWithOverride/output.json index df56951df1..28d5d8cf68 100644 --- a/test/carelink/bolus/dual/withWizardInterruptedWithOverride/output.json +++ b/test/carelink/bolus/dual/withWizardInterruptedWithOverride/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-15T10:47:16", "time": "2014-11-15T20:47:16.000Z", "timezoneOffset": -600, @@ -37,6 +38,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-15T10:47:17", "time": "2014-11-15T20:47:17.000Z", "timezoneOffset": -600, @@ -50,6 +52,7 @@ }, { "type": "suspend", + "source": "carelink", "deviceTime": "2014-11-15T11:31:40", "time": "2014-11-15T21:31:40.000Z", "timezoneOffset": -600, @@ -58,6 +61,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-15T11:41:36", "time": "2014-11-15T21:41:36.000Z", "timezoneOffset": -600, @@ -69,6 +73,7 @@ }, { "type": "resume", + "source": "carelink", "deviceTime": "2014-11-15T11:41:37", "time": "2014-11-15T21:41:37.000Z", "timezoneOffset": -600, @@ -77,6 +82,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-15T12:00:00", "time": "2014-11-15T22:00:00.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withWizardMultiIntervention/output.json b/test/carelink/bolus/dual/withWizardMultiIntervention/output.json index f2eafd6974..7eaa2e4fd9 100644 --- a/test/carelink/bolus/dual/withWizardMultiIntervention/output.json +++ b/test/carelink/bolus/dual/withWizardMultiIntervention/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-19T09:33:44", "time": "2014-11-19T19:33:44.000Z", "timezoneOffset": -600, @@ -34,6 +35,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-19T09:33:45", "time": "2014-11-19T19:33:45.000Z", "timezoneOffset": -600, @@ -48,6 +50,7 @@ }, { "type": "cbg", + "source": "carelink", "deviceTime": "2014-11-19T09:35:00", "time": "2014-11-19T19:35:00.000Z", "timezoneOffset": -600, @@ -57,6 +60,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-19T09:36:27", "time": "2014-11-19T19:36:27.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withWizardNoNormal/output.json b/test/carelink/bolus/dual/withWizardNoNormal/output.json index 67148e49ba..61ca621b8f 100644 --- a/test/carelink/bolus/dual/withWizardNoNormal/output.json +++ b/test/carelink/bolus/dual/withWizardNoNormal/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-16T20:33:49", "time": "2014-11-17T06:33:49.000Z", "timezoneOffset": -600, @@ -34,6 +35,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-16T20:33:50", "time": "2014-11-17T06:33:50.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/dual/withWizardOutOfSequence/output.json b/test/carelink/bolus/dual/withWizardOutOfSequence/output.json index f8ebbd09cf..4eb16f9f26 100644 --- a/test/carelink/bolus/dual/withWizardOutOfSequence/output.json +++ b/test/carelink/bolus/dual/withWizardOutOfSequence/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-05-29T21:01:58", "time": "2014-05-30T07:01:58.000Z", "timezoneOffset": -600, @@ -45,6 +46,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-05-29T21:01:58", "time": "2014-05-30T07:01:58.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/normal/noWizard/output.json b/test/carelink/bolus/normal/noWizard/output.json index 5d627a64c4..54e64fe859 100644 --- a/test/carelink/bolus/normal/noWizard/output.json +++ b/test/carelink/bolus/normal/noWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T12:11:50", "time": "2014-11-14T22:11:50.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/normal/noWizardInterrupted/output.json b/test/carelink/bolus/normal/noWizardInterrupted/output.json index 67b6943723..5d7ce34e2a 100644 --- a/test/carelink/bolus/normal/noWizardInterrupted/output.json +++ b/test/carelink/bolus/normal/noWizardInterrupted/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T12:25:21", "time": "2014-11-14T22:25:21.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/normal/withOverride/output.json b/test/carelink/bolus/normal/withOverride/output.json index 053f05c711..a0fa178ac7 100644 --- a/test/carelink/bolus/normal/withOverride/output.json +++ b/test/carelink/bolus/normal/withOverride/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-14T13:00:11", "time": "2014-11-14T23:00:11.000Z", "timezoneOffset": -600, @@ -33,6 +34,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T13:00:11", "time": "2014-11-14T23:00:11.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/normal/withWizard/output.json b/test/carelink/bolus/normal/withWizard/output.json index 258aa6bc63..f349ee73ea 100644 --- a/test/carelink/bolus/normal/withWizard/output.json +++ b/test/carelink/bolus/normal/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-14T08:55:54", "time": "2014-11-14T18:55:54.000Z", "timezoneOffset": -600, @@ -33,6 +34,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T08:55:54", "time": "2014-11-14T18:55:54.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/normal/withWizardInterveningBG/output.json b/test/carelink/bolus/normal/withWizardInterveningBG/output.json index b434012dbf..038a4916ae 100644 --- a/test/carelink/bolus/normal/withWizardInterveningBG/output.json +++ b/test/carelink/bolus/normal/withWizardInterveningBG/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-14T15:06:44", "time": "2014-11-15T01:06:44.000Z", "timezoneOffset": -600, @@ -33,6 +34,7 @@ }, { "type": "smbg", + "source": "carelink", "deviceTime": "2014-11-14T15:07:01", "time": "2014-11-15T01:07:01.000Z", "timezoneOffset": -600, @@ -42,6 +44,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T15:07:23", "time": "2014-11-15T01:07:23.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/square/noWizard/output.json b/test/carelink/bolus/square/noWizard/output.json index e8bc43f16d..ce773f7cbd 100644 --- a/test/carelink/bolus/square/noWizard/output.json +++ b/test/carelink/bolus/square/noWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T10:39:03", "time": "2014-11-14T20:39:03.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/square/noWizardInterrupted/output.json b/test/carelink/bolus/square/noWizardInterrupted/output.json index bbb5ae271f..48fada192a 100644 --- a/test/carelink/bolus/square/noWizardInterrupted/output.json +++ b/test/carelink/bolus/square/noWizardInterrupted/output.json @@ -1,6 +1,7 @@ [ { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-16T16:03:47", "time": "2014-11-17T02:03:47.000Z", "timezoneOffset": -600, @@ -13,6 +14,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-16T16:04:30", "time": "2014-11-17T02:04:30.000Z", "timezoneOffset": -600, @@ -24,6 +26,7 @@ }, { "type": "suspend", + "source": "carelink", "deviceTime": "2014-11-16T16:17:50", "time": "2014-11-17T02:17:50.000Z", "timezoneOffset": -600, @@ -32,6 +35,7 @@ }, { "type": "resume", + "source": "carelink", "deviceTime": "2014-11-16T16:28:43", "time": "2014-11-17T02:28:43.000Z", "timezoneOffset": -600, diff --git a/test/carelink/bolus/square/withWizard/output.json b/test/carelink/bolus/square/withWizard/output.json index 0cdb8a853c..7805d6ed82 100644 --- a/test/carelink/bolus/square/withWizard/output.json +++ b/test/carelink/bolus/square/withWizard/output.json @@ -1,6 +1,7 @@ [ { "type": "wizard", + "source": "carelink", "deviceTime": "2014-11-14T08:59:03", "time": "2014-11-14T18:59:03.000Z", "timezoneOffset": -600, @@ -34,6 +35,7 @@ }, { "type": "bolus", + "source": "carelink", "deviceTime": "2014-11-14T08:59:03", "time": "2014-11-14T18:59:03.000Z", "timezoneOffset": -600, diff --git a/test/carelink/cbg/output.json b/test/carelink/cbg/output.json index 9180b4dfd0..cc2ba69b1b 100644 --- a/test/carelink/cbg/output.json +++ b/test/carelink/cbg/output.json @@ -1,6 +1,7 @@ [ { "type": "cbg", + "source": "carelink", "time": "2014-03-13T10:04:00.000Z", "deviceTime": "2014-03-13T00:04:00", "timezoneOffset": -600, diff --git a/test/carelink/settings/noChanges/output.json b/test/carelink/settings/noChanges/output.json index 3b3163b09a..0bbd13612d 100644 --- a/test/carelink/settings/noChanges/output.json +++ b/test/carelink/settings/noChanges/output.json @@ -45,6 +45,7 @@ { "amount": 45, "start": 18000000 }, { "amount": 65, "start": 82800000 } ], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:00:00.000Z", "type": "settings", @@ -58,6 +59,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:00:00", "scheduleName": "standard", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:00:00.000Z", "type": "basal-scheduled", diff --git a/test/carelink/settings/withChanges/output.json b/test/carelink/settings/withChanges/output.json index d2b7edb1ce..3ee154c04c 100644 --- a/test/carelink/settings/withChanges/output.json +++ b/test/carelink/settings/withChanges/output.json @@ -2,6 +2,7 @@ { "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T00:04:00", + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T10:04:00.000Z", "type": "cbg", @@ -20,6 +21,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-13T11:51:05", "insulinSensitivity": [], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-13T21:51:05.000Z", "type": "settings", @@ -47,6 +49,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-14T01:01:27", "insulinSensitivity": [], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-14T11:01:27.000Z", "type": "settings", @@ -76,6 +79,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-14T01:02:02", "insulinSensitivity": [], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-14T11:02:02.000Z", "type": "settings", @@ -113,6 +117,7 @@ "deviceId": "Paradigm Revel - 723-=-53021863", "deviceTime": "2014-03-14T01:03:59", "insulinSensitivity": [], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-14T11:03:59.000Z", "type": "settings", @@ -164,6 +169,7 @@ { "amount": 45, "start": 18000000 }, { "amount": 65, "start": 82800000 } ], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-14T11:08:07.000Z", "type": "settings", @@ -215,6 +221,7 @@ { "amount": 45, "start": 18000000 }, { "amount": 65, "start": 82800000 } ], + "source": "carelink", "timezoneOffset": -600, "time": "2014-03-14T21:51:05.000Z", "type": "settings", diff --git a/test/carelink/settings/withSameTimeChanges/output.json b/test/carelink/settings/withSameTimeChanges/output.json index f48a8b273b..d788fd3b35 100644 --- a/test/carelink/settings/withSameTimeChanges/output.json +++ b/test/carelink/settings/withSameTimeChanges/output.json @@ -1,6 +1,7 @@ [ { "type": "settings", + "source": "carelink", "deviceTime": "2014-11-24T11:09:57", "time": "2014-11-24T21:09:57.000Z", "timezoneOffset": -600, @@ -130,6 +131,7 @@ }, { "type": "basal-scheduled", + "source": "carelink", "deviceTime": "2014-11-24T11:09:57", "time": "2014-11-24T21:09:57.000Z", "timezoneOffset": -600, @@ -141,6 +143,7 @@ }, { "type": "settings", + "source": "carelink", "deviceTime": "2014-11-24T11:12:26", "time": "2014-11-24T21:12:26.000Z", "timezoneOffset": -600, @@ -275,6 +278,7 @@ }, { "type": "smbg", + "source": "carelink", "deviceTime": "2014-11-25T17:53:45", "time": "2014-11-26T03:53:45.000Z", "timezoneOffset": -600, @@ -284,6 +288,7 @@ }, { "type": "smbg", + "source": "carelink", "deviceTime": "2014-11-26T10:44:23", "time": "2014-11-26T20:44:23.000Z", "timezoneOffset": -600, diff --git a/test/carelink/smbg/output.json b/test/carelink/smbg/output.json index a90752c781..2c2adcbebb 100644 --- a/test/carelink/smbg/output.json +++ b/test/carelink/smbg/output.json @@ -1,6 +1,7 @@ [ { "type": "smbg", + "source": "carelink", "deviceTime": "2014-03-13T21:03:51", "time": "2014-03-14T07:03:51.000Z", "timezoneOffset": -600, diff --git a/test/carelink/suspend/output.json b/test/carelink/suspend/output.json index c9835385f2..9072ce7625 100644 --- a/test/carelink/suspend/output.json +++ b/test/carelink/suspend/output.json @@ -3,6 +3,7 @@ "time": "2014-03-14T15:48:38.000Z", "deviceTime": "2014-03-14T05:48:38", "timezoneOffset": -600, + "source": "carelink", "type": "suspend", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-52825853" @@ -11,6 +12,7 @@ "time": "2014-03-14T20:08:19.000Z", "deviceTime": "2014-03-14T10:08:19", "timezoneOffset": -600, + "source": "carelink", "type": "suspend", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-52850875" @@ -19,6 +21,7 @@ "time": "2014-03-14T20:11:06.000Z", "deviceTime": "2014-03-14T10:11:06", "timezoneOffset": -600, + "source": "carelink", "type": "resume", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-52861049" @@ -27,6 +30,7 @@ "time": "2014-03-15T01:40:47.000Z", "deviceTime": "2014-03-14T15:40:47", "timezoneOffset": -600, + "source": "carelink", "type": "suspend", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-53118738" @@ -35,6 +39,7 @@ "time": "2014-03-15T01:42:38.000Z", "deviceTime": "2014-03-14T15:42:38", "timezoneOffset": -600, + "source": "carelink", "type": "suspend", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-53021863" @@ -43,6 +48,7 @@ "time": "2014-03-15T01:42:52.000Z", "deviceTime": "2014-03-14T15:42:52", "timezoneOffset": -600, + "source": "carelink", "type": "resume", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-53021863" @@ -51,6 +57,7 @@ "time": "2014-03-15T01:51:39.000Z", "deviceTime": "2014-03-14T15:51:39", "timezoneOffset": -600, + "source": "carelink", "type": "resume", "reason": "manual", "deviceId": "Paradigm Revel - 723-=-53136995" diff --git a/test/carelink/testSerial.js b/test/carelink/testSerial.js new file mode 100644 index 0000000000..2469bdb642 --- /dev/null +++ b/test/carelink/testSerial.js @@ -0,0 +1,96 @@ +/* + * == BSD2 LICENSE == + * Copyright (c) 2014, Tidepool Project + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the associated License, which is identical to the BSD 2-Clause + * License as published by the Open Source Initiative at opensource.org. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the License for more details. + * + * You should have received a copy of the License along with this program; if + * not, you can obtain one from Tidepool Project at tidepool.org. + * == BSD2 LICENSE == + */ + +/* global describe, it */ + +var _ = require('lodash'); +var expect = require('salinity').expect; + +var getDeviceInfo = require('../../lib/carelink/getDeviceInfo'); + +describe('getDeviceInfo', function() { + var fakeRows = [ + ['The cure for anything is salt water:', 'sweat', 'tears', 'or the sea'], + ['Isak', 'Dinesen'], + ['Meter:', 'OneTouch Mini', '#12345'], + ['Pump:', 'MiniMed 530G - 551', '#6789A'], + ['Baroness', 'Karen', 'von', 'Blixen-Finecke'] + ]; + + var multiplePumps = _.cloneDeep(fakeRows); + multiplePumps.splice(4, 0, ['Pump:', 'Paradigm Revel - 523', 'foobar']); + + it('should return an object', function() { + expect(getDeviceInfo([], /foo/)).to.be.an('object'); + }); + + it('should read the model and serial number of a bgm', function() { + var devices = getDeviceInfo(fakeRows, /Meter/); + expect(devices.getDeviceModel()).to.equal('OneTouch Mini'); + expect(devices.getDeviceSerialNumber()).to.equal('12345'); + }); + + it('should read the model and serial number of a pump', function() { + var devices = getDeviceInfo(fakeRows, /Pump/); + expect(devices.getDeviceModel()).to.equal('MiniMed 530G 551'); + }); + + it('should return `multiple` when more than one pump or meter is present', function() { + var devices = getDeviceInfo(multiplePumps, /Pump/); + expect(devices.getDeviceModel()).to.equal('multiple'); + expect(devices.getDeviceSerialNumber()).to.equal('multiple'); + }); + + it('should return a payload object containing a `devices` array that is an array of all devices', function() { + var devices = getDeviceInfo(multiplePumps, /Pump/); + var payloadDevices = devices.getPayload().devices; + expect(payloadDevices).to.be.an('array'); + expect(payloadDevices.length).to.equal(2); + }); + + describe('getDeviceModel', function() { + it('should throw an error if devices array is empty', function() { + var devices = getDeviceInfo([], /Pump/); + var fn = function() { devices.getDeviceModel(); }; + expect(fn).to.throw(Error); + }); + }); + + describe('getDeviceSerialNumber', function() { + it('should throw an error if devices array is empty', function() { + var devices = getDeviceInfo([], /Pump/); + var fn = function() { devices.getDeviceSerialNumber(); }; + expect(fn).to.throw(Error); + }); + }); + + describe('hasMultiple', function() { + it('should return false when only one device of a particular type present', function() { + var meters1 = getDeviceInfo(fakeRows, /Meter/); + var pumps = getDeviceInfo(fakeRows, /Pump/); + var meters2 = getDeviceInfo(multiplePumps, /Meter/); + expect(meters1.hasMultiple()).to.be.false; + expect(pumps.hasMultiple()).to.be.false; + expect(meters2.hasMultiple()).to.be.false; + }); + + it('should return true when multiple devices of a particular type present', function() { + var pumps = getDeviceInfo(multiplePumps, /Pump/); + expect(pumps.hasMultiple()).to.be.true; + }); + }); +}); \ No newline at end of file