Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# openaps-js

Javascript plugins for openaps

This is part of a series of tools to support a self-driven DIY
implementation based on the OpenAPS reference design. The tools may be
categorized as *monitor* (collecting data about environment, and
operational status of devices and/or aggregating as much data as is
relevant into one place), *predict* (make predictions about what should
happen next), or *control* (enacting changes, and feeding more data back
into the *monitor*).

By proceeding using these tools or any piece within, you agree to the
copyright (see LICENSE.txt for more information) and release any
contributors from liability.

*Note:* This is intended to be a set of tools to support a self-driven DIY
implementation and any person choosing to use these tools is solely
responsible for testing and implement these tools independently or
together as a system. The [DIY part of OpenAPS is important]
(http://bit.ly/1NBbZtO). While formal training or experience as an
engineer or a developer is not required, what *is* required is a growth
mindset to learn what are essentially "building blocks" to implement an
OpenAPS instance. This is not a "set and forget" system; it requires
diligent and consistent testing and monitoring to ensure each piece of
the system is monitoring, predicting, and performing as desired. The
performance and quality of your system lies solely with you.
2 changes: 1 addition & 1 deletion bin/determine-basal.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ function init() {
rT.reason = "Eventual BG " + eventualBG + ">" + profile.max_bg + ", ";
if (basal_iob > max_iob) {
rT.reason = "basal_iob " + basal_iob + " > max_iob " + max_iob;
return determinebasal.setTempBasal(0, 0);
return determinebasal.setTempBasal(0, 0, profile, rT, offline);
}
// otherwise, calculate 30m high-temp required to get projected BG down to target
// insulinReq is the additional insulin required to get down to max bg:
Expand Down
211 changes: 49 additions & 162 deletions bin/loop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,14 @@ die() {
exit 1
}

# TODO: allow openaps instances in directories other than ~/openaps-dev
# for now, make sure we're running in ~/openaps-dev/, or die.
cd ~/openaps-dev/ || die "can't cd ~/openaps-dev/"

# remove all requestedtemp* files on startup, just in case an old process is in an endless loop
rm requestedtemp* 2>/dev/null
# delete any json files older than 10m to make triply sure we avoid using stale data
find *.json -mmin +10 -exec rm {} \; 2>/dev/null > /dev/null

# remove any old stale lockfiles
find /tmp/openaps.lock -mmin +10 -exec rm {} \; 2>/dev/null > /dev/null

# only one process can talk to the pump at a time
if ls /tmp/openaps.lock >/dev/null 2>/dev/null; then
ls -la /tmp/openaps.lock
echo "/tmp/openaps.lock exists"
exit 1
fi
ls /tmp/openaps.lock >/dev/null 2>/dev/null && die "OpenAPS already running: exiting" && exit

echo "No lockfile: continuing"
touch /tmp/openaps.lock
# if there are any old loops still running without proper lockfiles, kill them off
kill $(pgrep -f openaps-js/bin/loop.sh | grep -v ^$$\$)

# make sure decocare can talk to the Carelink USB stick
~/decocare/insert.sh 2>/dev/null >/dev/null
Expand All @@ -56,7 +41,7 @@ cd ~/openaps-dev && ( git status > /dev/null || ( mv ~/openaps-dev/.git /tmp/.gi
openaps report show > /dev/null || cp openaps.ini.bak openaps.ini

function finish {
rm /tmp/openaps.lock 2>/dev/null
rm /tmp/openaps.lock
}
trap finish EXIT

Expand All @@ -65,40 +50,33 @@ trap finish EXIT
# get glucose data, either from attached CGM or from Share
getglucose() {
echo "Querying CGM"
( ( openaps report invoke glucose.json.new || openaps report invoke glucose.json.new ) 2>/dev/null && grep -v '"glucose": 5' glucose.json.new | grep -q glucose ) || share2-bridge file glucose.json.new 2>/dev/null >/dev/null
if diff -q glucose.json glucose.json.new; then
( ( openaps report invoke glucose.json.new || openaps report invoke glucose.json.new ) && grep -v '"glucose": 5' glucose.json.new | grep glucose ) || share2-bridge file glucose.json.new
if diff -u glucose.json glucose.json.new; then
echo No new glucose data
return 1;
else
grep glucose glucose.json.new | head -1 | awk '{print $2}' | while read line; do echo -n " $line "; done >> /var/log/openaps/easy.log \
&& rsync -tu glucose.json.new glucose.json \
#&& git commit -m"glucose.json has glucose data: committing" glucose.json
return 0;
&& git commit -m"glucose.json has glucose data: committing" glucose.json
fi
}
# get pump status (suspended, etc.)
getpumpstatus() {
echo "Checking pump status"
openaps status 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log
openaps status || echo -n "!" >> /var/log/openaps/easy.log
grep -q status status.json.new && ( rsync -tu status.json.new status.json && echo -n "." >> /var/log/openaps/easy.log ) || echo -n "!" >> /var/log/openaps/easy.log
}
# query pump, and update pump data files if successful
querypump() {
#openaps pumpquery 2>/dev/null || ( echo -n "!" >> /var/log/openaps/easy.log && return 1 )
openaps report invoke clock.json.new 2>/dev/null || ( echo -n "!" >> /var/log/openaps/easy.log && return 1 )
openaps pumpquery || openaps pumpquery || echo -n "!" >> /var/log/openaps/easy.log
findclocknew && grep T clock.json.new && ( rsync -tu clock.json.new clock.json && echo -n "." >> /var/log/openaps/easy.log ) || echo -n "!" >> /var/log/openaps/easy.log
openaps report invoke currenttemp.json.new 2>/dev/null || ( echo -n "!" >> /var/log/openaps/easy.log && return 1 )
grep -q temp currenttemp.json.new && ( rsync -tu currenttemp.json.new currenttemp.json && echo -n "." >> /var/log/openaps/easy.log ) || echo -n "!" >> /var/log/openaps/easy.log
openaps report invoke pumphistory.json.new 2>/dev/null || ( echo -n "!" >> /var/log/openaps/easy.log && return 1 )
grep -q timestamp pumphistory.json.new && ( rsync -tu pumphistory.json.new pumphistory.json && echo -n "." >> /var/log/openaps/easy.log ) || echo -n "!" >> /var/log/openaps/easy.log
upload
return 0
}
# try to upload pumphistory data
upload() {
#findpumphistory && ~/bin/openaps-mongo.sh &
~/openaps-js/bin/ns-upload.sh
#ping -c 1 google.com > /dev/null && touch /tmp/openaps.online
ping -c 1 google.com > /dev/null && touch /tmp/openaps.online
}
# if we haven't uploaded successfully in 10m, use offline mode (if no temp running, set current basal as temp to show the loop is working)
suggest() {
Expand All @@ -109,156 +87,65 @@ suggest() {
getpumpsettings() { ~/openaps-js/bin/pumpsettings.sh; }

# functions for making sure we have up-to-date data before proceeding
findclock() { find clock.json -mmin -10 | egrep -q '.*'; }
findclocknew() { find clock.json.new -mmin -10 | egrep -q '.*'; }
findglucose() { find glucose.json -mmin -10 | egrep -q '.*'; }
findpumphistory() { find pumphistory.json -mmin -10 | egrep -q '.*'; }
findrequestedtemp() { find requestedtemp.json -mmin -10 | egrep -q '.*'; }
# write out current status to pebble.json
pebble() { ~/openaps-js/bin/pebble.sh; }

bail() {
echo "$@" | tee -a /var/log/openaps/easy.log
return 1
}

actionrequired() {
# make sure we can still talk to the carelink stick
python -m decocare.stick $(python -m decocare.scan) >/dev/null || sudo ~/openaps-js/bin/fix-dead-carelink.sh | tee -a /var/log/openaps/easy.log
# if reservoir insulin remaining changes by more than 0.2U between runs, that probably indicates a bolus
if awk '{getline t<"reservoir.json.new"; if (($0-t) > 0.2 || ($0-t < -0.2)) print "Reservoir changed from " $0 " to " t}' reservoir.json | grep changed; then
echo "Reservoir status changed"
rsync -tu reservoir.json.new reservoir.json
return 0;
else
rsync -tu reservoir.json.new reservoir.json
# if a temp is needed based on current BG and temp
openaps report invoke requestedtemp.online.json || return 0
grep rate requestedtemp.online.json
return $?
fi
}

execute() {
getglucose
head -15 glucose.json | grep -B1 glucose

numprocs=$(fuser -n file $(python -m decocare.scan) 2>&1 | wc -l)
if [[ $numprocs -gt 0 ]] ; then
bail "Carelink USB already in use or not available."; return $?
fi

retries=5
retry=0
echo "Querying pump" && querypump 2>/dev/null
until findpumphistory && findclock; do
echo "Querying pump (try $retry)" && querypump 2>/dev/null
retry=`expr $retry + 1`
if [ $retry -ge $retries ]; then bail "Failed to query pump history after $retries retries"; return $?; fi
sleep 30;
done
# main event loop

# get glucose again in case the pump queries took awhile
getglucose
getglucose
head -15 glucose.json

# if we're offline, set the clock to the pump/CGM time
~/openaps-js/bin/clockset.sh
numprocs=$(fuser -n file $(python -m decocare.scan) 2>&1 | wc -l)
if [[ $numprocs -gt 0 ]] ; then
die "Carelink USB already in use or not available."
fi

# dump out a "what we're about to try to do" report
suggest && pebble
getpumpstatus
echo "Querying pump" && querypump

tail clock.json
tail currenttemp.json
upload

# make sure we're not using an old suggestion
rm requestedtemp* 2>/dev/null
echo "Removing requestedtemp.json and recreating it"
# if we can't run suggest, it might be because our pumpsettings are missing or screwed up"
suggest || ( getpumpsettings && suggest ) || ( bail "Can't calculate IOB or basal"; return $? )
pebble
tail profile.json
tail iob.json
tail requestedtemp.json
# get glucose again in case the pump queries took awhile
getglucose

# if we're offline, set the clock to the pump/CGM time
~/openaps-js/bin/clockset.sh

# don't act on stale glucose data
findglucose && grep -q glucose glucose.json || ( bail "No recent glucose data"; return $? )
# execute/enact the requested temp
cat requestedtemp.json | json_pp | grep reason >> /var/log/openaps/easy.log
if grep -q rate requestedtemp.json; then
echo "Enacting temp"
retries=5
retry=0
until openaps enact; do
retry=`expr $retry + 1`
echo "enact failed; retry $retry"
if [ $retry -ge $retries ]; then bail "Failed to enact temp after $retries retries"; return $?; fi
sleep 10;
done
tail enactedtemp.json && ( echo && cat enactedtemp.json | egrep -i "bg|dur|rate|re|tic|tim" | sort -r ) >> /var/log/openaps/easy.log && cat iob.json | json_pp | grep '"iob' >> /var/log/openaps/easy.log && return 0
fi
}
# dump out a "what we're about to try to do" report
suggest && pebble

requery() {
numprocs=$(fuser -n file $(python -m decocare.scan) 2>&1 | wc -l)
if [[ $numprocs -gt 0 ]] ; then
bail "Carelink USB already in use or not available."; return $?
fi
tail clock.json
tail currenttemp.json

echo "Re-querying pump"
retries=5
retry=0
until querypump; do
retry=`expr $retry + 1`
echo "Re-query failed; retry $retry"
if [ $retry -ge $retries ]; then bail "Failed to re-query pump"; return $?; fi
done
# make sure we're not using an old suggestion
rm requestedtemp*
# if we can't run suggest, it might be because our pumpsettings are missing or screwed up"
suggest || ( getpumpsettings && suggest ) || die "Can't calculate IOB or basal"
pebble
tail profile.json
tail iob.json
tail requestedtemp.json

# unlock in case upload is really slow
#rm /tmp/openaps.lock 2>/dev/null
pebble
upload
# don't act on stale glucose data
findglucose && grep -q glucose glucose.json || die "No recent glucose data"
# execute/enact the requested temp
cat requestedtemp.json | json_pp | grep reason >> /var/log/openaps/easy.log
grep -q rate requestedtemp.json && ( openaps enact || openaps enact ) && tail enactedtemp.json && ( echo && cat enactedtemp.json | egrep -i "bg|rate|dur|re|tic|tim" | sort -r ) >> /var/log/openaps/easy.log && cat iob.json | json_pp | grep '"iob' >> /var/log/openaps/easy.log

# if another instance didn't start while we were uploading, refresh pump settings
#ls /tmp/openaps.lock >/dev/null 2>/dev/null && die "OpenAPS already running: exiting" && exit
touch /tmp/openaps.lock
numprocs=$(fuser -n file $(python -m decocare.scan) 2>&1 | wc -l)
if [[ $numprocs -gt 0 ]] ; then
bail "Carelink USB already in use or not available."; return $?
fi
retries=2
retry=0
until getpumpsettings; do
retry=`expr $retry + 1`
echo "getpumpsettings failed; retry $retry"
if [ $retry -ge $retries ]; then bail "getpumpsettings failed"; return $?; fi
done
}
echo "Re-querying pump"
query pump

# main event loop
# unlock in case upload is really slow
rm /tmp/openaps.lock
pebble
upload

while(true); do

touch /tmp/openaps.lock
# execute on startup, and then whenever actionrequired()
until execute; do
echo "Failed; retrying"
sleep 5
done
requery
getglucose && openaps report invoke requestedtemp.online.json && cat requestedtemp.online.json | json_pp | grep reason >> /var/log/openaps/easy.log
# set a new reservoir baseline and watch for changes (boluses)
openaps report invoke reservoir.json.new 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log && rsync -tu reservoir.json.new reservoir.json
openaps report invoke currenttemp.json.new 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log
until actionrequired; do
touch /tmp/openaps.lock
getglucose && openaps report invoke requestedtemp.online.json && cat requestedtemp.online.json | json_pp | grep reason >> /var/log/openaps/easy.log
openaps report invoke currenttemp.json.new 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log
openaps report invoke reservoir.json.new 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log
openaps report invoke clock.json.new 2>/dev/null || echo -n "!" >> /var/log/openaps/easy.log
findclocknew && grep T clock.json.new && rsync -tu clock.json.new clock.json || echo -n "!" >> /var/log/openaps/easy.log
pebble
echo -n "-" >> /var/log/openaps/easy.log
sleep 30
done
done
# if another instance didn't start while we were uploading, refresh pump settings
ls /tmp/openaps.lock >/dev/null 2>/dev/null && die "OpenAPS already running: exiting" && exit
touch /tmp/openaps.lock
getpumpsettings
4 changes: 2 additions & 2 deletions bin/ns-upload.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@ cat $HISTORY | \
> $OUTPUT


# requires API_SECRET and site to be set in calling environment (i.e. in crontab)
curl -s -X POST --data-binary @$OUTPUT -H "API-SECRET: $API_SECRET" -H "content-type: application/json" $site/api/v1/entries.json >/dev/null && ( touch /tmp/openaps.online && echo "Uploaded $OUTPUT to $site." ) || echo "Unable to upload to $site."
# requires API_SECRET and NIGHTSCOUT_HOST to be set in calling environment (i.e. in crontab)
curl -s -X POST --data-binary @$OUTPUT -H "API-SECRET: $API_SECRET" -H "content-type: application/json" $NIGHTSCOUT_HOST/api/v1/entries.json >/dev/null && ( touch /tmp/openaps.online && echo "Uploaded $OUTPUT to $NIGHTSCOUT_HOST" ) || echo "Unable to upload to $NIGHTSCOUT_HOST"
18 changes: 11 additions & 7 deletions bin/sendtempbasal-Azure.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
/*
#!/usr/bin/env node

/*
Send Temporary Basal to Azure

Copyright (c) 2015 OpenAPS Contributors
Expand All @@ -21,15 +23,17 @@ if (!module.parent) {
var iob_input = process.argv.slice(2, 3).pop()
var enacted_temps_input = process.argv.slice(3, 4).pop()
var glucose_input = process.argv.slice(4, 5).pop()
if (!iob_input || !enacted_temps_input || !glucose_input) {
console.log('usage: ', process.argv.slice(0, 2), '<iob.json> <enactedBasal.json> <bgreading.json>');
var webapi = process.argv.slice(5, 6).pop()
if (!iob_input || !enacted_temps_input || !glucose_input || !webapi) {
console.log('usage: ', process.argv.slice(0, 2), '<iob.json> <enactedBasal.json> <bgreading.json> <[your_webapi].azurewebsites.net>');
process.exit(1);
}
}

var glucose_data = require('./' + glucose_input);
var enacted_temps = require('./' + enacted_temps_input);
var iob_data = require('./' + iob_input);
var cwd = process.cwd();
var glucose_data = require(cwd + '/' + glucose_input);
var enacted_temps = require(cwd + '/' + enacted_temps_input);
var iob_data = require(cwd + '/' + iob_input);



Expand All @@ -46,7 +50,7 @@ var data = JSON.stringify({
);

var options = {
host: '[your_webapi].azurewebsites.net',
host: webapi,
port: '443',
path: '/api/openapstempbasals',
method: 'POST',
Expand Down