diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ad2bacf1..d4706a25e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,26 +30,10 @@ performance and quality of your system lies solely with you. Additionally, this community of contributors believes in "paying it forward", and individuals who are implementing these tools are asked to contribute by asking questions, helping improve documentation, and -contribute in other ways. +contribute in other ways. We always need testers for various pieces of works-in-progress; please do ask if you would like to help but aren't sure where to get started. Please submit issues and pull requests so that all users can share -knowledge. If you're unfamiliar with GitHub and/or coding, [check out these other ways to get involved with OpenAPS.](https://openaps.gitbooks.io/building-an-open-artificial-pancreas-system/content/docs/Overview/contribute.html) - -For hacking on openaps, here are some tips to help your patches reach -more people more quickly. The `master` branch is special, it should -be "production" ready code, tested and verified, and should match the -contents available in pypi. Basically that means the `master` branch -is never touched directly, but rather we use a variety of other -branches to do things, and then merge the work into the `master` -branch. Sometimes this is called -[git flow](http://nvie.com/posts/a-successful-git-branching-model/). -Here's few guidelines that might help: - - * target a `dev` branch for pull requests. The latest updated - branch, especially any recently updated branch with `dev` in the - name. - * Avoid editing `master` branch. - * test changes +knowledge. If you're unfamiliar with GitHub and/or coding, [check out these other ways to get involved with OpenAPS.](http://openaps.readthedocs.io/en/latest/docs/Give%20Back-Pay%20It%20Forward/contribute.html) See [OpenAPS.org](http://OpenAPS.org/) for background on the OpenAPS movement and project. diff --git a/README.md b/README.md index b9f45a41d..8ede8f1db 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,21 @@ # oref0 -Javascript plugins for openaps +Algorithm for OpenAPS implementations. To get started with OpenAPS, see the [OpenAPS documentation](http://openaps.readthedocs.org/en/latest/) -Master code coverage: [![Coverage Status](https://coveralls.io/repos/github/openaps/oref0/badge.svg?branch=master)](https://coveralls.io/github/openaps/oref0?branch=master) - -Dev code coverage: [![Coverage Status](https://coveralls.io/repos/github/openaps/oref0/badge.svg?branch=dev)](https://coveralls.io/github/openaps/oref0?branch=dev) - -## Installing +## Installing oref0 Install tools globally: `npm run global-install` -## Usage +## Usage of oref0 ### `oref0` -The open reference implementation of the reference design. + +
+ The open reference implementation of the reference design. (click to expand for more usage details) +
+ ``` Usage: oref0 @@ -85,9 +85,6 @@ These can be defined in crontab, or in a simple file, eg API_SECRET="..." NIGHTSCOUT_HOST=localhost:1337 ns-upload-entries ``` -## Contributing - -See the [CONTRIBUTING document](CONTRIBUTING.md) ### Get the source ``` @@ -115,6 +112,11 @@ git push origin -u wip/my-enhancement-fix-or-proposal ``` Then target our `dev` branch for a pull request/peer review. +
+ +## Contributing + +See the [CONTRIBUTING document](CONTRIBUTING.md). PRs welcome! ## openaps @@ -140,4 +142,6 @@ 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. +performance and quality of your system lies solely with you. + +Read the [OpenAPS documentation](http://openaps.readthedocs.io/en/latest/) for more details. diff --git a/bin/openaps-install.sh b/bin/openaps-install.sh index df66b9874..e813fc731 100755 --- a/bin/openaps-install.sh +++ b/bin/openaps-install.sh @@ -28,7 +28,7 @@ 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 ntpdate +apt-get -o Acquire::ForceIPv4=true update && 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 diff --git a/bin/oref0-online.sh b/bin/oref0-online.sh index 3ccc14303..8240ad6cb 100755 --- a/bin/oref0-online.sh +++ b/bin/oref0-online.sh @@ -118,7 +118,10 @@ function bt_connect { echo; echo "No Internet access detected, attempting to connect BT to $MAC" oref0-bluetoothup sudo bt-pan client $MAC -d - sudo bt-pan client $MAC && sudo dhclient bnep0 + for i in {1..3} + do + sudo bt-pan client $MAC && sudo dhclient bnep0 + done if ifconfig | egrep -q "bnep0" >/dev/null; then echo -n "Connected to Bluetooth with IP: " print_local_ip bnep0 diff --git a/bin/oref0-pump-loop.sh b/bin/oref0-pump-loop.sh index 1b412e771..6d2cd06bd 100755 --- a/bin/oref0-pump-loop.sh +++ b/bin/oref0-pump-loop.sh @@ -29,6 +29,7 @@ fi # main pump-loop main() { + check_duty_cycle prep if ! overtemp; then echo && echo "Starting oref0-pump-loop at $(date) with $upto30s second wait_for_silence:" @@ -110,6 +111,81 @@ function fail { exit 1 } +# The function "check_duty_cycle" checks if the loop has to run and it returns 0 if so. +# It exits the script with code 0 otherwise. +# The desicion is based on the time since last *successful* loop. +# !Note duty cycle times are set in seconds. +# +# Additionally it may start an "emergency action" if enabled. +# Possible actions are usb power cycling or reboot the system. +# The EMERGENCY_ACTION variable sets the allowable time between successful loops. +# If no loop has completed in that time, it performs the enabled actions. +# !Note to enable a emergency action use 0 to enable and 1 to disable +# +# The intention is two fold: +# First the battery consumption is reduced (Pump and Pi) if the loop runs less often. +# This is most dramatic for Enlite CGM, where wait_for_bg can't be used. +# Secondly, if Carelink USB is used with Enlite, and wait_for_silence can't be used, this +# prevents the loop from disrupting the communication between the pump and enlite sensors. +# +# Use DUTY_CYCLE=0 (default) if you don't want to limit the loop +# +# Suggestion for Carelink USB users are +# DUTY_CYCLE=120 +# EMERGENCY_ACTION=900 +# REBOOT_ENABLE=0 #0=true +# USB_RESET_ENABLE=0 #0=true +# +# Default is DUTY_CYCLE=0 to disable this feature. +DUTY_CYCLE=${DUTY_CYCLE:-0} + +EMERGENCY_ACTION=${EMERGENCY_ACTION:-900} +REBOOT_ENABLE=${REBOOT_ENABLE:-1} #0=true +USB_RESET_ENABLE=${USB_RESET_ENABLE:-1} #0=true + +function check_duty_cycle { + if [ "$DUTY_CYCLE" -gt "0" ]; then + if [ -e /tmp/pump_loop_success ]; then + DIFF_SECONDS=$(expr $(date +%s) - $(stat -c %Y /tmp/pump_loop_success)) + + if ([ $USB_RESET_ENABLE ] || [ $REBOOT_ENABLE ]) && [ "$DIFF_SECONDS" -gt "$EMERGENCY_ACTION" ]; then + if [ $USB_RESET_ENABLE ]; then + USB_RESET_DIFF=$EMERGENCY_ACTION + if [ -e /tmp/usp_power_cycled ]; then + USB_RESET_DIFF=$(expr $(date +%s) - $(stat -c %Y /tmp/usp_power_cycled)) + fi + + if [ "$USB_RESET_DIFF" -gt "$EMERGENCY_ACTION" ]; then + # file is old --> power-cycling is long time ago (most probably not this round) --> power-cycling + echo -n "$DIFF_SECONDS (of $DUTY_CYCLE) since last run --> trying to reset USB... " + /usr/local/bin/oref0-reset-usb 2>&3 >&4 + touch /tmp/usp_power_cycled + echo " done. --> start new cycle." + return 0 #return to loop routine + fi + fi + # if usb reset doesn't help or is not enabled --> reboot system + if [ $REBOOT_ENABLE ]; then + echo "$DIFF_SECONDS (of $DUTY_CYCLE) since last run --> rebooting." + sudo shutdown -r now + exit 0 + fi + elif [ "$DIFF_SECONDS" -gt "$DUTY_CYCLE" ]; then + echo "$DIFF_SECONDS (of $DUTY_CYCLE) since last run --> start new cycle." + return 0 + else + echo "$DIFF_SECONDS (of $DUTY_CYCLE) since last run --> stop now." + exit 0 + fi + else + echo "/tmp/pump_loop_success does not exist; create it to start the loop duty cycle." + # if pump_loop_success does not exist, use the system uptime + touch -d "$(cat /proc/uptime | awk '{print $1}') seconds ago" /tmp/pump_loop_success + return 0 + fi + fi +} + function overtemp { # check for CPU temperature above 85°C @@ -264,7 +340,7 @@ function smb_verify_status { false fi \ && if grep -q 12 monitor/status.json; then - echo -n "x12 model detected." + echo -n "x12 model detected." true fi } @@ -407,7 +483,7 @@ function preflight { # reset radio, init world wide pump (if applicable), mmtune, and wait_for_silence 60 if no signal function mmtune { if grep "carelink" pump.ini 2>&1 >/dev/null; then - echo "using carelink; skipping mmtune" + echo "using carelink; skipping mmtune" return fi @@ -458,7 +534,7 @@ function any_pump_comms { # listen for $1 seconds of silence (no other rigs talking to pump) before continuing function wait_for_silence { if grep "carelink" pump.ini 2>&1 >/dev/null; then - echo "using carelink; not waiting for silence" + echo "using carelink; not waiting for silence" return fi if [ -z $1 ]; then @@ -573,7 +649,7 @@ function get_settings { # On the x12 pumps, these 'reports' are simulated by static json files created during the oref0-setup.sh run. NON_X12_ITEMS="settings/bg_targets.json" else - # On all other supported pumps, these reports work. + # On all other supported pumps, these reports work. NON_X12_ITEMS="settings/bg_targets_raw.json settings/bg_targets.json settings/basal_profile.json settings/settings.json" fi retry_return timerun openaps report invoke settings/model.json settings/insulin_sensitivities_raw.json settings/insulin_sensitivities.json settings/carb_ratios.json $NON_X12_ITEMS 2>&3 >&4 | tail -1 || return 1 diff --git a/bin/oref0-set-device-clocks.sh b/bin/oref0-set-device-clocks.sh index 7ad8f4523..278074101 100755 --- a/bin/oref0-set-device-clocks.sh +++ b/bin/oref0-set-device-clocks.sh @@ -47,6 +47,9 @@ if checkNTP; then sudo ntpdate -s -b time.nist.gov echo Setting pump time to $(date) openaps use $PUMP set_clock --to now 2>&1 >/dev/null | tail -1 - echo Setting CGM time to $(date) - openaps use $CGM UpdateTime --to now 2>&1 >/dev/null | tail -1 + # xdripaps CGM does not have a clock to set, so don't try. + if [ ! -d xdrip ]; then + echo Setting CGM time to $(date) + openaps use $CGM UpdateTime --to now 2>&1 >/dev/null | tail -1 + fi fi diff --git a/bin/oref0-setup.sh b/bin/oref0-setup.sh index e05e4e82a..5f214e903 100755 --- a/bin/oref0-setup.sh +++ b/bin/oref0-setup.sh @@ -775,16 +775,16 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then if [[ "$ttyport" =~ "spi" ]]; then echo Checking kernel for spi_serial installation if ! python -c "import spi_serial" 2>/dev/null; then - if uname -r 2>&1 | egrep "^4.1[0-9]"; then # kernel >= 4.10+, use pietergit version of spi_serial (does not use mraa) - echo Installing spi_serial && sudo pip install --upgrade git+https://github.com/pietergit/spi_serial.git || die "Couldn't install pietergit/spi_serial" - else # kernel < 4.10, use scottleibrand version of spi_serial (requires mraa) + #if uname -r 2>&1 | egrep "^4.1[0-9]"; then # kernel >= 4.10+, use pietergit version of spi_serial (does not use mraa) + # echo Installing spi_serial && sudo pip install --upgrade git+https://github.com/pietergit/spi_serial.git || die "Couldn't install pietergit/spi_serial" + #else # kernel < 4.10, use scottleibrand version of spi_serial (requires mraa) if [[ "$ttyport" =~ "spidev0.0" ]]; then echo Installing spi_serial && sudo pip install --upgrade git+https://github.com/scottleibrand/spi_serial.git@explorer-hat || die "Couldn't install scottleibrand/spi_serial for explorer-hat" sed -i.bak -e "s/#dtparam=spi=on/dtparam=spi=on/" /boot/config.txt else echo Installing spi_serial && sudo pip install --upgrade git+https://github.com/scottleibrand/spi_serial.git || die "Couldn't install scottleibrand/spi_serial" fi - fi + #fi #echo Installing spi_serial && sudo pip install --upgrade git+https://github.com/EnhancedRadioDevices/spi_serial || die "Couldn't install spi_serial" fi @@ -798,9 +798,9 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then openaps alias add mmtune "! bash -c \"oref0_init_pump_comms.py --ww_ti_usb_reset=yes -v; find monitor/ -size +5c | grep -q mmtune && cp monitor/mmtune.json mmtune_old.json; echo {} > monitor/mmtune.json; echo -n \"mmtune: \" && openaps report invoke monitor/mmtune.json; grep -v setFreq monitor/mmtune.json | grep -A2 $(cat monitor/mmtune.json | jq -r .setFreq) | while read line; do echo -n \"$line \"; done\"" fi echo Checking kernel for mraa installation - if uname -r 2>&1 | egrep "^4.1[0-9]"; then # don't install mraa on 4.10+ kernels - echo "Skipping mraa install for kernel 4.10+" - else # check if mraa is installed + #if uname -r 2>&1 | egrep "^4.1[0-9]"; then # don't install mraa on 4.10+ kernels + # echo "Skipping mraa install for kernel 4.10+" + #else # check if mraa is installed if ! ldconfig -p | grep -q mraa; then # if not installed, install it echo Installing swig etc. sudo apt-get install -y libpcre3-dev git cmake python-dev swig || die "Could not install swig etc." @@ -821,7 +821,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then make && sudo make install && echo && touch /tmp/reboot-required && echo mraa installed. Please reboot before using. && echo ) || die "Could not compile mraa" sudo bash -c "grep -q i386-linux-gnu /etc/ld.so.conf || echo /usr/local/lib/i386-linux-gnu/ >> /etc/ld.so.conf && ldconfig" || die "Could not update /etc/ld.so.conf" fi - fi + #fi fi echo Checking openaps dev installation @@ -835,6 +835,8 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then ( killall -g openaps; killall -g oref0-pump-loop) 2>/dev/null; openaps device remove pump 2>/dev/null if [[ -z "$ttyport" ]]; then openaps device add pump medtronic $serial || die "Can't add pump" + # add carelink to pump.ini + grep -q radio_type pump.ini || echo "radio_type=carelink" >> pump.ini # carelinks can't listen for silence or mmtune, so just do a preflight check instead openaps alias add wait-for-silence 'report invoke monitor/temp_basal.json' openaps alias add wait-for-long-silence 'report invoke monitor/temp_basal.json' @@ -845,23 +847,17 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then openaps alias add wait-for-silence '! bash -c "(mmeowlink-any-pump-comms.py --port '$ttyport' --wait-for 1 | grep -q comms && echo -n Radio ok, || openaps mmtune) && echo -n \" Listening: \"; for i in $(seq 1 100); do echo -n .; mmeowlink-any-pump-comms.py --port '$ttyport' --wait-for 30 2>/dev/null | egrep -v subg | egrep No && break; done"' openaps alias add wait-for-long-silence '! bash -c "echo -n \"Listening: \"; for i in $(seq 1 200); do echo -n .; mmeowlink-any-pump-comms.py --port '$ttyport' --wait-for 45 2>/dev/null | egrep -v subg | egrep No && break; done"' if [[ ${radio_locale,,} =~ "ww" ]]; then - if [ -d "$HOME/src/subg_rfspy/" ]; then - echo "$HOME/src/subg_rfspy/ already exists; pulling latest" - (cd $HOME/src/subg_rfspy && git fetch && git pull) || die "Couldn't pull latest subg_rfspy" - else - echo -n "Cloning subg_rfspy: " - (cd $HOME/src && git clone https://github.com/ps2/subg_rfspy) || die "Couldn't clone oref0" - fi - - # from 0.5.0 the subg-ww-radio-parameters script will be run from oref0_init_pump_comms.py - # this will be called when mmtune is use with a WW pump. - # See https://github.com/oskarpearson/mmeowlink/issues/51 or https://github.com/oskarpearson/mmeowlink/wiki/Non-USA-pump-settings for details - # use --ww_ti_usb_reset=yes if using a TI USB stick and a WW pump. This will reset the USB subsystem if the TI USB device is not foundTI USB (instead of calling reset.py) + if [ -d "$HOME/src/subg_rfspy/" ]; then + echo "$HOME/src/subg_rfspy/ already exists; pulling latest" + (cd $HOME/src/subg_rfspy && git fetch && git pull) || die "Couldn't pull latest subg_rfspy" + else + echo -n "Cloning subg_rfspy: " + (cd $HOME/src && git clone https://github.com/ps2/subg_rfspy) || die "Couldn't clone oref0" + fi - # Hack to check if radio_locale has been set in pump.ini. This is a temporary workaround for https://github.com/oskarpearson/mmeowlink/issues/55 - # It will remove empty line at the end of pump.ini and then append radio_locale if it's not there yet - # TODO: remove once https://github.com/openaps/openaps/pull/112 has been released in a openaps version - grep -q radio_locale pump.ini || echo "$(< pump.ini)" > pump.ini ; echo "radio_locale=$radio_locale" >> pump.ini + # Hack to check if radio_locale has been set in pump.ini. + # It will remove empty line at the end of pump.ini and then append radio_locale if it's not there yet + grep -q radio_locale pump.ini || echo "$(< pump.ini)" > pump.ini ; echo "radio_locale=$radio_locale" >> pump.ini fi fi @@ -1005,7 +1001,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then echo "export API_SECRET" >> $HOME/.bash_profile echo - + #Check to see if Explorer HAT is present, and install all necessary stuff if grep -qa "Explorer HAT" /proc/device-tree/hat/product 2>/dev/null ; then echo "Looks like you're using an Explorer HAT!" @@ -1023,7 +1019,7 @@ if [[ $REPLY =~ ^[Yy]$ ]]; then cp $HOME/src/openaps-menu/openaps-menu.service /etc/systemd/system/ && systemctl enable openaps-menu cd $HOME/myopenaps && openaps alias remove battery-status; openaps alias add battery-status '! bash -c "sudo ~/src/openaps-menu/scripts/getvoltage.sh > monitor/edison-battery.json"' fi - + if [[ "$ttyport" =~ "spi" ]]; then echo Resetting spi_serial reset_spi_serial.py diff --git a/lib/iob/history.js b/lib/iob/history.js index 02441bc6b..681f4d345 100644 --- a/lib/iob/history.js +++ b/lib/iob/history.js @@ -513,7 +513,7 @@ function calcTempTreatments (inputs, zeroTempDuration) { //process.stderr.write("Autosens ratio: "+sensitivityRatio+"; "); } if ( sensitivityRatio ) { - currentRate = profile_data.current_basal * sensitivityRatio; + currentRate = currentRate * sensitivityRatio; } var netBasalRate = currentItem.rate - currentRate; diff --git a/lib/profile/index.js b/lib/profile/index.js index 5b6b87e53..5f347ca43 100644 --- a/lib/profile/index.js +++ b/lib/profile/index.js @@ -40,13 +40,16 @@ function defaults ( ) { , A52_risk_enable: false , enableSMB_with_COB: false // enable supermicrobolus while COB is positive , enableSMB_with_temptarget: false // enable supermicrobolus for eating soon temp targets - // *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar - // xDrip+, LimiTTer, etc. do not properly filter out high-noise SGVs + // *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with Libre or similar + // LimiTTer, etc. do not properly filter out high-noise SGVs. xDrip+ builds greater than or equal to + // version number d8e-7097-2018-01-22 provide proper noise values, so that oref0 can ignore high noise + // readings, and can temporarily raise the BG target when sensor readings have medium noise, + // resulting in appropriate SMB behaviour. Older versions of xDrip+ should not be used with enableSMB_always. // Using SMB overnight with such data sources risks causing a dangerous overdose of insulin // if the CGM sensor reads falsely high and doesn't come down as actual BG does , enableSMB_always: false // always enable supermicrobolus (unless disabled by high temptarget) , enableSMB_after_carbs: false // enable supermicrobolus for 6h after carbs, even with 0 COB - // *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar + // *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with Libre or similar. , allowSMB_with_high_temptarget: false // allow supermicrobolus (if otherwise enabled) even with high temp targets , maxSMBBasalMinutes: 30 // maximum minutes of basal that can be delivered as a single SMB with uncovered COB , maxUAMSMBBasalMinutes: 30 // maximum minutes of basal that can be delivered as a single SMB when IOB exceeds COB diff --git a/package.json b/package.json index e1925285a..2269ca8b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "oref0", - "version": "0.6.1", + "version": "0.6.2-dev", "description": "openaps oref0 reference implementation of the reference design", "scripts": { "test": "make test", diff --git a/www/app.py b/www/app.py index e01687aff..add4199f7 100644 --- a/www/app.py +++ b/www/app.py @@ -1,7 +1,7 @@ import os import socket -from flask import Flask, render_template, url_for, json, jsonify +from flask import Flask, render_template, url_for, json, jsonify, request from datetime import datetime import pytz @@ -51,6 +51,23 @@ def glucose(): data = json.load(open(json_url)) return jsonify(data) +@app.route("/sgv.json") +def sgvjson(): + json_url = os.path.join("/root/myopenaps/settings/profile.json") + data = json.load(open(json_url)) + units = data['out_units'] + count = request.args.get('count', default = 10, type = int) + if os.path.getmtime("/root/myopenaps/xdrip/glucose.json") > os.path.getmtime("/root/myopenaps/monitor/glucose.json"): + json_url = os.path.join("/root/myopenaps/xdrip/glucose.json") + else: + json_url = os.path.join("/root/myopenaps/monitor/glucose.json") + data = json.load(open(json_url)) + if units == "mg/dL": + data[0]['units_hint'] = "mgdl" + else: + data[0]['units_hint'] = "mmol" + return jsonify(data[0:count]) + @app.route("/temptargets") def temptargets(): json_url = os.path.join("/root/myopenaps/settings/temptargets.json")