Skip to content

Instantly share code, notes, and snippets.

@channemann
Last active December 30, 2015 21:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save channemann/d29abfabffd365ed1735 to your computer and use it in GitHub Desktop.
Save channemann/d29abfabffd365ed1735 to your computer and use it in GitHub Desktop.

Set up RPi

See docs, Section 3.1

Notes that aren't included there ...

$ wpa_passphrase "<my_SSID>" "<my_password>" >> /etc/wpa_supplicant/wpa_supplicant.conf

Repeat as necessary to add all relevant WiFi networks

Use single quotes for SSID and PSK if an escape character is required

Add 8192cu.conf to /etc/modprobe.d/

Two solutions:

  1. https://www.raspberrypi.org/forums/viewtopic.php?t=61665
  2. https://learn.adafruit.com/adafruits-raspberry-pi-lesson-3-network-setup/test-and-configure#fixing-wifi-dropout-issues

Set up the timezone; make sure the RPi, pump, and dex are in-sync (and if you change one, you change them all)

Set up openaps

See docs, Section 3.2

Install Git

$ sudo apt-get install git

Install Python packages, system wide

$ sudo apt-get install python python-dev python-setuptools python-software-properties python-numpy python-scipy

Install PyPi and OpenAPS

$ sudo apt-get install python python-dev python-setuptools python-software-properties python-numpy && sudo easy_install -ZU openaps

Install udev-rules

$ sudo openaps-install-udev-rules

Enable tab completion for efficiency

$ sudo activate-global-python-argcomplete

Update openaps (when required)

$ sudo easy_install -ZU openaps

Install openaps plugins

These installations assume the system is for usage, not for development. To install from source, see the individual plugin GitHub pages

Install mmhistorytools

$ sudo easy_install openapscontrib.mmhistorytools

Install glucosetools

$ sudo easy_install openapscontrib.glucosetools

Install openaps-predict

$ sudo easy_install openapscontrib.predict

Install openaps-dose

(not going to show how for this one quite yet)

Install openaps-monitor

(check the link for full installation instructions)

Configure openaps

Initialize openaps environment

$ openaps init <my_openaps>

Move into new openaps directory

$ cd <my_openaps>

Add pump as device

$ openaps device add <my_pump_name> medtronic <my_serial_number>

Add Dexcom CGM receiver as device (not required if using Medtronic CGM)

$ openaps device add <my_dexcom_name> dexcom

Add openaps plugins (first as vendors, then as devices)

$ openaps vendor add openapscontrib.mmhistorytools
$ openaps device add <munge> mmhistorytools
$ openaps vendor add openapscontrib.glucosetools
$ openaps device add <glucose> glucosetools
$ openaps vendor add openapscontrib.predict
$ openaps device add <predict> predict
$ openaps vendor add openapscontrib.dose
$ openaps device add <dose> dose

Check that the devices are all added properly

$ openaps device show

should return something like:

medtronic://pump
dexcom://cgms
mmhistorytools://munge
mmglucosetools://glucose
predict://predict
dose://dose

where the strings after the // are the names you used for <my_pump_name>, <my_dexcom_name>, et cetera

Check that you can talk with your pump

$ openaps use <my_pump_name> model

should return something like:

"723"

Check that you can talk with your dex

$ openaps use <my_dexcom_name> iter_glucose 1

should return something like:

[
  {
    "trend_arrow": "FLAT", 
    "system_time": "2015-08-23T21:45:29", 
    "display_time": "2015-08-23T13:46:21", 
    "glucose": 137
  }
]

Add a whole bunch of reports

It's a good idea to check each one out after adding by invoking it and checking the output. For example, after the first one below (with your dex connected), run $ openaps report invoke recent_glucose.json, which will create a file called recent_glucose.json. Then, run $ cat recent_glucose.json and you should see a file with your most recent glucose values.

Also, a few notes:

  • The items in <angle_brackets> are the names you assigned when adding the devices; don't actually use the < >
  • If you are using a Medtronic CGM, the first report should use the <my_pump_name> device instead of the <my_dexcom_name> device; the iter_glucose_hours function is common to those devices
  • For the first two, the number 6 is used; you should use a number greater than or equal to your insulin duration, plus a few hours (I have an insulin duration of 3 hours, so I use 3 + 3 = 6 hours to cover longer square boluses)
  • We know that read_insulin_sensitivies is mispelled; this is done because it is mispelled in the openaps toolset, so we decided to keep it consistent
  • When you are testing the ones near the bottom (that take in a file), make sure you have run the previous reports to generate those input files
$ openaps report add recent_glucose.json JSON <my_dexcom_name> iter_glucose_hours 6
$ openaps report add recent_history.json JSON <my_pump_name> iter_pump_hours 6
$ openaps report add read_clock.json JSON <my_pump_name> read_clock
$ openaps report add read_battery_status.json JSON <my_pump_name> read_battery_status
$ openaps report add read_settings.json JSON <my_pump_name> read_settings
$ openaps report add read_carb_ratios.json JSON <my_pump_name> read_carb_ratios
$ openaps report add read_selected_basal_profile.json JSON <my_pump_name> read_selected_basal_profile
$ openaps report add read_insulin_sensitivies.json JSON <my_pump_name> read_insulin_sensitivies
$ openaps report add read_bg_targets.json JSON <my_pump_name> read_bg_targets
$ openaps report add read_status.json JSON <my_pump_name> read_status
$ openaps report add clean_glucose.json JSON <glucose> clean recent_glucose.json
$ openaps report add clean_history.json JSON <munge> clean recent_history.json
$ openaps report add reconcile_history.json JSON <munge> reconcile clean_history.json
$ openaps report add resolve_history.json JSON <munge> resolve reconcile_history.json
$ openaps report add normalized_history.json JSON <munge> normalize \
	resolve_history.json \
	--basal-profile read_selected_basal_profile.json
$ openaps report add predict_glucose.json JSON <predict> glucose \
        normalized_history.json \
	clean_glucose.json \
	--settings read_settings.json \
	--insulin-sensitivities read_insulin_sensitivies.json \
	--carb-ratios read_carb_ratios.json
$ openaps report add predict_glucose_without_future_basal.json JSON <predict> glucose \
        normalized_history.json \
	clean_glucose.json \
	--settings read_settings.json \
	--insulin-sensitivities read_insulin_sensitivies.json \
	--carb-ratios read_carb_ratios.json \
	--basal-dosing-end read_clock.json
$ openaps report add recommended_dose.json JSON <dose> recommend \
	--resolved-history resolve_history.json \
	--settings read_settings.json \
	--clock read_clock.json \
	--bg-targets read_bg_targets.json \
	--insulin-sensitivities read_insulin_sensitivies.json \
	--basal-profile read_selected_basal_profile.json \
	predict_glucose_without_future_basal.json
$ openaps report add set_dose.json JSON <my_pump_name> deliver recommended_dose.json		

Did you remember to test all of those reports (in order)? Good!

Add aliases

Aliases are a way to gather a number of openaps commands into a single, easy-to-exute command. Instead of having to run all of the above reports individually, you can instead make logical groupings and run them together. For example, after adding the first alias below (refresh), you can simply run $ openaps refresh and it will execute the constituent reports in order. Note here that we are reusing some of the device names from above (such as munge and predict) as aliases. These won't be in conflict, but feel free to use different names if it is confusing.

Add the following aliases:

$ openaps alias add refresh "report invoke read_settings.json read_bg_targets.json read_insulin_sensitivies.json read_selected_basal_profile.json read_carb_ratios.json"
$ openaps alias add update "report invoke read_status.json read_battery_status.json read_clock.json recent_glucose.json recent_history.json"
$ openaps alias add munge "report invoke clean_glucose.json clean_history.json reconcile_history.json resolve_history.json normalized_history.json"
$ openaps alias add predict "report invoke predict_glucose.json predict_glucose_without_future_basal.json"
$ openaps alias add dose "report invoke recommended_dose.json set_dose.json"

Just like you did with the reports, go ahead and test each of these aliases to make sure the execute properly. For example,

$ openaps refresh

should return:

pump://JSON/read_settings/read_settings.json
reporting read_settings.json
pump://JSON/read_bg_targets/read_bg_targets.json
reporting read_bg_targets.json
pump://JSON/read_insulin_sensitivies/read_insulin_sensitivies.json
reporting read_insulin_sensitivies.json
pump://JSON/read_selected_basal_profile/read_selected_basal_profile.json
reporting read_selected_basal_profile.json
pump://JSON/read_carb_ratios/read_carb_ratios.json
reporting read_carb_ratios.json

This completes the setup of the openaps.ini file, which resides in your <my_openaps> directory. Go ahead and take a look using $ cat openaps.ini.

Set up your loop

Make a new directory in your top-level directory (which is probably something like /home/pi) called /bin.

$ cd
$ mkdir bin
$ cd bin

We will put three files in the /bin directory: one to initialize the web server, one that power cycles the CareLink stick to make sure it continues to run, and one that defines the loop. For each of these, make sure and replace <my_openaps> with the directory name you chose for your OpenAPS instance. I'm assuming here that it is in /home/pi/<my_openaps>, but make sure to check and use the correct full pathname.

Set up start-web

start-web.sh

cd /home/pi/openaps-monitor
screen -d -A -S openaps -m python monitor.py /home/pi/<my_openaps>
cd -
cd /home/pi/<my_openaps>
openaps refresh
cd -

Set up fix-stick

fix-stick.sh

#!/bin/sh
echo "Power-cycling USB to fix dead Carelink stick"
sleep 0.1
echo 0 > /sys/devices/platform/bcm2708_usb/buspower
sleep 1
echo 1 > /sys/devices/platform/bcm2708_usb/buspower
sleep 2

Set up loop shell script

every-five.sh

#!/bin/bash
fuser $(python -m decocare.scan) && exit 1
cd /home/pi/<my_openaps>
openaps update && \
openaps munge && \
openaps predict && \
openaps dose || (python -m decocare.stick $(python -m decocare.scan) > /dev/null && echo "Stick OK" 1>&2 || sudo ~/bin/fix-stick.sh 1>&2)
# git push 2>&1

cd -

While still in /home/pi/bin, run:

$ sudo chmod a+xr ./*

(I forget exactly what this does ... changed the color of the .sh files when doing ls, I believe, so it registered them or something?)

Install Flask

$ sudo pip install Flask

Also, do this:

$ sudo apt-get install screen

I think this is for the openaps-monitor to function properly.

Also, need to do this for newer version of openaps-predict:

$ sudo pip install functools32

Set up CRON job

This file goes in your top-level directory (again, probably /home/pi). It tells the OS when to run the scripts. In this case, it is running start-web.sh upon reboot and every-five.sh every five minutes (surprise). every-five.sh calls fix-stick.sh to make sure the CareLink stick is still ticking.

# Edit this file to introduce tasks to be run by cron.
# 
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
# 
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').# 
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
# 
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
# 
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
# 
# For more information see the manual pages of crontab(5) and cron(8)
# 

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# m  h dom mon dow   command
 */5 *  *   *   *    /home/pi/bin/every-five.sh > /home/pi/bin/mylog.log 2>&1
@reboot		     /home/pi/bin/start-web.sh > /dev/null

New Notes:

$ openaps report add recent_history_with_dose.json JSON <munge> append_dose recent_history.json --dose set_dose.json
$ openaps report add prepared_history_with_dose.json JSON <munge> prepare recent_history_with_dose.json --basal_profile read_selected_basal_profile.json
$ openaps report add predict_glucose_with_dose.json JSON <predict> glucose \
        prepared_history_with_dose.json \
	clean_glucose.json \
	--settings read_settings.json \
	--insulin-sensitivities read_insulin_sensitivies.json \
	--carb-ratios read_carb_ratios.json
$ openaps report add iob_history.json JSON <predict> walsh_iob prepared_history_with_dose.json --settings read_settings.json
$ openaps report add cgms_calibrations.json JSON cgms iter_calibrations 3
$ openaps report add glucose_momentum_effect.json JSON predict glucose_momentum_effect clean_glucose.json --prediction-time 30 --calibrations cgms_calibrations.json
$ openaps report add predict_glucose_without_future_basal.json JSON predict glucose_from_effects insulin_effect_without_future_basal.json carb_effect.json --glucose clean_glucose.json --momentum glucose_momentum_effect.json
$ openaps report add predict_glucose_with_dose.json JSON predict glucose_from_effects insulin_effect_with_dose.json carb_effect.json --glucose clean_glucose.json --momentum glucose_momentum_effect.json 
$ openaps report add cob_history.json JSON preict scheiner_cob prepared_history_with_dose.json

$ openaps alias add update "report invoke recent_glucose.json clean_glucose.json cgms_calibrations.json read_status.json read_battery_status.json read_clock.json recent_history.json"
$ openaps alias add predict "report invoke insulin_effect_without_future_basal.json carb_effect.json glucose_momentum_effect.json predict_glucose_without_future_basal.json"
$ openaps alias add review "report invoke recent_history_with_dose.json prepared_history_with_dose.json insulin_effect_with_dose.json predict_glucose_with_dose.json iob_history.json cob_history.json"

$ openaps alias show
refresh report invoke read_settings.json read_bg_targets.json read_insulin_sensitivies.json read_selected_basal_profile.json read_carb_ratios.json
update report invoke recent_glucose.json clean_glucose.json cgms_calibrations.json read_status.json read_battery_status.json read_clock.json recent_history.json
predict report invoke insulin_effect_without_future_basal.json carb_effect.json glucose_momentum_effect.json predict_glucose_without_future_basal.json
dose report invoke recommended_dose.json set_dose.json
munge report invoke clean_history.json reconcile_history.json resolve_history.json normalize_history.json
review report invoke recent_history_with_dose.json prepared_history_with_dose.json insulin_effect_with_dose.json predict_glucose_with_dose.json iob_history.json cob_history.json
$ cat openaps.ini 
[device "pump"]
serial = 123456
vendor = openaps.vendors.medtronic
expires = 2015-10-27T14:48:07.526992
model = 723

[device "cgms"]
vendor = openaps.vendors.dexcom

[vendor "openapscontrib.mmhistorytools"]
path = .
module = openapscontrib.mmhistorytools

[device "munge"]
vendor = openapscontrib.mmhistorytools

[vendor "openapscontrib.predict"]
path = .
module = openapscontrib.predict

[device "predict"]
vendor = openapscontrib.predict

[vendor "openapscontrib.dose"]
path = .
module = openapscontrib.dose

[device "dose"]
vendor = openapscontrib.dose

[report "recent_history.json"]
device = pump
hours = 6.0
use = iter_pump_hours
reporter = JSON

[report "read_clock.json"]
device = pump
use = read_clock
reporter = JSON

[report "read_battery_status.json"]
device = pump
use = read_battery_status
reporter = JSON

[report "read_settings.json"]
device = pump
use = read_settings
reporter = JSON

[report "read_carb_ratios.json"]
device = pump
use = read_carb_ratios
reporter = JSON

[report "read_selected_basal_profile.json"]
device = pump
use = read_selected_basal_profile
reporter = JSON

[report "read_insulin_sensitivies.json"]
device = pump
use = read_insulin_sensitivies
reporter = JSON

[report "read_bg_targets.json"]
device = pump
use = read_bg_targets
reporter = JSON

[report "read_status.json"]
device = pump
use = read_status
reporter = JSON

[report "reconcile_history.json"]
device = munge
use = reconcile
infile = clean_history.json
reporter = JSON

[report "resolve_history.json"]
device = munge
use = resolve
infile = reconcile_history.json
reporter = JSON

[report "clean_history.json"]
device = munge
use = clean
infile = recent_history.json
reporter = JSON

[report "predict_glucose.json"]
use = glucose
settings = read_settings.json
reporter = JSON
carb_ratios = read_carb_ratios.json
pump-history = normalize_history.json
device = predict
insulin_sensitivities = read_insulin_sensitivies.json
glucose = clean_glucose.json

[report "predict_glucose_without_future_basal.json"]
use = glucose_from_effects
settings = read_settings.json
reporter = JSON
carb_ratios = read_carb_ratios.json
pump-history = normalize_history.json
device = predict
insulin_sensitivities = read_insulin_sensitivies.json
glucose = clean_glucose.json
basal_dosing_end = read_clock.json
effects = ['insulin_effect_without_future_basal.json', 'carb_effect.json']

[report "recommended_dose.json"]
use = recommend
bg_targets = read_bg_targets.json
settings = read_settings.json
basal_profile = read_selected_basal_profile.json
reporter = JSON
predicted-glucose-without-basal = predict_glucose_without_future_basal.json
resolved_history = resolve_history.json
device = dose
clock = read_clock.json
insulin_sensitivities = read_insulin_sensitivies.json

[report "set_dose.json"]
device = pump
use = deliver
recommendation = recommended_dose.json
reporter = JSON

[alias]
refresh = report invoke read_settings.json read_bg_targets.json read_insulin_sensitivies.json read_selected_basal_profile.json read_carb_ratios.json
update = report invoke recent_glucose.json clean_glucose.json cgms_calibrations.json read_status.json read_battery_status.json read_clock.json recent_history.json
predict = report invoke insulin_effect_without_future_basal.json carb_effect.json glucose_momentum_effect.json predict_glucose_without_future_basal.json
dose = report invoke recommended_dose.json set_dose.json
munge = report invoke clean_history.json reconcile_history.json resolve_history.json normalize_history.json
review = report invoke recent_history_with_dose.json prepared_history_with_dose.json insulin_effect_with_dose.json predict_glucose_with_dose.json iob_history.json

[report "normalize_history.json"]
use = normalize
reporter = JSON
basal_profile = read_selected_basal_profile.json
device = munge
infile = resolve_history.json

[report "recent_glucose.json"]
device = cgms
hours = 6.0
use = iter_glucose_hours
reporter = JSON

[report "clean_glucose.json"]
device = glucose
use = clean
infile = recent_glucose.json
reporter = JSON

[report "all_glucose.json"]
device = cgms
use = glucose
reporter = JSON

[report "clean_all_glucose.json"]
device = glucose
use = clean
infile = all_glucose.json
reporter = JSON

[vendor "openapscontrib.glucosetools"]
path = .
module = openapscontrib.glucosetools

[device "glucose"]
vendor = openapscontrib.glucosetools

[report "recent_history_with_dose.json"]
device = munge
use = append_dose
dose = set_dose.json
infile = recent_history.json
reporter = JSON

[report "prepared_history_with_dose.json"]
device = munge
infile = recent_history_with_dose.json
use = prepare
basal_profile = read_selected_basal_profile.json
reporter = JSON

[report "iob_history.json"]
device = predict
use = walsh_iob
settings = read_settings.json
history = prepared_history_with_dose.json
reporter = JSON

[report "insulin_effect_without_future_basal.json"]
use = walsh_insulin_effect
settings = read_settings.json
reporter = JSON
device = predict
history = normalize_history.json
basal_dosing_end = read_clock.json
insulin_sensitivities = read_insulin_sensitivies.json

[report "insulin_effect_with_dose.json"]
use = walsh_insulin_effect
settings = read_settings.json
reporter = JSON
device = predict
insulin_sensitivities = read_insulin_sensitivies.json
history = prepared_history_with_dose.json

[report "carb_effect.json"]
use = scheiner_carb_effect
reporter = JSON
carb_ratios = read_carb_ratios.json
device = predict
history = normalize_history.json
insulin_sensitivities = read_insulin_sensitivies.json

[report "predict_glucose_with_dose.json"]
device = predict
use = glucose_from_effects
glucose = clean_glucose.json
effects = ['insulin_effect_with_dose.json', 'carb_effect.json']
reporter = JSON

[report "cgms_calibrations.json"]
device = cgms
count = 3
use = iter_calibrations
reporter = JSON

[report "glucose_momentum_effect.json"]
use = glucose_momentum_effect
reporter = JSON
prediction_time = 20
device = predict
calibrations = cgms_calibrations.json
glucose = clean_glucose.json

[report "cob_history.json"]
device = predict
use = scheiner_cob
history = prepared_history_with_dose.json
reporter = JSON
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment