Skip to content

Commit ae17b9d

Browse files
Offline xdrip (#1248)
* 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 (#1252) * Remove binary download options * Add radiotags to runagain, and fix bug for radiofruit hardware type * Use Edison's FAT32 Partition (#1253) Mount the Edison's FAT32 partition to give us enough room to install golang. * Radiotags in oref0-runagain.sh (#1254) Pass radiotags to oref0-setup.sh from oref0-runagain.sh. * Add network module dependency (#1261) Fixes issue of `Cannot find module 'network'` in the ns-looplog. * Debian Buster compatibility (#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 (#1285) * Unused local variables (#1284) * raspbian password checking adjustment (#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 (#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 (#1268) * Categorize improvements for libre 1 minute data (#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 (#1294) - parametrized mocha test * Improved rounding of mmol/L units in oref0-upload-profile (#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 (#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 #1288, only use minZTUAMPredBG if enableUAM, and use minGuardBG otherwise (#1292) * run oref0-set-system-clock after oref0-set-device-clocks in case rig is offline (#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 (#1296) * Add checks to make sure variables are defined. (#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 (#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 (#1302) * Standalone MRAA installer for OpenAPS v0.7.0 Addresses #1270 * Add oref0-mraa-install to package.json * Unused local variables (#1301) * Unused local variables * Unused local variables * Upload preferences.json and oref0 version to devicestatus (#1300) * per #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 (#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 (#1304) * Non-breaking space (#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 (#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
1 parent 7396534 commit ae17b9d

File tree

6 files changed

+228
-49
lines changed

6 files changed

+228
-49
lines changed

bin/oref0-get-ns-entries.js

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
#!/usr/bin/env node
2+
3+
/*
4+
oref0 Nightscout treatment fetch tool
5+
6+
Collects latest treatment data from Nightscout, with support for sending the
7+
If-Modified-Since header and not outputting the report file on 304 Not Modified
8+
response.
9+
10+
Released under MIT license. See the accompanying LICENSE.txt file for
11+
full terms and conditions
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
20+
21+
*/
22+
23+
var crypto = require('crypto');
24+
var request = require('request');
25+
var _ = require('lodash');
26+
var fs = require('fs');
27+
var network = require('network');
28+
29+
var safe_errors = ['ECONNREFUSED', 'ESOCKETTIMEDOUT', 'ETIMEDOUT'];
30+
var log_errors = true;
31+
32+
if (!module.parent) {
33+
34+
var argv = require('yargs')
35+
.usage("$0 ns-glucose.json NSURL API-SECRET <hours>")
36+
.strict(true)
37+
.help('help');
38+
39+
function usage() {
40+
argv.showHelp();
41+
}
42+
43+
var params = argv.argv;
44+
var glucose_input = params._.slice(0, 1).pop();
45+
46+
if ([null, '--help', '-h', 'help'].indexOf(glucose_input) > 0) {
47+
usage();
48+
process.exit(0);
49+
}
50+
51+
var nsurl = params._.slice(1, 2).pop();
52+
if (nsurl && nsurl.charAt(nsurl.length - 1) == "/") nsurl = nsurl.substr(0, nsurl.length - 1); // remove trailing slash if it exists
53+
54+
var apisecret = params._.slice(2, 3).pop();
55+
var hours = Number(params._.slice(3, 4).pop());
56+
var records = 1000;
57+
58+
if (hours > 0) {
59+
records = 12 * hours;
60+
}
61+
62+
if (!glucose_input || !nsurl || !apisecret) {
63+
usage();
64+
process.exit(1);
65+
}
66+
67+
if (apisecret.length != 40) {
68+
var shasum = crypto.createHash('sha1');
69+
shasum.update(apisecret);
70+
apisecret = shasum.digest('hex');
71+
}
72+
73+
var cwd = process.cwd();
74+
var outputPath = cwd + '/' + glucose_input;
75+
76+
function loadFromxDrip(callback, ip) {
77+
var headers = {
78+
'api-secret': apisecret
79+
};
80+
81+
var uri = 'http://' + ip + ':17580/sgv.json?count=' + records; // 192.168.43.1
82+
83+
var options = {
84+
uri: uri
85+
, json: true
86+
, timeout: 10000
87+
, headers: headers
88+
};
89+
90+
if (log_errors) console.error('Connected to ' + ip +', testing for xDrip API availability');
91+
92+
request(options, function(error, res, data) {
93+
var failed = false;
94+
if (res && res.statusCode == 403) {
95+
console.error("Load from xDrip failed: API_SECRET didn't match");
96+
failed = true;
97+
}
98+
99+
if (error) {
100+
if (safe_errors.includes(error.code)) {
101+
if (log_errors) console.error('Load from local xDrip timed out, likely not connected to xDrip hotspot');
102+
log_errors = false;
103+
} else {
104+
if (log_errors) console.error("Load from xDrip failed", error);
105+
log_errors = false;
106+
failed = true;
107+
}
108+
109+
failed = true;
110+
}
111+
112+
if (!failed && data) {
113+
console.error("CGM results loaded from xDrip");
114+
processAndOutput(data);
115+
return true;
116+
}
117+
118+
if (failed && callback) callback();
119+
});
120+
121+
return false;
122+
}
123+
124+
var nsCallback = function loadFromNightscout() {
125+
// try Nightscout
126+
127+
var lastDate;
128+
var glucosedata;
129+
130+
fs.readFile(outputPath, 'utf8', function(err, fileContent) {
131+
132+
if (err) {
133+
console.error(err);
134+
} else {
135+
try {
136+
glucosedata = JSON.parse(fileContent);
137+
138+
if (glucosedata.constructor == Array) { //{ throw "Glucose data file doesn't seem to be valid"; }
139+
_.forEach(glucosedata, function findLatest(sgvrecord) {
140+
var d = new Date(sgvrecord.dateString);
141+
if (!lastDate || lastDate < d) {
142+
lastDate = d;
143+
}
144+
});
145+
} else {
146+
glucosedata = null;
147+
}
148+
} catch (e) {
149+
console.error(e);
150+
}
151+
}
152+
loadFromNightscoutWithDate(lastDate, glucosedata);
153+
});
154+
}
155+
156+
function loadFromNightscoutWithDate(lastDate, glucosedata) {
157+
158+
var headers = {
159+
'api-secret': apisecret
160+
};
161+
162+
if (!_.isNil(lastDate)) {
163+
headers["If-Modified-Since"] = lastDate.toISOString();
164+
}
165+
166+
var uri = nsurl + '/api/v1/entries/sgv.json?count=' + records;
167+
var options = {
168+
uri: uri
169+
, json: true
170+
, headers: headers
171+
};
172+
173+
request(options, function(error, res, data) {
174+
if (res && (res.statusCode == 200 || res.statusCode == 304)) {
175+
176+
if (data) {
177+
console.error("Got CGM results from Nightscout");
178+
processAndOutput(data);
179+
} else {
180+
console.error("Got Not Changed response from Nightscout, assuming no new data is available");
181+
// output old file
182+
if (!_.isNil(glucosedata)) {
183+
console.log(JSON.stringify(glucosedata));
184+
}
185+
}
186+
} else {
187+
console.error("Loading CGM data from Nightscout failed", error);
188+
}
189+
});
190+
191+
}
192+
193+
function processAndOutput(glucosedata) {
194+
195+
_.forEach(glucosedata, function findLatest(sgvrecord) {
196+
sgvrecord.glucose = sgvrecord.sgv;
197+
});
198+
199+
console.log(JSON.stringify(glucosedata));
200+
}
201+
202+
network.get_gateway_ip(function(err, ip) {
203+
loadFromxDrip(nsCallback, ip);
204+
});
205+
206+
}

bin/oref0-ns-loop.sh

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,17 @@ function pushover_snooze {
5151

5252

5353
function get_ns_bg {
54-
#openaps get-ns-glucose > /dev/null
5554
# update 24h glucose file if it's 55m old or too small to calculate COB
5655
if ! file_is_recent cgm/ns-glucose-24h.json 54 \
57-
|| ! grep -c glucose cgm/ns-glucose-24h.json | jq -e '. > 36' >/dev/null; then
58-
nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -24hours > cgm/ns-glucose-24h.json
56+
|| ! jq . cgm/ns-glucose-24h.json | grep -c glucose | jq -e '. > 36' >/dev/null; then
57+
#nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -24hours > cgm/ns-glucose-24h.json
58+
cp cgm/ns-glucose-24h.json cgm/ns-glucose-24h-temp.json
59+
oref0-get-ns-entries cgm/ns-glucose-24h-temp.json $NIGHTSCOUT_HOST $API_SECRET 24 2>&1 >cgm/ns-glucose-24h.json
5960
fi
60-
nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -1hour > cgm/ns-glucose-1h.json
61+
#nightscout ns $NIGHTSCOUT_HOST $API_SECRET oref0_glucose_since -1hour > cgm/ns-glucose-1h.json
62+
cp cgm/ns-glucose-1h.json cgm/ns-glucose-1h-temp.json
63+
oref0-get-ns-entries cgm/ns-glucose-1h-temp.json $NIGHTSCOUT_HOST $API_SECRET 1 2>&1 >cgm/ns-glucose-1h.json
64+
6165
jq -s '.[0] + .[1]|unique|sort_by(.date)|reverse' cgm/ns-glucose-24h.json cgm/ns-glucose-1h.json > cgm/ns-glucose.json
6266
glucose_fresh # update timestamp on cgm/ns-glucose.json
6367
# if ns-glucose.json data is <10m old, no more than 5m in the future, and valid (>38),

lib/oref0-setup/device.json

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,6 @@
88
"name": "cgm",
99
"extra": {}
1010
},
11-
{
12-
"ns-glucose": {
13-
"vendor": "openaps.vendors.process",
14-
"extra": "ns-glucose.ini"
15-
},
16-
"type": "device",
17-
"name": "ns-glucose",
18-
"extra": {
19-
"fields": "",
20-
"cmd": "bash -c \"curl --compressed -m 30 -s $NIGHTSCOUT_HOST/api/v1/entries/sgv.json?count=1000 | json -e \\\"this.glucose = this.sgv\\\"\"",
21-
"args": ""
22-
}
23-
},
2411
{
2512
"extra": {
2613
"fields": "",

lib/oref0-setup/report.json

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,6 @@
2323
},
2424
"name": "monitor/carbhistory.json"
2525
},
26-
{
27-
"type": "report",
28-
"name": "monitor/cgm-glucose.json",
29-
"monitor/cgm-glucose.json": {
30-
"hours": "25.0",
31-
"device": "cgm",
32-
"use": "iter_glucose_hours",
33-
"reporter": "JSON"
34-
}
35-
},
3626
{
3727
"type": "report",
3828
"name": "raw-cgm/raw-entries.json",
@@ -52,18 +42,6 @@
5242
"glucose": ""
5343
}
5444
},
55-
{
56-
"cgm/ns-glucose.json": {
57-
"oper": "oref0_glucose_since",
58-
"use": "shell",
59-
"reporter": "JSON",
60-
"device": "ns",
61-
"remainder": "-24hours",
62-
"json_default": "True"
63-
},
64-
"type": "report",
65-
"name": "cgm/ns-glucose.json"
66-
},
6745
{
6846
"type": "report",
6947
"monitor/mmtune.json": {

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"oref0-upload-entries": "./bin/oref0-upload-entries.sh",
9090
"oref0-upload-profile": "./bin/oref0-upload-profile.js",
9191
"oref0-version": "./bin/oref0-version.sh",
92+
"oref0-get-ns-entries": "./bin/oref0-get-ns-entries.js",
9293
"peb-urchin-status": "./bin/peb-urchin-status.sh",
9394
"wifi": "./bin/oref0-tail-wifi.sh"
9495
},
@@ -99,6 +100,7 @@
99100
"lodash": "^4.17.15",
100101
"moment": "^2.24.0",
101102
"moment-timezone": "0.5.23",
103+
"network": "^0.4.1",
102104
"request": "^2.88.0",
103105
"share2nightscout-bridge": "^0.2.1",
104106
"yargs": "^13.2.2"

www/templates/index.html

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@
482482

483483
function loadBasalBolus(param) {
484484
var i_bg = 0 ;
485-
var bg = 0;
485+
var bg = 100;
486486
$.ajax({
487487
url: "pumphistory",
488488
async: false,
@@ -513,15 +513,17 @@
513513
} else if ( data[i]._type == 'Bolus' ) {
514514
if ( date1 >= param.minDate ) {
515515
if (parseFloat(data[i].amount) > param.maxBolus) { param.maxBolus = parseFloat(data[i].amount);}
516-
while (i_bg <= param.data.bg.length-1 && param.data.bg[i_bg].t > date1 ) {
517-
i_bg++ ;
518-
}
519-
if ( i_bg == 0 ) {
520-
bg = param.data.bg[i_bg].y;
521-
} else if ( i_bg == param.data.bg.length) {
522-
bg = param.data.bg[i_bg-1].y ;
523-
} else {
524-
bg = ( param.data.bg[i_bg].y + param.data.bg[i_bg-1].y ) / 2;
516+
if (param.data.bg.length > 0) {
517+
while (i_bg <= param.data.bg.length-1 && param.data.bg[i_bg].t > date1 ) {
518+
i_bg++ ;
519+
}
520+
if ( i_bg == 0 ) {
521+
bg = param.data.bg[i_bg].y;
522+
} else if ( i_bg == param.data.bg.length) {
523+
bg = param.data.bg[i_bg-1].y ;
524+
} else {
525+
bg = ( param.data.bg[i_bg].y + param.data.bg[i_bg-1].y ) / 2;
526+
}
525527
}
526528
param.data.bolusBG[param.data.bolusBG.length] = {t:date1,y:bg,label:data[i].amount.toString().replace(/^0+/, '')};
527529
var date3 = new Date(date1.getTime()-60000)

0 commit comments

Comments
 (0)