From 167ee5c873adec1e3141f98b2ee80c91a73d623a Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Tue, 7 Aug 2018 13:09:07 -0500 Subject: [PATCH 01/21] Added genereic delete capability. --- lib/api/devicestatus/index.js | 51 ++++++++++++++++++++++++++++------- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 9d6fc1bfce7..2f8dab5663b 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -2,6 +2,12 @@ var consts = require('../../constants'); +var ID_PATTERN = /^[a-f\d]{24}$/; + +function isId(value) { + return value && ID_PATTERN.test(value) && value.length === 24; +} + function configure (app, wares, ctx) { var express = require('express'), api = express.Router( ); @@ -28,6 +34,31 @@ function configure (app, wares, ctx) { }); }); + /** + * @function delete_records + * Delete entries. The query logic works the same way as find/list. This + * endpoint uses same search logic to remove records from the database. + */ + function delete_records(req, res, next) { + // bias towards model, but allow expressing a preference + if (!req.model) { + req.model = ctx.devicestatus; + } + var query = req.query; + if (!query.count) { + query.count = 10 + } + // remove using the query + req.model.remove(query, function(err, stat) { + if (err) { + return next(err); + } + // yield some information about success of operation + res.json(stat); + return next(); + }); + } + function config_authed (app, api, wares, ctx) { function doPost (req, res) { @@ -44,15 +75,17 @@ function configure (app, wares, ctx) { api.post('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:create'), doPost); // delete record - api.delete('/devicestatus/:_id', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { - ctx.devicestatus.remove(req.params._id, function (err, removed) { - if (err) { - res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); - } else { - res.json(removed); - } - }); - }); + api.delete('/devicestatus/:spec', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { + // if ID, prepare to query for one record + if (isId(req.params.spec)) { + req.query = { + find: { + _id: req.params.spec + } + }; + } + next(); + }, delete_records); } From dfebdde32ef0a588408defdb1c0726b7dc239bfa Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Tue, 7 Aug 2018 13:24:39 -0500 Subject: [PATCH 02/21] Added missing function argument. --- lib/api/devicestatus/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 2f8dab5663b..f262a540400 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -75,7 +75,7 @@ function configure (app, wares, ctx) { api.post('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:create'), doPost); // delete record - api.delete('/devicestatus/:spec', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { + api.delete('/devicestatus/:spec', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { // if ID, prepare to query for one record if (isId(req.params.spec)) { req.query = { From 6cc2bcf2e13191fd811b06e9de996b453de4961c Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Tue, 7 Aug 2018 13:37:25 -0500 Subject: [PATCH 03/21] Added debug message. --- lib/api/devicestatus/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index f262a540400..1349b06de6c 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -48,6 +48,7 @@ function configure (app, wares, ctx) { if (!query.count) { query.count = 10 } + console.log(query); // remove using the query req.model.remove(query, function(err, stat) { if (err) { From b6f5703869c6a34b753b019ee3c00d45ce9764cd Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Tue, 7 Aug 2018 13:43:03 -0500 Subject: [PATCH 04/21] Revised devicestatus server to allow generic query parameters for remove. --- lib/server/devicestatus.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index 1939450adb5..e5e47489932 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -59,14 +59,8 @@ function storage (collection, ctx) { ).toArray(toArray); } - function remove (_id, fn) { - var filter; - if (_id === '*') { - filter = {}; - } else { - filter = { '_id': new ObjectID(_id) }; - } - return api( ).remove(filter, fn); + function remove (opts, fn) { + api( ).remove(query_for(opts), fn); } function api() { From 39dda80554cf905f6fb7e838a21bfb2da68bf51e Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 21:02:25 -0500 Subject: [PATCH 05/21] Added debug. --- lib/api/devicestatus/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 1349b06de6c..aaadff3c615 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -77,6 +77,8 @@ function configure (app, wares, ctx) { // delete record api.delete('/devicestatus/:spec', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { + console.log('Here: ', req); + // if ID, prepare to query for one record if (isId(req.params.spec)) { req.query = { From 6b3813341138dc31cd2d3bdaccd233dd69812472 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 21:36:24 -0500 Subject: [PATCH 06/21] Added id specific routh path back for api.delete. --- lib/api/devicestatus/index.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index aaadff3c615..54b47285cf0 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -49,6 +49,10 @@ function configure (app, wares, ctx) { query.count = 10 } console.log(query); + + res.json({ status: 'here' }); + + return next(); // remove using the query req.model.remove(query, function(err, stat) { if (err) { @@ -75,18 +79,18 @@ function configure (app, wares, ctx) { api.post('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:create'), doPost); + api.delete('/devicestatus/:_id', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { + ctx.devicestatus.remove(req.params._id, function (err, removed) { + if (err) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + } else { + res.json(removed); + } + }); + }); + // delete record - api.delete('/devicestatus/:spec', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { - console.log('Here: ', req); - - // if ID, prepare to query for one record - if (isId(req.params.spec)) { - req.query = { - find: { - _id: req.params.spec - } - }; - } + api.delete('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { next(); }, delete_records); From bf72ccd7e90aefec5364890eacceb936dad83c65 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 21:55:22 -0500 Subject: [PATCH 07/21] Debug. --- lib/api/devicestatus/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 54b47285cf0..fd29304cff4 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -48,11 +48,9 @@ function configure (app, wares, ctx) { if (!query.count) { query.count = 10 } - console.log(query); - res.json({ status: 'here' }); + console.log('Delete records with query: ', query); - return next(); // remove using the query req.model.remove(query, function(err, stat) { if (err) { @@ -80,6 +78,8 @@ function configure (app, wares, ctx) { api.post('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:create'), doPost); api.delete('/devicestatus/:_id', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { + console.log('Deleting id: ' + req.params._id); + ctx.devicestatus.remove(req.params._id, function (err, removed) { if (err) { res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); From bc99e63015cd6e492a0dc6c72f13eba91c892b19 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 22:29:16 -0500 Subject: [PATCH 08/21] Fixed delete devicestatus by id. --- lib/api/devicestatus/index.js | 10 ++-------- lib/server/devicestatus.js | 12 +++++++++++- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index fd29304cff4..712fc42da30 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -2,12 +2,6 @@ var consts = require('../../constants'); -var ID_PATTERN = /^[a-f\d]{24}$/; - -function isId(value) { - return value && ID_PATTERN.test(value) && value.length === 24; -} - function configure (app, wares, ctx) { var express = require('express'), api = express.Router( ); @@ -80,7 +74,7 @@ function configure (app, wares, ctx) { api.delete('/devicestatus/:_id', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { console.log('Deleting id: ' + req.params._id); - ctx.devicestatus.remove(req.params._id, function (err, removed) { + ctx.devicestatus.remove_id(req.params._id, function (err, removed) { if (err) { res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); } else { @@ -89,7 +83,7 @@ function configure (app, wares, ctx) { }); }); - // delete record + // delete record that match query api.delete('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { next(); }, delete_records); diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index e5e47489932..fb99615dc79 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -60,7 +60,17 @@ function storage (collection, ctx) { } function remove (opts, fn) { - api( ).remove(query_for(opts), fn); + return api( ).remove(query_for(opts), fn); + } + + function remove_id (_id, fn) { + var filter; + if (_id === '*') { + filter = {}; + } else { + filter = { '_id': new ObjectID(_id) }; + } + return api( ).remove(filter, fn); } function api() { From 78023e6830b68bae495ec156c19d49315f0fc6a6 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 22:35:21 -0500 Subject: [PATCH 09/21] Added remove_id to devicestatus server functions. --- lib/server/devicestatus.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index fb99615dc79..3d925a56605 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -82,6 +82,7 @@ function storage (collection, ctx) { api.query_for = query_for; api.last = last; api.remove = remove; + api.remove_id = remove_id; api.aggregate = require('./aggregate')({ }, api); api.indexedFields = [ 'created_at' From 8e84d116b46639577074a8d764f3eecbe06688a5 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 22:56:04 -0500 Subject: [PATCH 10/21] Cleaned up code in api/devicestatus/index.js --- lib/api/devicestatus/index.js | 51 ++++++++++++++--------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 712fc42da30..2c0a7443188 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -28,34 +28,6 @@ function configure (app, wares, ctx) { }); }); - /** - * @function delete_records - * Delete entries. The query logic works the same way as find/list. This - * endpoint uses same search logic to remove records from the database. - */ - function delete_records(req, res, next) { - // bias towards model, but allow expressing a preference - if (!req.model) { - req.model = ctx.devicestatus; - } - var query = req.query; - if (!query.count) { - query.count = 10 - } - - console.log('Delete records with query: ', query); - - // remove using the query - req.model.remove(query, function(err, stat) { - if (err) { - return next(err); - } - // yield some information about success of operation - res.json(stat); - return next(); - }); - } - function config_authed (app, api, wares, ctx) { function doPost (req, res) { @@ -84,9 +56,26 @@ function configure (app, wares, ctx) { }); // delete record that match query - api.delete('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res, next) { - next(); - }, delete_records); + api.delete('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { + var query = req.query; + if (!query.count) { + query.count = 10 + } + + console.log('Delete records with query: ', query); + + // remove using the query + ctx.devicestatus.remove(query, function(err, stat) { + if (err) { + res.sendJSONStatus(res, consts.HTTP_INTERNAL_ERROR, 'Mongo Error', err); + console.log('Error saving treatment'); + console.log(err); + } else { + res.json(stat); + console.log('devicestatus records deleted', data); + } + }); + }); } From 91a8135e454bea6c7f5a3c1ac4a1dc6b88c7d979 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Wed, 8 Aug 2018 23:03:55 -0500 Subject: [PATCH 11/21] Fixed --- lib/api/devicestatus/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 2c0a7443188..783388ca644 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -72,7 +72,7 @@ function configure (app, wares, ctx) { console.log(err); } else { res.json(stat); - console.log('devicestatus records deleted', data); + console.log('devicestatus records deleted'); } }); }); From bcce40aa279e24bfbf91c397e9cc2c854bed8d6e Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 12:59:09 -0500 Subject: [PATCH 12/21] Added new option to delete up to a certain number of days worth of devicestatus collection records. --- lib/admin_plugins/cleanstatusdb.js | 69 ++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index 4769a724789..f3981ab6a60 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -1,5 +1,7 @@ 'use strict'; +var moment = require('moment'); + var cleanstatusdb = { name: 'cleanstatusdb' , label: 'Clean Mongo status database' @@ -19,6 +21,12 @@ cleanstatusdb.actions = [ , buttonLabel: 'Delete all documents' , confirmText: 'Delete all documents from devicestatus collection?' } + , { + name: 'Delete all documents from devicestatus collection older than 30 days' + , description: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' + , buttonLabel: 'Delete old documents' + , confirmText: 'Delete old documents from devicestatus collection?' + } ]; cleanstatusdb.actions[0].init = function init(client, callback) { @@ -66,4 +74,65 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { callback(); } }); + + +cleanstatusdb.actions[1].init = function init(client, callback) { + var translate = client.translate; + var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); + + $status.hide(); + + var numDays = '
' + + ''; + + $('#admin_' + cleanstatusdb.name + '_1_html').html(numDays); + + if (callback) { callback(); } +}; + +cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { + var translate = client.translate; + var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); + var numDays = Number($('#admin_devicestatus_days').val()); + + if (isNaN(numDays) || (numDays <= 0)) { + alert(translate('%1 is not a valid number', { params: [$('#admin_devicestatus_days').val()] })); + if (callback) { + callback(); + } + return; + } + var endDate = moment().subtract(numDays, 'days'); + var dateStr = endDate.format('YYYY-MM-DD'); + + 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/' + dateStr + , headers: client.headers() + , success: function (retVal) { + $status.hide().text(translate('%1 records deleted',{ params: [retVal.n] })).fadeIn('slow'); + } + }).done(function success () { + if (callback) { + callback(); + } + }).fail(function fail() { + $status.hide().text(translate('Error')).fadeIn('slow'); + if (callback) { + callback(); + } + }); + }; From 59ffd011f39a421e41a5127c4bc04e621fccc942 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 13:38:16 -0500 Subject: [PATCH 13/21] Removed extra line. --- lib/admin_plugins/cleanstatusdb.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index f3981ab6a60..ce716c2bd35 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -75,7 +75,6 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { } }); - cleanstatusdb.actions[1].init = function init(client, callback) { var translate = client.translate; var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); From 471ad30228131c354519552dc3d69321ba149a44 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 13:44:41 -0500 Subject: [PATCH 14/21] Fixed syntax error. --- lib/admin_plugins/cleanstatusdb.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index ce716c2bd35..10a17d578cd 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -74,6 +74,7 @@ cleanstatusdb.actions[0].code = function deleteRecords(client, callback) { callback(); } }); +}; cleanstatusdb.actions[1].init = function init(client, callback) { var translate = client.translate; @@ -99,9 +100,7 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { if (isNaN(numDays) || (numDays <= 0)) { alert(translate('%1 is not a valid number', { params: [$('#admin_devicestatus_days').val()] })); - if (callback) { - callback(); - } + if (callback) { callback(); } return; } var endDate = moment().subtract(numDays, 'days'); @@ -124,14 +123,10 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { $status.hide().text(translate('%1 records deleted',{ params: [retVal.n] })).fadeIn('slow'); } }).done(function success () { - if (callback) { - callback(); - } + if (callback) { callback(); } }).fail(function fail() { $status.hide().text(translate('Error')).fadeIn('slow'); - if (callback) { - callback(); - } + if (callback) { callback(); } }); }; From 682739b3d974ac38f29173909fe888d43a69ce5b Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 15:01:52 -0500 Subject: [PATCH 15/21] Fixed delete devicestatus url. --- lib/admin_plugins/cleanstatusdb.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index 10a17d578cd..52a7de026ba 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -117,7 +117,7 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { $status.hide().text(translate('Deleting records ...')).fadeIn('slow'); $.ajax({ method: 'DELETE' - , url: '/api/v1/devicestatus/' + dateStr + , url: '/api/v1/devicestatus/?find[created_at][$lte]=' + dateStr , headers: client.headers() , success: function (retVal) { $status.hide().text(translate('%1 records deleted',{ params: [retVal.n] })).fadeIn('slow'); From f88621e378b0a0a731fae6b20b76868c833df24c Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 21:05:47 -0500 Subject: [PATCH 16/21] Added devicestatus endpoint, devicestatus record type shell with xdripjs record detail. --- swagger.json | 306 +++++++++++++++++++++++++++++++++++++++++++++++++++ swagger.yaml | 222 ++++++++++++++++++++++++++++++++++++- 2 files changed, 526 insertions(+), 2 deletions(-) diff --git a/swagger.json b/swagger.json index 8294da2479a..1f1e478ca9e 100644 --- a/swagger.json +++ b/swagger.json @@ -640,6 +640,175 @@ } } } + }, + "/devicestatus/": { + "get": { + "summary": "All Devicestatuses matching query", + "description": "The Devicestatus endpoint returns information about the Nightscout devicestatus records.", + "parameters": [ + { + "name": "find", + "in": "query", + "description": "The query used to find entries, support nested query syntax, for example `find[dateString][$gte]=2015-08-27`. All find parameters are interpreted as strings.", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "Number of devicestatus records to return.", + "required": false, + "schema": { + "type": "number" + } + } + ], + "tags": [ + "Devicestatus" + ], + "responses": { + "200": { + "description": "An array of devicestatus entries", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Devicestatuses" + } + } + } + }, + "default": { + "description": "Unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "post": { + "tags": [ + "Devicestatus" + ], + "summary": "Add new devicestatus records.", + "description": "", + "operationId": "addDevicestatuses", + "responses": { + "200": { + "description": "Rejected list of device statuses. Empty list is success." + }, + "405": { + "description": "Invalid input" + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Devicestatuses" + } + } + }, + "description": "Device statuses to be uploaded.", + "required": true + } + }, + "delete": { + "summary": "Delete all Devicestatus records matching query", + "description": "The Devicestatus endpoint returns information about the\nNightscout devicestatus records.\n", + "parameters": [ + { + "name": "find", + "in": "query", + "description": "The query used to find entries, support nested query syntax, for\nexample `find[created_at][$gte]=2015-08-27`. All find parameters\nare interpreted as strings.\n", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "count", + "in": "query", + "description": "Number of records to return.", + "required": false, + "schema": { + "type": "number" + } + } + ], + "tags": [ + "Devicestatus" + ], + "responses": { + "200": { + "description": "An array of devicestatus records", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Devicestatuses" + } + } + } + }, + "default": { + "description": "Devicestatuses", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Entries" + } + } + } + } + } + } + }, + "/devicestatus/{spec}": { + "delete": { + "summary": "Delete devicestatus record with id provided in spec", + "description": "The Devicestatus endpoint returns information about the\nNightscout devicestatus records.\n", + "parameters": [ + { + "name": "spec", + "in": "path", + "description": "entry id, such as `55cf81bc436037528ec75fa5`\n", + "required": true, + "schema": { + "type": "string" + } + } + ], + "tags": [ + "Devicestatus" + ], + "responses": { + "200": { + "description": "An array of devicestatus records", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Devicestatuses" + } + } + } + }, + "default": { + "description": "Devicestatuses", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Devicestatuses" + } + } + } + } + } + } } }, "components": { @@ -710,6 +879,143 @@ "$ref": "#/components/schemas/Entry" } }, + "Devicestatus": { + "required": [ + "device", + "created_at" + ], + "properties": { + "device": { + "type": "string", + "description": "Device type and hostname for example openaps://hostname" + }, + "created_at": { + "type": "string", + "description": "dateString, prefer ISO `8601`" + }, + "openaps": { + "type": "string", + "description": "OpenAPS devicestatus record" + }, + "loop": { + "type": "string", + "description": "Loop devicestatus record" + }, + "xdripjs": { + "$ref": "#/components/schemas/xdripjs" + } + } + }, + "Devicestatuses": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Devicestatus" + } + }, + "xdripjs": { + "properties": { + "state": { + "type": "number", + "description": "CGM Sensor Session State Code" + }, + "stateString": { + "type": "string", + "description": "CGM Sensor Session State String" + }, + "stateStringShort": { + "type": "string", + "description": "CGM Sensor Session State Short String" + }, + "txId": { + "type": "string", + "description": "CGM Transmitter ID" + }, + "txStatus": { + "type": "number", + "description": "CGM Transmitter Status" + }, + "txStatusString": { + "type": "string", + "description": "CGM Transmitter Status String" + }, + "txStatusStringShort": { + "type": "string", + "description": "CGM Transmitter Status Short String" + }, + "txActivation": { + "type": "number", + "description": "CGM Transmitter Activation Milliseconds After Epoch" + }, + "mode": { + "type": "string", + "description": "Mode xdrip-js Application Operationg: expired, not expired, etc." + }, + "timestamp": { + "type": "number", + "description": "Last Update Milliseconds After Epoch" + }, + "rssi": { + "type": "number", + "description": "Receive Signal Strength of Transmitter" + }, + "unfiltered": { + "type": "number", + "description": "Most Recent Raw Unfiltered Glucose" + }, + "filtered": { + "type": "number", + "description": "Most Recent Raw Filtered Glucose" + }, + "noise": { + "type": "number", + "description": "Calculated Noise Value - 1=Clean, 2=Light, 3=Medium, 4=Heavy" + }, + "noiseString": { + "type": "number", + "description": "Noise Value String" + }, + "slope": { + "type": "number", + "description": "Calibration Slope Value" + }, + "intercept": { + "type": "number", + "description": "Calibration Intercept Value" + }, + "calType": { + "type": "string", + "description": "Algorithm Used to Calculate Calibration Values" + }, + "lastCalibrationDate": { + "type": "number", + "description": "Most Recent Calibration Milliseconds After Epoch" + }, + "sessionStart": { + "type": "number", + "description": "Sensor Session Start Milliseconds After Epoch" + }, + "batteryTimestamp": { + "type": "number", + "description": "Most Recent Batter Status Read Milliseconds After Epoch" + }, + "voltagea": { + "type": "number", + "description": "Voltage of Battery A" + }, + "voltageb": { + "type": "number", + "description": "Voltage of Battery B" + }, + "temperature": { + "type": "number", + "description": "Transmitter Temperature" + }, + "resistance": { + "type": "number", + "description": "Sensor Resistance" + } + } + }, "Treatment": { "properties": { "_id": { diff --git a/swagger.yaml b/swagger.yaml index fea7b3be7fa..80c24b303ad 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -484,6 +484,124 @@ paths: application/json: schema: $ref: '#/components/schemas/Error' + '/devicestatus/': + get: + summary: All Devicestatuses matching query + description: The Devicestatus endpoint returns information about the Nightscout devicestatus records. + parameters: + - name: find + in: query + description: >- + The query used to find entries, support nested query syntax, for + example `find[dateString][$gte]=2015-08-27`. All find parameters + are interpreted as strings. + required: false + schema: + type: string + - name: count + in: query + description: Number of devicestatus records to return. + required: false + schema: + type: number + tags: + - Devicestatus + responses: + '200': + description: An array of devicestatus entries + content: + application/json: + schema: + $ref: '#/components/schemas/Devicestatuses' + default: + description: Unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + post: + tags: + - Devicestatus + summary: Add new devicestatus records. + description: '' + operationId: addDevicestatuses + responses: + '200': + description: Rejected list of device statuses. Empty list is success. + '405': + description: Invalid input + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Devicestatuses' + description: Device statuses to be uploaded. + required: true + delete: + summary: Delete all Devicestatus records matching query + description: | + The Devicestatus endpoint returns information about the + Nightscout devicestatus records. + parameters: + - name: find + in: query + description: | + The query used to find entries, support nested query syntax, for + example `find[created_at][$gte]=2015-08-27`. All find parameters + are interpreted as strings. + required: false + schema: + type: string + - name: count + in: query + description: Number of records to return. + required: false + schema: + type: number + tags: + - Devicestatus + responses: + '200': + description: An array of devicestatus records + content: + application/json: + schema: + $ref: '#/components/schemas/Devicestatuses' + default: + description: Devicestatuses + content: + application/json: + schema: + $ref: '#/components/schemas/Entries' + '/devicestatus/{spec}': + delete: + summary: Delete devicestatus record with id provided in spec + description: | + The Devicestatus endpoint returns information about the + Nightscout devicestatus records. + parameters: + - name: spec + in: path + description: | + entry id, such as `55cf81bc436037528ec75fa5` + required: true + schema: + type: string + tags: + - Devicestatus + responses: + '200': + description: An array of devicestatus records + content: + application/json: + schema: + $ref: '#/components/schemas/Devicestatuses' + default: + description: Devicestatuses + content: + application/json: + schema: + $ref: '#/components/schemas/Devicestatuses' components: securitySchemes: api_secret: @@ -495,7 +613,9 @@ components: type: apiKey name: token in: query - description: Add token as query item in the URL. You can manage access Token in `/admin`. This uses json webtokens. + description: >- + Add token as query item in the URL. You can manage access Token in + `/admin`. This uses json webtokens. jwtoken: type: http scheme: bearer @@ -543,6 +663,104 @@ components: type: array items: $ref: '#/components/schemas/Entry' + Devicestatus: + required: ['device', 'created_at'] + properties: + device: + type: string + description: 'Device type and hostname for example openaps://hostname' + created_at: + type: string + description: 'dateString, prefer ISO `8601`' + openaps: + type: string + description: 'OpenAPS devicestatus record' + loop: + type: string + description: 'Loop devicestatus record' + xdripjs: + $ref: '#/components/schemas/xdripjs' + Devicestatuses: + type: array + items: + $ref: '#/components/schemas/Devicestatus' + xdripjs: + properties: + state: + type: number + description: 'CGM Sensor Session State Code' + stateString: + type: string + description: 'CGM Sensor Session State String' + stateStringShort: + type: string + description: 'CGM Sensor Session State Short String' + txId: + type: string + description: 'CGM Transmitter ID' + txStatus: + type: number + description: 'CGM Transmitter Status' + txStatusString: + type: string + description: 'CGM Transmitter Status String' + txStatusStringShort: + type: string + description: 'CGM Transmitter Status Short String' + txActivation: + type: number + description: 'CGM Transmitter Activation Milliseconds After Epoch' + mode: + type: string + description: 'Mode xdrip-js Application Operationg: expired, not expired, etc.' + timestamp: + type: number + description: 'Last Update Milliseconds After Epoch' + rssi: + type: number + description: 'Receive Signal Strength of Transmitter' + unfiltered: + type: number + description: 'Most Recent Raw Unfiltered Glucose' + filtered: + type: number + description: 'Most Recent Raw Filtered Glucose' + noise: + type: number + description: 'Calculated Noise Value - 1=Clean, 2=Light, 3=Medium, 4=Heavy' + noiseString: + type: number + description: 'Noise Value String' + slope: + type: number + description: 'Calibration Slope Value' + intercept: + type: number + description: 'Calibration Intercept Value' + calType: + type: string + description: 'Algorithm Used to Calculate Calibration Values' + lastCalibrationDate: + type: number + description: 'Most Recent Calibration Milliseconds After Epoch' + sessionStart: + type: number + description: 'Sensor Session Start Milliseconds After Epoch' + batteryTimestamp: + type: number + description: 'Most Recent Batter Status Read Milliseconds After Epoch' + voltagea: + type: number + description: 'Voltage of Battery A' + voltageb: + type: number + description: 'Voltage of Battery B' + temperature: + type: number + description: 'Transmitter Temperature' + resistance: + type: number + description: 'Sensor Resistance' Treatment: properties: _id: @@ -723,4 +941,4 @@ components: message: type: string fields: - type: object \ No newline at end of file + type: object From e433e293e4f3c70fe2dde2fb2198339b7f6db120 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 21:16:29 -0500 Subject: [PATCH 17/21] Added TODO for OpenAPS and Loop devicestatus records. --- swagger.json | 6 +++--- swagger.yaml | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/swagger.json b/swagger.json index 1f1e478ca9e..37d3a732af5 100644 --- a/swagger.json +++ b/swagger.json @@ -895,11 +895,11 @@ }, "openaps": { "type": "string", - "description": "OpenAPS devicestatus record" + "description": "OpenAPS devicestatus record - TODO: Fill In Details" }, "loop": { "type": "string", - "description": "Loop devicestatus record" + "description": "Loop devicestatus record - TODO: Fill In Details" }, "xdripjs": { "$ref": "#/components/schemas/xdripjs" @@ -1255,4 +1255,4 @@ } } } -} \ No newline at end of file +} diff --git a/swagger.yaml b/swagger.yaml index 80c24b303ad..7e13d78585f 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -674,10 +674,10 @@ components: description: 'dateString, prefer ISO `8601`' openaps: type: string - description: 'OpenAPS devicestatus record' + description: 'OpenAPS devicestatus record - TODO: Fill In Details' loop: type: string - description: 'Loop devicestatus record' + description: 'Loop devicestatus record - TODO: Fill In Details' xdripjs: $ref: '#/components/schemas/xdripjs' Devicestatuses: From 71ed718603996e62f4d73c436ade00d9712e74f0 Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Thu, 9 Aug 2018 21:34:24 -0500 Subject: [PATCH 18/21] Added pump and uploader records. --- swagger.json | 74 +++++++++++++++++++++++++++++++++++++++++++++++++--- swagger.yaml | 50 +++++++++++++++++++++++++++++++++-- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/swagger.json b/swagger.json index 37d3a732af5..b567ba0a9f9 100644 --- a/swagger.json +++ b/swagger.json @@ -895,11 +895,17 @@ }, "openaps": { "type": "string", - "description": "OpenAPS devicestatus record - TODO: Fill In Details" + "description": "OpenAPS devicestatus record - TODO: Fill Out Details" }, "loop": { "type": "string", - "description": "Loop devicestatus record - TODO: Fill In Details" + "description": "Loop devicestatus record - TODO: Fill Out Details" + }, + "pump": { + "$ref": "#/components/schemas/pump" + }, + "uploader": { + "$ref": "#/components/schemas/uploader" }, "xdripjs": { "$ref": "#/components/schemas/xdripjs" @@ -912,6 +918,68 @@ "$ref": "#/components/schemas/Devicestatus" } }, + "pump": { + "properties": { + "clock": { + "type": "string", + "description": "dateString, prefer ISO `8601`" + }, + "battery": { + "$ref": "#/components/schemas/pumpbattery" + }, + "reservoir": { + "type": "number", + "description": "Amount of insulin remaining in pump reservoir" + }, + "status": { + "$ref": "#/components/schemas/pumpstatus" + } + } + }, + "pumpbattery": { + "properties": { + "status": { + "type": "string", + "description": "Pump Battery Status String" + }, + "voltage": { + "type": "number", + "description": "Pump Battery Voltage Level" + } + } + }, + "pumpstatus": { + "properties": { + "status": { + "type": "string", + "description": "Pump Status String" + }, + "bolusing": { + "type": "boolean", + "description": "Is Pump Bolusing" + }, + "suspended": { + "type": "boolean", + "description": "Is Pump Suspended" + }, + "timestamp": { + "type": "string", + "description": "dateString, prefer ISO `8601`" + } + } + }, + "uploader": { + "properties": { + "batteryVoltage": { + "type": "number", + "description": "Uploader Device Battery Voltage" + }, + "battery": { + "type": "number", + "description": "Uploader Device Battery Percentage Charge Remaining" + } + } + }, "xdripjs": { "properties": { "state": { @@ -1255,4 +1323,4 @@ } } } -} +} \ No newline at end of file diff --git a/swagger.yaml b/swagger.yaml index 7e13d78585f..522ba5650fc 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -674,16 +674,62 @@ components: description: 'dateString, prefer ISO `8601`' openaps: type: string - description: 'OpenAPS devicestatus record - TODO: Fill In Details' + description: 'OpenAPS devicestatus record - TODO: Fill Out Details' loop: type: string - description: 'Loop devicestatus record - TODO: Fill In Details' + description: 'Loop devicestatus record - TODO: Fill Out Details' + pump: + $ref: '#/components/schemas/pump' + uploader: + $ref: '#/components/schemas/uploader' xdripjs: $ref: '#/components/schemas/xdripjs' Devicestatuses: type: array items: $ref: '#/components/schemas/Devicestatus' + pump: + properties: + clock: + type: string + description: 'dateString, prefer ISO `8601`' + battery: + $ref: '#/components/schemas/pumpbattery' + reservoir: + type: number + description: 'Amount of insulin remaining in pump reservoir' + status: + $ref: '#/components/schemas/pumpstatus' + pumpbattery: + properties: + status: + type: string + description: 'Pump Battery Status String' + voltage: + type: number + description: 'Pump Battery Voltage Level' + pumpstatus: + properties: + status: + type: string + description: 'Pump Status String' + bolusing: + type: boolean + description: 'Is Pump Bolusing' + suspended: + type: boolean + description: 'Is Pump Suspended' + timestamp: + type: string + description: 'dateString, prefer ISO `8601`' + uploader: + properties: + batteryVoltage: + type: number + description: 'Uploader Device Battery Voltage' + battery: + type: number + description: 'Uploader Device Battery Percentage Charge Remaining' xdripjs: properties: state: From 4405ba884685c3f8e5ee96a32d023ebbbc33395b Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Sat, 25 Aug 2018 09:40:25 -0500 Subject: [PATCH 19/21] Remove max days to keep limit in devicestatus delete. Remove unused count query option in devicestatus delete api. (cherry picked from commit 3101a8d7d054df469071f78bba18a8295dc34404) --- lib/admin_plugins/cleanstatusdb.js | 4 ++-- lib/api/devicestatus/index.js | 3 --- swagger.json | 9 --------- swagger.yaml | 6 ------ 4 files changed, 2 insertions(+), 20 deletions(-) mode change 100644 => 100755 swagger.json mode change 100644 => 100755 swagger.yaml diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index 52a7de026ba..4648b2b90eb 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -85,7 +85,7 @@ cleanstatusdb.actions[1].init = function init(client, callback) { var numDays = '
' + ''; $('#admin_' + cleanstatusdb.name + '_1_html').html(numDays); @@ -98,7 +98,7 @@ cleanstatusdb.actions[1].code = function deleteOldRecords(client, callback) { var $status = $('#admin_' + cleanstatusdb.name + '_1_status'); var numDays = Number($('#admin_devicestatus_days').val()); - if (isNaN(numDays) || (numDays <= 0)) { + if (isNaN(numDays) || (numDays < 1)) { alert(translate('%1 is not a valid number', { params: [$('#admin_devicestatus_days').val()] })); if (callback) { callback(); } return; diff --git a/lib/api/devicestatus/index.js b/lib/api/devicestatus/index.js index 783388ca644..5ea15acf5c3 100644 --- a/lib/api/devicestatus/index.js +++ b/lib/api/devicestatus/index.js @@ -58,9 +58,6 @@ function configure (app, wares, ctx) { // delete record that match query api.delete('/devicestatus/', ctx.authorization.isPermitted('api:devicestatus:delete'), function(req, res) { var query = req.query; - if (!query.count) { - query.count = 10 - } console.log('Delete records with query: ', query); diff --git a/swagger.json b/swagger.json old mode 100644 new mode 100755 index b567ba0a9f9..b73229eed23 --- a/swagger.json +++ b/swagger.json @@ -730,15 +730,6 @@ "schema": { "type": "string" } - }, - { - "name": "count", - "in": "query", - "description": "Number of records to return.", - "required": false, - "schema": { - "type": "number" - } } ], "tags": [ diff --git a/swagger.yaml b/swagger.yaml old mode 100644 new mode 100755 index 522ba5650fc..a17648258c7 --- a/swagger.yaml +++ b/swagger.yaml @@ -552,12 +552,6 @@ paths: required: false schema: type: string - - name: count - in: query - description: Number of records to return. - required: false - schema: - type: number tags: - Devicestatus responses: From c0fd25c2b54888a46e9c1bf290dff19599dac0ae Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Sat, 25 Aug 2018 10:13:49 -0500 Subject: [PATCH 20/21] Cleaned up response values for devicestatus delete api. --- swagger.json | 58 ++++++++++++++++++++++++++++++++++++++++++++-------- swagger.yaml | 47 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 89 insertions(+), 16 deletions(-) diff --git a/swagger.json b/swagger.json index b73229eed23..46c11e664f0 100755 --- a/swagger.json +++ b/swagger.json @@ -737,21 +737,21 @@ ], "responses": { "200": { - "description": "An array of devicestatus records", + "description": "A status record of the delete.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Devicestatuses" + "$ref": "#/components/schemas/DeleteStatus" } } } }, "default": { - "description": "Devicestatuses", + "description": "Unexpected error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Entries" + "$ref": "#/components/schemas/Error" } } } @@ -779,21 +779,21 @@ ], "responses": { "200": { - "description": "An array of devicestatus records", + "description": "A status record of the delete.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Devicestatuses" + "$ref": "#/components/schemas/DeleteStatus" } } } }, "default": { - "description": "Devicestatuses", + "description": "Unexpected error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Devicestatuses" + "$ref": "#/components/schemas/Error" } } } @@ -1311,6 +1311,48 @@ "type": "object" } } + }, + "DeleteStatus": { + "properties": { + "n": { + "type": "integer", + "format": "int32", + "description": "Number of records deleted" + }, + "optime": { + "$ref": "#/components/schemas/optime" + }, + "electionId": { + "type": "string", + "description": "Election id of operation" + }, + "ok": { + "type": "integer", + "format": "int32", + "description": "Status of whether delete was successful" + }, + "operationTime": { + "type": "string", + "description": "Time delete operation was executed" + }, + "$clusterTime": { + "type": "string", + "description": "Information about execution time in cluster environment" + } + } + }, + "optime": { + "properties": { + "ts": { + "type": "string", + "description": "Time the operation started" + }, + "t": { + "type": "integer", + "format": "int32", + "description": "Time the operation took to complete" + } + } } } } diff --git a/swagger.yaml b/swagger.yaml index a17648258c7..e330137533b 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -556,17 +556,17 @@ paths: - Devicestatus responses: '200': - description: An array of devicestatus records + description: A status record of the delete. content: application/json: schema: - $ref: '#/components/schemas/Devicestatuses' + $ref: '#/components/schemas/DeleteStatus' default: - description: Devicestatuses + description: Unexpected error content: application/json: schema: - $ref: '#/components/schemas/Entries' + $ref: '#/components/schemas/Error' '/devicestatus/{spec}': delete: summary: Delete devicestatus record with id provided in spec @@ -585,17 +585,17 @@ paths: - Devicestatus responses: '200': - description: An array of devicestatus records + description: A status record of the delete. content: application/json: schema: - $ref: '#/components/schemas/Devicestatuses' + $ref: '#/components/schemas/DeleteStatus' default: - description: Devicestatuses + description: Unexpected error content: application/json: schema: - $ref: '#/components/schemas/Devicestatuses' + $ref: '#/components/schemas/Error' components: securitySchemes: api_secret: @@ -982,3 +982,34 @@ components: type: string fields: type: object + DeleteStatus: + properties: + n: + type: integer + format: int32 + description: 'Number of records deleted' + optime: + $ref: '#/components/schemas/optime' + electionId: + type: string + description: 'Election id of operation' + ok: + type: integer + format: int32 + description: 'Status of whether delete was successful' + operationTime: + type: string + description: 'Time delete operation was executed' + $clusterTime: + type: string + description: 'Information about execution time in cluster environment' + optime: + properties: + ts: + type: string + description: 'Time the operation started' + t: + type: integer + format: int32 + description: 'Time the operation took to complete' + From 15223077fad450edba13eeff9f3db2685b57f10f Mon Sep 17 00:00:00 2001 From: Jeremy Cunningham Date: Sat, 29 Sep 2018 08:36:12 -0500 Subject: [PATCH 21/21] Retain action button for deleting old devicestatus records. --- lib/admin_plugins/cleanstatusdb.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/admin_plugins/cleanstatusdb.js b/lib/admin_plugins/cleanstatusdb.js index 4648b2b90eb..f2014d69b23 100644 --- a/lib/admin_plugins/cleanstatusdb.js +++ b/lib/admin_plugins/cleanstatusdb.js @@ -26,6 +26,7 @@ cleanstatusdb.actions = [ , description: 'This task removes all documents from devicestatus collection that are older than 30 days. Useful when uploader battery status is not properly updated.' , buttonLabel: 'Delete old documents' , confirmText: 'Delete old documents from devicestatus collection?' + , preventClose: true } ];