Reports - the value of reproducibility¶
Reports can automate this by recording the output of any use to a
file. Reports make uses reproducible. Let’s peek at openaps report -h
.
usage: openaps-report [-h] [--version] {add,remove,show,invoke} ...
openaps-report - configure reports
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
## Reports Menu:
reports - manage report configurations
{add,remove,show,invoke}
Operation
add add - add a new report configuration
remove remove - remove a device configuration
show show - show all reports
invoke invoke - generate a report
Manage which devices produce which reports.
Example workflow:
Use the add, remove, show to manage which reports openaps knows about.
The add command adds a new report to the system.
The syntax is: add <name> <reporter> <device> <use>
openaps report add my-results.json json pump basals
This example registers a json output, using the pump basals command, and
stores the result in my-results.json.
The show command will list or give more details about the reports registered with openaps.
The syntax is: show [name]. The default name is '*' which should list all available reports.
openaps report show
The remove command removes the previously configured report from openaps.
The syntax is: remove <name>
openaps report remove my-results.json
This example removes the report "my-results.json" from the openaps
environment.
openaps report invoke basals
<action> <name>
The use commands allow us to interact with devices.
This is very useful for exploring and learning about what the devices
can do, but the openaps use
tool is little unwieldy if we put our
commands in a script.
For example, consider a simple script which saves the output from our
howdy
device to a file called howdy.txt
:
openaps use --format text howdy shell > howdy.txt
Now, if there were any tools that needed to use the output from
howdy
can retrieve it from the howdy.txt
file.
What if we take a more complicated example? Try running these commands:
echo {} | json -e "this.foo = 'first thing'"
echo {} | json -e "this.bar = 'second thing'"
echo {} | json -e "this.baz = 'baz thing'"
These three bash commands will echo
slightly different json
objects to the terminal. Let’s create devices for each of these, and
pretend each is some important piece of data, such as glucose data or
pump history, or bg targets.
We’ll iterate on the above to implement some fake data for this tutorial:
openaps device add fake-cgm \
process bash -c '"echo {} | json -e '\''this.cgm_fake=\"fake-cgm\"'\'' "'
openaps device add fake-pump \
process bash -c '"echo {} | json -e '\''this.pump_fake=\"fake-pump\"'\'' "'
openaps device add fake-oref0 \
process bash -c '"echo {} | json -e '\''this.oref0_fake=\"fake-oref0\"'\'' "'
Let’s assume we want to get data from all these devices in order to run an algorithm on the complete data set. The algorithm we want to run needs all the information from all three devices in a file. Just to review the uses:
Known Devices Menu:
These are the devices openaps knows about:
device Name and description:
fake-cgm process - a fake vendor to run arbitrary commands
fake-oref0 process - a fake vendor to run arbitrary commands
fake-pump process - a fake vendor to run arbitrary commands
howdy process - a fake vendor to run arbitrary commands
pump Medtronic - openaps driver for Medtronic
We can interact with the devices like this, but this just prints the information to the screen, and then it’s gone.
openaps use fake-cgm shell
openaps use fake-pump shell
openaps use fake-oref0 shell
If we wanted to get all the information into a file, we might have to do something like this:
openaps use fake-cgm shell > fake-cgm-data.txt
openaps use fake-pump shell > fake-pump-data.txt
openaps use fake-oref0 shell > fake-oref0-data.txt
Let’s try to create reports for each of our fake device uses before:
openaps report add -h
:
usage: openaps-report add [-h] report {base,text,stdout,JSON} device ...
add - add a new report configuration
positional arguments:
report
{base,text,stdout,JSON}
optional arguments:
-h, --help show this help message and exit
Known Devices Menu:
These are the devices openaps knows about:
device Name and description:
fake-cgm process - a fake vendor to run arbitrary commands
fake-oref0 process - a fake vendor to run arbitrary commands
fake-pump process - a fake vendor to run arbitrary commands
howdy process - a fake vendor to run arbitrary commands
pump Medtronic - openaps driver for Medtronic
Interesting, apparently the reports know about valid devices
also. Let’s configure a report to save the fake-cgm
shell
data into a file called fake-cgm-data.txt
:
openaps report add fake-cgm-data.txt JSON fake-cgm shell
Notice how the ...
in openaps report add <name> <format> ...
and
openaps use ...
are identical. This is a design feature to
encourage iterating through interactive usage, and then saving the
commands that work into the openaps configuration using the add
comands.
openap report add saves use configuration¶
What did this add command do?
$ openaps report add fake-cgm-data.txt JSON fake-cgm shell
added fake-cgm://JSON/shell/fake-cgm-data.txt
Let’s get a list of all our known reports: openaps report show
fake-cgm://JSON/shell/fake-cgm-data.txt
Or let’s see what happened behind the scenes with git show
:
commit 25104f7cd4e56e6cb2ca630ce06f927046a669a3
Author: Ben West <bewest@gmail.com>
Date: Sun Mar 27 18:53:11 2016 -0700
openaps-report add fake-cgm-data.txt JSON fake-cgm shell
TODO: better change descriptions
/usr/local/bin/openaps-report add fake-cgm-data.txt JSON fake-cgm shell
diff --git a/openaps.ini b/openaps.ini
index 8b1dbeb..f55161a 100644
--- a/openaps.ini
+++ b/openaps.ini
@@ -18,3 +18,10 @@ extra = fake-pump.ini
vendor = openaps.vendors.process
extra = fake-oref0.ini
+[report "fake-cgm-data.txt"]
+device = fake-cgm
+remainder = []
+use = shell
+json_default = True
+reporter = JSON
+
It modified the openaps configuration with information that matches the use configuration. It did not run the use, and it did not create the file, it only saves the configuration.
Let’s go ahead and add the others:
openaps report add howdy.txt text howdy shell
openaps report add fake-pump-data.txt JSON fake-pump shell
openaps report add fake-oref0-data.txt JSON fake-oref0 shell
Notice these add commands saves information about how were using openaps. This allows us to reproduce the same logic every time.
Show¶
Let’s take another look at openaps report show
:
fake-cgm://JSON/shell/fake-cgm-data.txt
howdy://text/shell/howdy.txt
fake-pump://JSON/shell/fake-pump-data.txt
fake-oref0://JSON/shell/fake-oref0-data.txt
Invoke¶
It’s time to generate a bunch of reports. Instead of attempting to reproduce all the uses again with all the right flags and in the right ways, we can invoke the previously saved uses.
First, if we haven’t run any reports before, our directory might look like this. There’s no data here yet, just some configuration.
$ ls
fake-cgm.ini
fake-oref0.ini
fake-pump.ini
foo.ini
howdy.ini
openaps.ini
pump.ini
Let’s try invoking a single report and see what happens:
$ openaps report invoke howdy.txt
howdy://text/shell/howdy.txt
reporting howdy.txt
$ ls
fake-cgm.ini
fake-oref0.ini
fake-pump.ini
foo.ini
howdy.ini
howdy.txt
openaps.ini
pump.ini
Now there’s a howdy.txt
file containing cat howdy.txt
:
hello world!
Invoke runs preconfigured uses¶
openaps report invoke
takes a list of any number of reports:
openaps report invoke \
fake-cgm-data.txt howdy.txt fake-pump-data.txt fake-oref0-data.txt
$ openaps report \
invoke fake-cgm-data.txt howdy.txt fake-pump-data.txt fake-oref0-data.txt
fake-cgm://JSON/shell/fake-cgm-data.txt
reporting fake-cgm-data.txt
howdy://text/shell/howdy.txt
reporting howdy.txt
fake-pump://JSON/shell/fake-pump-data.txt
reporting fake-pump-data.txt
fake-oref0://JSON/shell/fake-oref0-data.txt
reporting fake-oref0-data.txt
Now we can invoke many groups of reports in one line, save the data to their own files consistently, while referring to the preconfigured use for that device.
Each invoke
creates a new git commit in the log: openaps show
:
commit eb782e12552ad664697aa38d7e6b05b41f5e5a22
Author: Ben West <bewest@gmail.com>
Date: Sun Mar 27 19:11:37 2016 -0700
openaps-report invoke fake-cgm-data.txt howdy.txt fake-pump-data.txt fake-oref0-data.txt
TODO: better change descriptions
/usr/local/bin/openaps-report invoke fake-cgm-data.txt howdy.txt fake-pump-data.txt fake-oref0-data.txt
diff --git a/fake-cgm-data.txt b/fake-cgm-data.txt
new file mode 100644
index 0000000..f54d1ff
--- /dev/null
+++ b/fake-cgm-data.txt
@@ -0,0 +1,3 @@
+{
+ "cgm_fake": "fake-cgm"
+}
\ No newline at end of file
diff --git a/fake-oref0-data.txt b/fake-oref0-data.txt
new file mode 100644
index 0000000..adb1295
--- /dev/null
+++ b/fake-oref0-data.txt
@@ -0,0 +1,3 @@
+{
+ "oref0_fake": "fake-oref0"
+}
\ No newline at end of file
diff --git a/fake-pump-data.txt b/fake-pump-data.txt
new file mode 100644
index 0000000..d2d5bf6
--- /dev/null
+++ b/fake-pump-data.txt
@@ -0,0 +1,3 @@
+{
+ "pump_fake": "fake-pump"
+}
\ No newline at end of file
Notice, we already ran howdy
, earlier, and it did not change.
Also notice how invoke
performs the same exact logic for each
report mentioned. It is equivalent to running the exact use
for each command, saving the data in a file, and creating a log entry.
Reports are how we organize and track the data flowing through the
system. In openaps
reports reproduce uses.