diff --git a/.gitignore b/.gitignore index b21a92f7a..4638eb4bc 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,7 @@ coverage/ npm-debug.log bin/__pycache__ + +package-lock.json + +*.pyc diff --git a/bin/ns-get.sh b/bin/ns-get.sh index 7fe272b15..814e587b2 100755 --- a/bin/ns-get.sh +++ b/bin/ns-get.sh @@ -57,7 +57,7 @@ case $1 in fi test -z "$NIGHTSCOUT_HOST" && usage && exit 1; - curl ${CURL_AUTH} ${CURL_FLAGS} $REPORT_ENDPOINT | $NIGHTSCOUT_FORMAT + curl -m 30 ${CURL_AUTH} ${CURL_FLAGS} $REPORT_ENDPOINT | $NIGHTSCOUT_FORMAT ;; type) @@ -69,7 +69,7 @@ case $1 in ;; *) test -z "$NIGHTSCOUT_HOST" && usage && exit 1; - curl ${CURL_AUTH} ${CURL_FLAGS} $REPORT_ENDPOINT | $NIGHTSCOUT_FORMAT + curl -m 30 ${CURL_AUTH} ${CURL_FLAGS} $REPORT_ENDPOINT | $NIGHTSCOUT_FORMAT ;; esac diff --git a/bin/openaps-bootstrap.sh b/bin/openaps-bootstrap.sh old mode 100644 new mode 100755 index d74b513d2..0f4065091 --- a/bin/openaps-bootstrap.sh +++ b/bin/openaps-bootstrap.sh @@ -29,6 +29,6 @@ ifdown wlan0; ifup wlan0 sleep 10 echo -ne "\nWifi SSID: "; iwgetid -r sleep 5 -# TODO check for options to fix the certificate activation error message for https -cd /tmp/; wget --no-check-certificate https://raw.githubusercontent.com/openaps/docs/dev/scripts/openaps-install.sh; bash ./openaps-install.sh +curl https://raw.githubusercontent.com/openaps/oref0/master/bin/openaps-install.sh > /tmp/openaps-install.sh +bash /tmp/openaps-install.sh ) diff --git a/bin/openaps-install.sh b/bin/openaps-install.sh old mode 100644 new mode 100755 index cf890daf6..48778a8fc --- a/bin/openaps-install.sh +++ b/bin/openaps-install.sh @@ -1,15 +1,26 @@ #!/bin/bash set -e -read -p "Enter your Edison's new hostname (this will be your rig's "name" in the future, so make sure to write it down): " -r -myedisonhostname=$REPLY -echo $myedisonhostname > /etc/hostname -sed -r -i"" "s/localhost( jubilinux)?$/localhost $myedisonhostname/" /etc/hosts +read -p "Enter your rig's new hostname (this will be your rig's "name" in the future, so make sure to write it down): " -r +myrighostname=$REPLY +echo $myrighostname > /etc/hostname +sed -r -i"" "s/localhost( jubilinux)?$/localhost $myrighostname/" /etc/hosts +sed -r -i"" "s/127.0.1.1.*$/127.0.1.1 $myrighostname/" /etc/hosts # if passwords are old, force them to be changed at next login -passwd -S edison | grep 20[01][0-6] && passwd -e root +passwd -S edison 2>/dev/null | grep 20[01][0-6] && passwd -e root # automatically expire edison account if its password is not changed in 3 days -passwd -S edison | grep 20[01][0-6] && passwd -e edison -i 3 +passwd -S edison 2>/dev/null | grep 20[01][0-6] && passwd -e edison -i 3 + +if [ -e /run/sshwarn ] ; then + echo Please select a secure password for ssh logins to your rig: + echo 'For the "root" account:' + passwd root + echo 'And for the "pi" account (same password is fine):' + passwd pi +fi + +grep "PermitRootLogin yes" /etc/ssh/sshd_config || echo "PermitRootLogin yes" > /etc/ssh/sshd_config # set timezone dpkg-reconfigure tzdata @@ -17,15 +28,23 @@ dpkg-reconfigure tzdata #dpkg -P nodejs nodejs-dev # TODO: remove the `-o Acquire::ForceIPv4=true` once Debian's mirrors work reliably over IPv6 apt-get -o Acquire::ForceIPv4=true update && apt-get -o Acquire::ForceIPv4=true -y dist-upgrade && apt-get -o Acquire::ForceIPv4=true -y autoremove -apt-get -o Acquire::ForceIPv4=true install -y sudo strace tcpdump screen acpid vim python-pip locate -adduser edison sudo -adduser edison dialout +apt-get -o Acquire::ForceIPv4=true install -y sudo strace tcpdump screen acpid vim python-pip locate ntpdate +#check if edison user exists before trying to add it to groups + +if getent passwd edison > /dev/null; then + echo "Adding edison to sudo users" + adduser edison sudo + echo "Adding edison to dialout users" + adduser edison dialout + # else + # echo "User edison does not exist. Apparently, you are runnning a non-edison setup." +fi sed -i "s/daily/hourly/g" /etc/logrotate.conf sed -i "s/#compress/compress/g" /etc/logrotate.conf -# TODO: change back to master after docs release -curl -s https://raw.githubusercontent.com/openaps/docs/dev/scripts/quick-packages.sh | bash - +# TODO: change to dev and then master after PR and release +curl -s https://raw.githubusercontent.com/openaps/oref0/dev/bin/openaps-packages.sh | bash - mkdir -p ~/src; cd ~/src && git clone git://github.com/openaps/oref0.git || (cd oref0 && git checkout master && git pull) echo "Press Enter to run oref0-setup with the current release (master branch) of oref0," read -p "or press ctrl-c to cancel. " -r diff --git a/bin/openaps-packages.sh b/bin/openaps-packages.sh old mode 100644 new mode 100755 index 21e25fa8d..bf104980e --- a/bin/openaps-packages.sh +++ b/bin/openaps-packages.sh @@ -3,7 +3,7 @@ # TODO: remove the `-o Acquire::ForceIPv4=true` once Debian's mirrors work reliably over IPv6 apt-get -o Acquire::ForceIPv4=true install -y sudo sudo apt-get -o Acquire::ForceIPv4=true update && sudo apt-get -o Acquire::ForceIPv4=true -y upgrade -sudo apt-get -o Acquire::ForceIPv4=true install -y git python python-dev python-software-properties python-numpy python-pip nodejs-legacy npm watchdog strace tcpdump screen acpid vim locate jq lm-sensors && \ +sudo apt-get -o Acquire::ForceIPv4=true install -y git python python-dev software-properties-common python-numpy python-pip nodejs-legacy npm watchdog strace tcpdump screen acpid vim locate jq lm-sensors && \ sudo pip install -U openaps && \ sudo pip install -U openaps-contrib && \ sudo openaps-install-udev-rules && \ diff --git a/bin/openaps-src.sh b/bin/openaps-src.sh old mode 100644 new mode 100755 diff --git a/bin/oref0-append-local-temptarget.sh b/bin/oref0-append-local-temptarget.sh new file mode 100755 index 000000000..fe78ba5d1 --- /dev/null +++ b/bin/oref0-append-local-temptarget.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if [[ ! -z "$2" ]]; then + input=$(oref0-set-local-temptarget $@) +elif [[ ! -z "$1" ]]; then + input=$(cat $1) +else + input=$(cat /dev/stdin) +fi +#cat "${1:-/dev/stdin}" \ +echo $input \ + | tee /tmp/temptarget.json \ + && jq -s '[.[0]] + .[1]' /tmp/temptarget.json settings/local-temptargets.json \ + | tee settings/local-temptargets.json.new \ + && mv settings/local-temptargets.json.new settings/local-temptargets.json diff --git a/bin/oref0-autosens-loop.sh b/bin/oref0-autosens-loop.sh new file mode 100755 index 000000000..d60054a39 --- /dev/null +++ b/bin/oref0-autosens-loop.sh @@ -0,0 +1,57 @@ +#!/bin/bash +main() { + echo + echo Starting oref0-autosens-loop at $(date): + overtemp && exit 1 + if highload && completed_recently; then + echo Load high at $(date): waiting up to 30m to continue + exit 2 + fi + + autosens 2>&1 + touch /tmp/autons-completed + echo Completed oref0-autons-loop at $(date) +} + +function overtemp { + # check for CPU temperature above 85°C + sensors -u 2>/dev/null | awk '$NF > 85' | grep input \ + && echo Edison is too hot: waiting for it to cool down at $(date)\ + && echo Please ensure rig is properly ventilated +} + +function highload { + # check whether system load average is high + uptime | awk '$NF > 2' | grep load +} + +function completed_recently { + find /tmp/ -mmin -30 | egrep -q "autosens-completed" +} + +# find settings/ -newer settings/autosens.json | grep -q pumphistory-24h-zoned.json || find settings/ -size -5c | grep -q autosens.json || ! find settings/ | grep -q autosens || ! find settings/autosens.json +# openaps use detect-sensitivity shell monitor/glucose.json settings/pumphistory-24h-zoned.json settings/insulin_sensitivities.json settings/basal_profile.json settings/profile.json monitor/carbhistory.json settings/temptargets.json +function autosens { + # only run autosens if pumphistory-24h is newer than autosens + if find settings/ -newer settings/autosens.json | grep -q pumphistory-24h-zoned.json \ + || find settings/ -size -5c | grep -q autosens.json \ + || ! find settings/ | grep -q autosens \ + || ! find settings/autosens.json >/dev/null; then + if oref0-detect-sensitivity monitor/glucose.json settings/pumphistory-24h-zoned.json settings/insulin_sensitivities.json settings/basal_profile.json settings/profile.json monitor/carbhistory.json settings/temptargets.json > settings/autosens.json.new && cat settings/autosens.json.new | jq .ratio | grep -q [0-9]; then + mv settings/autosens.json.new settings/autosens.json + echo -n "Autosens refreshed: " + else + echo -n "Failed to refresh autosens: using old autosens.json: " + fi + else + echo -n "No need to refresh autosens yet: " + fi + cat settings/autosens.json | jq . -C -c +} + +die() { + echo "$@" + exit 1 +} + +main "$@" diff --git a/bin/oref0-autotune-recommends-report.sh b/bin/oref0-autotune-recommends-report.sh index fffc2e094..95bc759e2 100755 --- a/bin/oref0-autotune-recommends-report.sh +++ b/bin/oref0-autotune-recommends-report.sh @@ -85,16 +85,14 @@ minutes_list=() end_time=23:30 time=00:00 minutes=0 -while : -do - time_list+=( "$time" ) - minutes_list+=( "$minutes" ) - if [ $time != "$end_time" ]; then - time="$(date --date="$time 30 minutes" +%R)"; - minutes=$(expr $minutes + 30) - else - break - fi +for h in $(seq -w 0 23); do + for m in 00 30; do + time="$h:$m" + minutes=$(echo "60 * $h + $m" | bc) + #echo $time $minutes + time_list+=( "$time" ) + minutes_list+=( "$minutes" ) + done done for (( i=0; i<${#minutes_list[@]}; i++ )) diff --git a/bin/oref0-autotune.sh b/bin/oref0-autotune.sh index c246ede43..a81309930 100755 --- a/bin/oref0-autotune.sh +++ b/bin/oref0-autotune.sh @@ -27,8 +27,13 @@ # THE SOFTWARE. die() { - echo "$@" - exit 1 + if [[ -z "$API_SECRET" ]]; then + echo "Warning: API_SECRET is not set when calling oref0-autotune.sh" + echo "(this is only a problem if you have locked down read-only access to your NS)." + fi + + echo "$@" + exit 1 } # defaults @@ -48,11 +53,6 @@ if [ -n "${API_SECRET_READ}" ]; then echo "WARNING: API_SECRET_READ is deprecated starting with oref 0.6.x. The Nightscout authentication information is now used from the API_SECRET environment variable" fi -if [[ -z "$API_SECRET" ]]; then - echo "Warning: API_SECRET is not set when calling oref0-autotune.sh" - # exit 1 -fi - # If we are running OS X, we need to use a different version # of the 'date' command; the built-in 'date' is BSD, which # has fewer options than the linux version. So the user @@ -155,7 +155,6 @@ fi # If a previous valid settings/autotune.json exists, use that; otherwise start from settings/profile.json cp settings/autotune.json autotune/profile.json && cat autotune/profile.json | jq . | grep -q start || cp autotune/profile.pump.json autotune/profile.json cd autotune -# TODO: Need to think through what to remove in the autotune folder... # Turn on stderr logging, if enabled (default to true) if [[ $TERMINAL_LOGGING = "true" ]]; then @@ -176,12 +175,23 @@ do fi done +echo "Compressing old json and log files to save space..." +gzip -f ns-*.json +gzip -f autotune*.json +# only gzip autotune log files more than 2 days old +find autotune.*.log -mtime +2 | while read file; do gzip -f $file; done +echo "Autotune disk usage:" +du -h . +echo "Overall disk used/avail:" +df -h . + echo "Grabbing NIGHTSCOUT treatments.json and entries/sgv.json for date range..." # Get Nightscout BG (sgv.json) Entries for i in "${date_list[@]}" do - query="find%5Bdate%5D%5B%24gte%5D=`(date -d $i +%s | tr -d '\n'; echo 000)`&find%5Bdate%5D%5B%24lte%5D=`(date --date="$i +1 days" +%s | tr -d '\n'; echo 000)`&count=1000" + # pull CGM data from 4am-4am + query="find%5Bdate%5D%5B%24gte%5D=`(date -d "$i +4 hours " +%s | tr -d '\n'; echo 000)`&find%5Bdate%5D%5B%24lte%5D=`(date --date="$i +28 hours" +%s | tr -d '\n'; echo 000)`&count=1000" echo Query: $NIGHTSCOUT_HOST $query ns-get host $NIGHTSCOUT_HOST entries/sgv.json $query > ns-entries.$i.json || die "Couldn't download ns-entries.$i.json" ls -la ns-entries.$i.json || die "No ns-entries.$i.json downloaded" @@ -190,8 +200,8 @@ do # echo $i $START_DATE; #query="find%5Bdate%5D%5B%24gte%5D=`(date -d $i +%s | tr -d'\n'; echo 000)`&find%5Bdate%5D%5B%24lte%5D=`(date --date="$i +1 days" +%s | tr -d '\n'; echo 000)`&count=1000" # to capture UTC-dated treatments, we need to capture an extra 12h on either side, plus the DIA lookback - # 18h = 12h for timezones + 6h for DIA; 36h = 24h for end-of-day + 12h for timezones - query="find%5Bcreated_at%5D%5B%24gte%5D=`date --date="$i -18 hours" -Iminutes`&find%5Bcreated_at%5D%5B%24lte%5D=`date --date="$i +36 hours" -Iminutes`" + # 18h = 12h for timezones + 6h for DIA; 40h = 28h for 4am + 12h for timezones + query="find%5Bcreated_at%5D%5B%24gte%5D=`date --date="$i -18 hours" -Iminutes`&find%5Bcreated_at%5D%5B%24lte%5D=`date --date="$i +42 hours" -Iminutes`" echo Query: $NIGHTSCOUT_HOST/$query ns-get host $NIGHTSCOUT_HOST treatments.json $query > ns-treatments.$i.json || die "Couldn't download ns-treatments.$i.json" ls -la ns-treatments.$i.json || die "No ns-treatments.$i.json downloaded" diff --git a/bin/oref0-calculate-iob.js b/bin/oref0-calculate-iob.js index 54b00345d..d6f1b1ee3 100755 --- a/bin/oref0-calculate-iob.js +++ b/bin/oref0-calculate-iob.js @@ -20,7 +20,7 @@ var generate = require('oref0/lib/iob'); function usage ( ) { - console.log('usage: ', process.argv.slice(0, 2), ' '); + console.log('usage: ', process.argv.slice(0, 2), ' [autosens.json]'); } @@ -32,6 +32,7 @@ if (!module.parent) { } var profile_input = process.argv.slice(3, 4).pop(); var clock_input = process.argv.slice(4, 5).pop(); + var autosens_input = process.argv.slice(5, 6).pop(); if (!pumphistory_input || !profile_input) { usage( ); @@ -43,6 +44,14 @@ if (!module.parent) { var profile_data = require(cwd + '/' + profile_input); var clock_data = require(cwd + '/' + clock_input); + var autosens_data = null; + if (autosens_input) { + try { + var autosens_data = require(cwd + '/' + autosens_input); + } catch (e) {} + //console.error(autosens_input, JSON.stringify(autosens_data)); + } + // all_data.sort(function (a, b) { return a.date > b.date }); var inputs = { @@ -50,6 +59,9 @@ if (!module.parent) { , profile: profile_data , clock: clock_data }; + if ( autosens_data ) { + inputs.autosens = autosens_data; + } var iob = generate(inputs); console.log(JSON.stringify(iob)); diff --git a/bin/oref0-detect-sensitivity.js b/bin/oref0-detect-sensitivity.js index 41520d594..6de147541 100755 --- a/bin/oref0-detect-sensitivity.js +++ b/bin/oref0-detect-sensitivity.js @@ -17,7 +17,7 @@ var basal = require('oref0/lib/profile/basal'); var get_iob = require('oref0/lib/iob'); -var detect = require('oref0/lib/determine-basal/cob-autosens'); +var detect = require('oref0/lib/determine-basal/autosens'); if (!module.parent) { var detectsensitivity = init(); @@ -27,9 +27,11 @@ if (!module.parent) { var isf_input = process.argv.slice(4, 5).pop() var basalprofile_input = process.argv.slice(5, 6).pop() var profile_input = process.argv.slice(6, 7).pop(); + var carb_input = process.argv.slice(7, 8).pop() + var temptarget_input = process.argv.slice(8, 9).pop() if (!glucose_input || !pumphistory_input || !profile_input) { - console.error('usage: ', process.argv.slice(0, 2), ' '); + console.error('usage: ', process.argv.slice(0, 2), ' [carbhistory.json] [temptargets.json]'); process.exit(1); } @@ -62,6 +64,24 @@ if (!module.parent) { } var basalprofile = require(cwd + '/' + basalprofile_input); + var carb_data = { }; + if (typeof carb_input != 'undefined') { + try { + carb_data = JSON.parse(fs.readFileSync(carb_input, 'utf8')); + } catch (e) { + console.error("Warning: could not parse "+carb_input); + } + } + + var temptarget_data = { }; + if (typeof temptarget_input != 'undefined') { + try { + temptarget_data = JSON.parse(fs.readFileSync(temptarget_input, 'utf8')); + } catch (e) { + console.error("Warning: could not parse "+temptarget_input); + } + } + var iob_inputs = { history: pumphistory_data , profile: profile @@ -73,13 +93,30 @@ if (!module.parent) { var detection_inputs = { iob_inputs: iob_inputs - , glucose_data: glucose_data - , basalprofile: basalprofile - //, clock: clock_data + , carbs: carb_data + , glucose_data: glucose_data + , basalprofile: basalprofile + , temptargets: temptarget_data + //, clock: clock_data }; + console.error("Calculating sensitivity using 8h of non-exluded data"); + detection_inputs.deviations = 96; detect(detection_inputs); + ratio8h = ratio; + newisf8h = newisf; + console.error("Calculating sensitivity using all non-exluded data (up to 24h)"); + detection_inputs.deviations = 288; + detect(detection_inputs); + ratio24h = ratio; + newisf24h = newisf; + if ( ratio8h < ratio24h ) { + console.error("Using 8h autosens ratio of",ratio8h,"(ISF",newisf8h+")"); + } else { + console.error("Using 24h autosens ratio of",ratio24h,"(ISF",newisf24h+")"); + } + var lowestRatio = Math.min(ratio8h, ratio24h); var sensAdj = { - "ratio": ratio + "ratio": lowestRatio } return console.log(JSON.stringify(sensAdj)); diff --git a/bin/oref0-determine-basal.js b/bin/oref0-determine-basal.js index 3156a0ae9..026f55e51 100755 --- a/bin/oref0-determine-basal.js +++ b/bin/oref0-determine-basal.js @@ -182,17 +182,6 @@ if (!module.parent) { } } - //if old reading from Dexcom do nothing - - var systemTime = new Date(); - var bgTime; - if (glucose_data[0].display_time) { - bgTime = new Date(glucose_data[0].display_time.replace('T', ' ')); - } else if (glucose_data[0].dateString) { - bgTime = new Date(glucose_data[0].dateString); - } else { console.error("Could not determine last BG time"); } - var minAgo = (systemTime - bgTime) / 60 / 1000; - if (warnings.length) { console.error(JSON.stringify(warnings)); } @@ -202,16 +191,6 @@ if (!module.parent) { process.exit(1); } - if (minAgo > 10 || minAgo < -5) { // Dexcom data is too old, or way in the future - var reason = "BG data is too old (it's probably this), or clock set incorrectly. The last BG data was read at "+bgTime+" but your system time currently is "+systemTime; - console.error(reason); - var msg = {reason: reason } - console.log(JSON.stringify(msg)); - // errors.push(msg); - process.exit(1); - } - - if (typeof(iob_data.length) && iob_data.length > 1) { console.error(JSON.stringify(iob_data[0])); } else { @@ -219,7 +198,7 @@ if (!module.parent) { } console.error(JSON.stringify(glucose_status)); - console.error(JSON.stringify(currenttemp)); + //console.error(JSON.stringify(currenttemp)); //console.error(JSON.stringify(profile)); var tempBasalFunctions = require('oref0/lib/basal-set-temp'); diff --git a/bin/oref0-dex-wait-until-expected.sh b/bin/oref0-dex-wait-until-expected.sh index 69e7b3593..c9ea49b2f 100755 --- a/bin/oref0-dex-wait-until-expected.sh +++ b/bin/oref0-dex-wait-until-expected.sh @@ -10,7 +10,9 @@ if (( $(bc <<< "$TIME_SINCE >= $OLD") )); then echo "CGM Data $TIME_SINCE mins ago is old (>=$OLD), not waiting" else WAIT_MINS=$(bc <<< "$OLD - $TIME_SINCE") - if (( $(bc <<< "$WAIT_MINS >= $MAX_WAIT") )); then + if (( $(bc <<< "$WAIT_MINS > 6") )); then + echo "Clock mismatch ($WAIT_MINS > 6); not waiting" + elif (( $(bc <<< "$WAIT_MINS >= $MAX_WAIT") )); then echo "CGM Data $TIME_SINCE mins ago is fresh (< $OLD), $WAIT_MINS mins > max wait ($MAX_WAIT mins) waiting for next attempt" exit 1 else diff --git a/bin/oref0-html.js b/bin/oref0-html.js index f05e01ac7..43a930685 100755 --- a/bin/oref0-html.js +++ b/bin/oref0-html.js @@ -135,7 +135,7 @@ if (!module.parent) { //console.log("