Skip to content

Commit

Permalink
Offline xdrip (openaps#1248)
Browse files Browse the repository at this point in the history
* Offline xDrip looping

* Add the script to package.json

* Add the glucose value

* Changed the setup json to use the offline script

* Also add the script to ns-loop shell script

* Fix web script trying to access BG data when there's none

* Better error logging

* Output full filename on on parse error

* Ensure JSON parse gets a string, not a stream

* Don't read the file we're outputting to

* Don't read file we're outputting to

* Fix path typo

* Try loading from router, not hardcoded address

* Fix bug resulting from code restructuring

* The apparently rare case where glucose is loaded from Nightscout before a new reading was available out misformatted data

* Better error logging for wrong secret

* Code cleanup

* remove unused ns-glucose report instead of updating it

* remove commented-out Spike stuff

* tabs to sapces

* Remove binary download options (openaps#1252)

* Remove binary download options

* Add radiotags to runagain, and fix bug for radiofruit hardware type

* Use Edison's FAT32 Partition (openaps#1253)

Mount the Edison's FAT32 partition to give us enough room to install golang.

* Radiotags in oref0-runagain.sh (openaps#1254)

Pass radiotags to oref0-setup.sh from oref0-runagain.sh.

* Add network module dependency (openaps#1261)

Fixes issue of `Cannot find module 'network'` in the ns-looplog.

* Debian Buster compatibility  (openaps#1275)

* Save hardwaretype in preferences.json

Store hardwaretype so that it can be used elsewhere.

* Install node v8

Make sure nodesource repo is used to install nodejs and npm.

* Install node v8

Make sure nodesource repo is used to install nodejs and npm, except on armv6...

* Switch Radiofruit openaps-menu back to main repo

* fix systemctl syntax

* skip bgproxy if we already have a new glucose value and it's time for another loop

* checkip.amazonaws.com now puts spaces after commas

* Allow oref0-upload-profile to also switch to new profile (openaps#1285)

* Unused local variables (openaps#1284)

* raspbian password checking adjustment (openaps#1282)

old line 12: the existing logic didn't make sense to me check for edison  but expire root so adjusting to check for root, expire root
old line 16-21: If you changed the password for 'pi' before running the script you'd never get to the part about changing root's password as it's disabled and locked by default and therefore /run/sshwarn will not exist.
new line 16-32: Check if we are running Raspbian, check the build date against the current password date for both pi and root. If they are the same, we are using default passwords and prompt for change. Checking them independently and only information message once.

* fix wrong interface choose (openaps#1286)

By default, choose the first interface found with a control socket in the socket path.

* fix bootstrap to put tune-dia-and-peak argument on openaps-install, not the curl

* Allow G4 Share serial to be blank (openaps#1268)

* Categorize improvements for libre 1 minute data (openaps#1238)

* Work in progress on categorize

  * Determine date & dateString properties in prepGlucose map function
  * Filter invalid records in filterRecords filter function
  * Clean up for loop to remove previously performed checks
  * Average any values that fall within the 2 minute deadband

* Increase limit to allow for 1 minute data

  * Ensure 1440 (60*24) records can be downloaded

* refactoring: round_basal (openaps#1294)

- parametrized mocha test

* Improved rounding of mmol/L units in oref0-upload-profile (openaps#1295)

* Round ISF properly in oref0-upload-profile with mmol/L units

* Round BG targets properly in oref0-upload-profile with mmol/L units

* Add explanations for unit conversion code

* Reestablish bluetooth connection after failure to set bluetooth hci name (openaps#1291)

* Reset bluetooth adapter if fail to set bluetooth hci name

* Check to make sure oref0-bluetoothup not already running

* Stop bluetoothd and allow next cycle to handle restart

* per openaps#1288, only use minZTUAMPredBG if enableUAM, and use minGuardBG otherwise (openaps#1292)

* run oref0-set-system-clock after oref0-set-device-clocks in case rig is offline (openaps#1290)

* run oref0-set-system-clock if oref0-set-device-clocks fails

* remove output redirection for debugging

* run oref0-set-system-clock regardless of return code from oref0-set-device-clocks

* fix tabs that should be spaces

* Fix case mismatch that causes values in mg/dl to be multiplied by 18 (openaps#1296)

* Add checks to make sure variables are defined. (openaps#1297)

* Update bin/all-autosens-history.sh

Add 2019

Co-Authored-By: viq <[email protected]>

* lodash 4.17.15 per npm audit fix

* Have autotune sync to NS nightly after autotune runs (openaps#1098)

* Have autotune sync to NS nightly after autotune runs

This will keep Nightscout in sync with autotune after the nightly run.

* always round insulin to carb ratios to 0.1g

* round basal rates to 0.01 U/h, not 0.001

* sleep 60s to generate a new profile.json

* Standalone MRAA installer for OpenAPS v0.7.0 (openaps#1302)

* Standalone MRAA installer for OpenAPS v0.7.0

Addresses openaps#1270

* Add oref0-mraa-install to package.json

* Unused local variables (openaps#1301)

* Unused local variables

* Unused local variables

* Upload preferences.json and oref0 version to devicestatus (openaps#1300)

* per openaps#1288, only use minZTUAMPredBG if enableUAM, and use minGuardBG otherwise

* upload preferences.json to devicestatus

* use --preferences instead of positional arguments

* yargs entry for --preferences

* upload oref0 package.json version string

* redact sensitive fields in preferences.json

* reduce size of large logfiles like new -date ones

* remove old commented-out code

* remove old commented and deprecated code

* Refactor enable smb in determine-basal.js (openaps#1299)

* Move the enable SMB into its own dedicated function

This will allow easier SMB conditional implementations

* Forgot to remove the existing logic...

* fix function naming

* function fix round 2

* don't let  kill the script if oref0 already exists

* Travis CI: Upgrade to Python 3.8 and add more flake8 tests (openaps#1304)

* Non-breaking space (openaps#1305)

* Non-breaking space detected by eslint

* Detect socket timeout and don't log stack trace

* whitespace

* Add  ECONNREFUSED to safe error list, better error message

* Reduced logging (openaps#1309)

* Detect socket timeout and don't log stack trace

* Add  ECONNREFUSED to safe error list, better error message

* Consolidate IP logging to same line as xDrip load notification, remove unused variables

* Disabled xDrip logging after first error

* expand one-line json to properly count glucose entries
  • Loading branch information
scottleibrand authored Oct 29, 2019
1 parent 7396534 commit ae17b9d
Show file tree
Hide file tree
Showing 6 changed files with 228 additions and 49 deletions.
206 changes: 206 additions & 0 deletions bin/oref0-get-ns-entries.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#!/usr/bin/env node

/*
oref0 Nightscout treatment fetch tool
Collects latest treatment data from Nightscout, with support for sending the
If-Modified-Since header and not outputting the report file on 304 Not Modified
response.
Released under MIT license. See the accompanying LICENSE.txt file for
full terms and conditions
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

var crypto = require('crypto');
var request = require('request');
var _ = require('lodash');
var fs = require('fs');
var network = require('network');

var safe_errors = ['ECONNREFUSED', 'ESOCKETTIMEDOUT', 'ETIMEDOUT'];
var log_errors = true;

if (!module.parent) {

var argv = require('yargs')
.usage("$0 ns-glucose.json NSURL API-SECRET <hours>")
.strict(true)
.help('help');

function usage() {
argv.showHelp();
}

var params = argv.argv;
var glucose_input = params._.slice(0, 1).pop();

if ([null, '--help', '-h', 'help'].indexOf(glucose_input) > 0) {
usage();
process.exit(0);
}

var nsurl = params._.slice(1, 2).pop();
if (nsurl && nsurl.charAt(nsurl.length - 1) == "/") nsurl = nsurl.substr(0, nsurl.length - 1); // remove trailing slash if it exists

var apisecret = params._.slice(2, 3).pop();
var hours = Number(params._.slice(3, 4).pop());
var records = 1000;

if (hours > 0) {
records = 12 * hours;
}

if (!glucose_input || !nsurl || !apisecret) {
usage();
process.exit(1);
}

if (apisecret.length != 40) {
var shasum = crypto.createHash('sha1');
shasum.update(apisecret);
apisecret = shasum.digest('hex');
}

var cwd = process.cwd();
var outputPath = cwd + '/' + glucose_input;

function loadFromxDrip(callback, ip) {
var headers = {
'api-secret': apisecret
};

var uri = 'http://' + ip + ':17580/sgv.json?count=' + records; // 192.168.43.1

var options = {
uri: uri
, json: true
, timeout: 10000
, headers: headers
};

if (log_errors) console.error('Connected to ' + ip +', testing for xDrip API availability');

request(options, function(error, res, data) {
var failed = false;
if (res && res.statusCode == 403) {
console.error("Load from xDrip failed: API_SECRET didn't match");
failed = true;
}

if (error) {
if (safe_errors.includes(error.code)) {
if (log_errors) console.error('Load from local xDrip timed out, likely not connected to xDrip hotspot');
log_errors = false;
} else {
if (log_errors) console.error("Load from xDrip failed", error);
log_errors = false;
failed = true;
}

failed = true;
}

if (!failed && data) {
console.error("CGM results loaded from xDrip");
processAndOutput(data);
return true;
}

if (failed && callback) callback();
});

return false;
}

var nsCallback = function loadFromNightscout() {
// try Nightscout

var lastDate;
var glucosedata;

fs.readFile(outputPath, 'utf8', function(err, fileContent) {

if (err) {
console.error(err);
} else {
try {
glucosedata = JSON.parse(fileContent);

if (glucosedata.constructor == Array) { //{ throw "Glucose data file doesn't seem to be valid"; }
_.forEach(glucosedata, function findLatest(sgvrecord) {
var d = new Date(sgvrecord.dateString);
if (!lastDate || lastDate < d) {
lastDate = d;
}
});
} else {
glucosedata = null;
}
} catch (e) {
console.error(e);
}
}
loadFromNightscoutWithDate(lastDate, glucosedata);
});
}

function loadFromNightscoutWithDate(lastDate, glucosedata) {

var headers = {
'api-secret': apisecret
};

if (!_.isNil(lastDate)) {
headers["If-Modified-Since"] = lastDate.toISOString();
}

var uri = nsurl + '/api/v1/entries/sgv.json?count=' + records;
var options = {
uri: uri
, json: true
, headers: headers
};

request(options, function(error, res, data) {
if (res && (res.statusCode == 200 || res.statusCode == 304)) {

if (data) {
console.error("Got CGM results from Nightscout");
processAndOutput(data);
} else {
console.error("Got Not Changed response from Nightscout, assuming no new data is available");
// output old file
if (!_.isNil(glucosedata)) {
console.log(JSON.stringify(glucosedata));
}
}
} else {
console.error("Loading CGM data from Nightscout failed", error);
}
});

}

function processAndOutput(glucosedata) {

_.forEach(glucosedata, function findLatest(sgvrecord) {
sgvrecord.glucose = sgvrecord.sgv;
});

console.log(JSON.stringify(glucosedata));
}

network.get_gateway_ip(function(err, ip) {
loadFromxDrip(nsCallback, ip);
});

}
12 changes: 8 additions & 4 deletions bin/oref0-ns-loop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,17 @@ function pushover_snooze {


function get_ns_bg {
#openaps get-ns-glucose > /dev/null
# update 24h glucose file if it's 55m old or too small to calculate COB
if ! file_is_recent cgm/ns-glucose-24h.json 54 \
|| ! grep -c glucose cgm/ns-glucose-24h.json | jq -e '. > 36' >/dev/null; then
nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -24hours > cgm/ns-glucose-24h.json
|| ! jq . cgm/ns-glucose-24h.json | grep -c glucose | jq -e '. > 36' >/dev/null; then
#nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -24hours > cgm/ns-glucose-24h.json
cp cgm/ns-glucose-24h.json cgm/ns-glucose-24h-temp.json
oref0-get-ns-entries cgm/ns-glucose-24h-temp.json $NIGHTSCOUT_HOST $API_SECRET 24 2>&1 >cgm/ns-glucose-24h.json
fi
nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -1hour > cgm/ns-glucose-1h.json
#nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -1hour > cgm/ns-glucose-1h.json
cp cgm/ns-glucose-1h.json cgm/ns-glucose-1h-temp.json
oref0-get-ns-entries cgm/ns-glucose-1h-temp.json $NIGHTSCOUT_HOST $API_SECRET 1 2>&1 >cgm/ns-glucose-1h.json

jq -s '.[0] + .[1]|unique|sort_by(.date)|reverse' cgm/ns-glucose-24h.json cgm/ns-glucose-1h.json > cgm/ns-glucose.json
glucose_fresh # update timestamp on cgm/ns-glucose.json
# if ns-glucose.json data is <10m old, no more than 5m in the future, and valid (>38),
Expand Down
13 changes: 0 additions & 13 deletions lib/oref0-setup/device.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,6 @@
"name": "cgm",
"extra": {}
},
{
"ns-glucose": {
"vendor": "openaps.vendors.process",
"extra": "ns-glucose.ini"
},
"type": "device",
"name": "ns-glucose",
"extra": {
"fields": "",
"cmd": "bash -c \"curl --compressed -m 30 -s $NIGHTSCOUT_HOST/api/v1/entries/sgv.json?count=1000 | json -e \\\"this.glucose = this.sgv\\\"\"",
"args": ""
}
},
{
"extra": {
"fields": "",
Expand Down
22 changes: 0 additions & 22 deletions lib/oref0-setup/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,6 @@
},
"name": "monitor/carbhistory.json"
},
{
"type": "report",
"name": "monitor/cgm-glucose.json",
"monitor/cgm-glucose.json": {
"hours": "25.0",
"device": "cgm",
"use": "iter_glucose_hours",
"reporter": "JSON"
}
},
{
"type": "report",
"name": "raw-cgm/raw-entries.json",
Expand All @@ -52,18 +42,6 @@
"glucose": ""
}
},
{
"cgm/ns-glucose.json": {
"oper": "oref0_glucose_since",
"use": "shell",
"reporter": "JSON",
"device": "ns",
"remainder": "-24hours",
"json_default": "True"
},
"type": "report",
"name": "cgm/ns-glucose.json"
},
{
"type": "report",
"monitor/mmtune.json": {
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"oref0-upload-entries": "./bin/oref0-upload-entries.sh",
"oref0-upload-profile": "./bin/oref0-upload-profile.js",
"oref0-version": "./bin/oref0-version.sh",
"oref0-get-ns-entries": "./bin/oref0-get-ns-entries.js",
"peb-urchin-status": "./bin/peb-urchin-status.sh",
"wifi": "./bin/oref0-tail-wifi.sh"
},
Expand All @@ -99,6 +100,7 @@
"lodash": "^4.17.15",
"moment": "^2.24.0",
"moment-timezone": "0.5.23",
"network": "^0.4.1",
"request": "^2.88.0",
"share2nightscout-bridge": "^0.2.1",
"yargs": "^13.2.2"
Expand Down
22 changes: 12 additions & 10 deletions www/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@

function loadBasalBolus(param) {
var i_bg = 0 ;
var bg = 0;
var bg = 100;
$.ajax({
url: "pumphistory",
async: false,
Expand Down Expand Up @@ -513,15 +513,17 @@
} else if ( data[i]._type == 'Bolus' ) {
if ( date1 >= param.minDate ) {
if (parseFloat(data[i].amount) > param.maxBolus) { param.maxBolus = parseFloat(data[i].amount);}
while (i_bg <= param.data.bg.length-1 && param.data.bg[i_bg].t > date1 ) {
i_bg++ ;
}
if ( i_bg == 0 ) {
bg = param.data.bg[i_bg].y;
} else if ( i_bg == param.data.bg.length) {
bg = param.data.bg[i_bg-1].y ;
} else {
bg = ( param.data.bg[i_bg].y + param.data.bg[i_bg-1].y ) / 2;
if (param.data.bg.length > 0) {
while (i_bg <= param.data.bg.length-1 && param.data.bg[i_bg].t > date1 ) {
i_bg++ ;
}
if ( i_bg == 0 ) {
bg = param.data.bg[i_bg].y;
} else if ( i_bg == param.data.bg.length) {
bg = param.data.bg[i_bg-1].y ;
} else {
bg = ( param.data.bg[i_bg].y + param.data.bg[i_bg-1].y ) / 2;
}
}
param.data.bolusBG[param.data.bolusBG.length] = {t:date1,y:bg,label:data[i].amount.toString().replace(/^0+/, '')};
var date3 = new Date(date1.getTime()-60000)
Expand Down

0 comments on commit ae17b9d

Please sign in to comment.