Pages

Tuesday, 24 November 2015

Nightscout on the 640g: Real-Time Pump Monitor

Nightscout was originally designed to display CGM data, those Sensor Glucose (SG) values that come from the Dexcom or Enlite system every five minutes.
But why stop there? 

Real-time* 640g CGM and Pump data up on Nightscout:

All of the data shown is automatically transferred from the 640g to Nightscout

*delayed by around 5 minutes due to the current bounce via CareLink

In addition to the core Nightscout code, developers** have added the Care Portal plugin for Nightscout's CGM Remote Monitor.

This currently gives you the option to enter 16 different types of T1D-related event, from a meal or correction bolus, a question to/from a carer, to inserting a new sensor or infusion set.
What a great idea to keep even more of your T1D data together and accessible.

No more text messages or Post-It Notes left at 2am to say "sensor tracking 3 units higher than BG" in case your other half gets the next alarm... 

**Jason Calabrese and Milos Kozak I think, but please correct me if I have it wrong

But I'm busy and so is everyone managing T1D. (Also I'm rubbish at typing on my touchscreen phone) I really don't want to enter data via the Nightscout CGM Remote Monitor app or browser, especially if I already have that data in the pump.

So after getting the first 640g SG and BG data up into Nightscout (see here and here for details, relying in part on Ben West's modified CSV parsing routines) the next step was to extract as much information as possible from pump. Automatically. Here's my first attempt.



All Pump Alarms
All alarms on the 640g are automatically passed to Nightscout as Announcements, recorded on the SG plot (e.g. the Basal Delivery Resumed announcement in the screen-shot above). These can be configured as per standard Nightscout Announcements to issue an alert on your device e.g. let you know SmartGuard has been triggered.

Cannula Age
Enable the CAGE plugin on Nightscout and let the pump + Nightscout automatically tell you how old the infusion set is:

Alerts can be set as per the manual site change entry, e.g. at 66 and 72 hrs

SmartGuard (Predicted Low Glucose Management)
All SmartGuard PLGM (Predicted Low Glucose Management) triggers are automatically shown, set initially at zero basal (0U) for 2 hours (the maximum time PLGM is on in one event). This time is then amended when the Basal Delivery Resumed trigger is found:
PLGM action on a school day.
Note: most other notifications turned off on this display

Temporary Basal Rates
Temporary basal rates, set manually on the pump, are automatically passed to Nightscout. They are displayed as set on the pump (e.g. in absolute units or a percentage change):
190% (+90%) basal set to try to coax down a stubborn high without putting all insulin eggs in one basket

Bolus Events, including Dual / Square Wave Cancellations
Details from the 640g's Bolus Wizard are automatically sent to Nightscout, including
  • Carbs (g)
  • Insulin delivered (units) now (Normal), shown at the time of delivery
  • Insulin delivered (units) as Square-wave (usually as component of Dual-wave), shown at the end of delivery.

We've posted before on the potential hazard of not putting back in dual-wave bolus insulin that has been interrupted by the pump initiating PLGM. The pump does not remind you about the missing bolus insulin when basal is resumed.

Therefore, any cancelled insulin is marked on a truncated square-wave bolus delivery. In the example below, a 0.5 unit, 2 hour (120 minute) square-wave component was requested at around 18:00 when Janki ate. At 19:32, PLGM kicked in and suspended the pump. Nightscout then automatically records and displays 0.35 units of the dual component delivered over the proceeding 87 minutes, but that, crucially, 0.15 units were cancelled:
Smartguard (PLGM) fires, 0.15 units of bolus is cancelled...

Could be useful for example, when checking-in on the fate of a lunchtime dual bolus at school? You'd want to double-check the bolus history on the pump before actioning of course.

Predicted SG Values
[Note: Currently disabled this on the GitHub script due to stability issues]
Along each SG value, Medtronic also include a "Predicted SG" value for use with its SmartGuard algorithm. I think this is the system's best estimate of where we - Janki - will be in 30 minutes time. Nightscout puts up a lovely range of likely predicted SG values (those open cyan/blue dots on the right). Details of this algorithm are also discussed here.  I find them very useful, but I also automatically pop the Medtronic prediction under the corresponding future time point.

These are parsed as "Notes" and appear as row of numbers under each SG value, the string of small, brown boxes in the view above. At any current time-point, it's the last number on the right (6.4 mmol/L in this case) which is of most interest.

At the moment they're there for no more than idle curiosity but may, in future, be useful when contemplating how much of a correction bolus or how many carbs to give. The rationale being that your fast acting insulin will not start to work for ~20 minutes and so it's potentially more important to know where you glucose will be at that time. At present, we guestimate or use a small Google Sheet on my phone to achieve that 'look ahead'.

How I did it
As this is not officially part of NS, I was careful to work within the existing NS infrastructure. Therefore, I haven't made any changes to my fork (version) of CGM Remote Monitor and its plugins. I've routed all the pump data through the Care Portal API using a number of additional parsers, based on the methodology originally laid down by Ben West.

I'll put these up on Github shortly, whilst also working on a number of further extensions (there's more data in each CSV). I hope others will find these ideas useful too.

This work is completely reliant on being able to build on the (open-source, open-standards) work of Nightscout developers over the years. A vast amount of work has gone into building up this application and its plugins thanks to clever people giving up their spare time to build this amazing platform. Thank-you.

A Reminder
As with previous posts on getting 640g data on to Nightscout, this is a "Proof of Principle", "First Step", "Alpha Release". You get the picture. It's clunky and it wobbles every now and then (it does rely on CareLink after all ;-) ). Therefore, I am certainly not recommending you go ahead and try this at home. 

As ever, feel free to post a comment below, on Facebook or on Twitter :-)

Update: If you've landed here looking for Nightscout on your 600-series pump, thanks for stopping by :) The simplest way to get your pump on to Nightscout is to use the 600-series Android Uploader. Enjoy!

Tuesday, 17 November 2015

Nightscout on the 640g: First Details

First, thanks to everyone who's been in touch after my post about getting the first Medtronic 640g connected to Nightscout. It's been humbling to read some of these messages and also nice to hear that it's given other 640g users - particularly those with small children - hope.

To give hope for other 640g users was exactly my intention with the post the other day. 
It can be done. It has been done.

Calm after the storm. BG and SG data - nice line, except for sensor compression...

Let's get some important bits out of the way
I am going to outline how I've pulled together this concept. I prefer to badge it as a "Proof of Principle", "First Step", "Alpha Release". You get the picture. It's clunky and it wobbles every now and then (it does rely on CareLink after all ;-) ). Therefore, I am certainly not recommending you go ahead and try this at home. I am saying this is a positive start - well, I think so. 

I'm a Medical Physicist - I solve scientific problems for a living, including writing clinical software solutions where no commercial software exists (oh, that sounds familiar...). I've had great fun over the years dreaming up and coding novel dose planning systems for internal radiation therapies, building simulations of clinical gamma and x-ray imaging systems to see how they cope at extremes and generally trying to enable the clinical work to get done as quickly and safely as possible. I am not a Software Developer or Computer Scientist*. Most of the day-job coding is in IDL - the Interactive Data Language - VB or occasionally Matlab. I'm not particularly familiar with Python, less so with Java or USB I/O.

*One of the academic computer scientists I've worked with on a few research projects was gracious enough to say that I "do a pretty good impression of being a computer scientist," which was lovely, but I've not let that go to my head ;-)

Because of all of the above I'm not going to put up online each and every line of the rough-n-ready code that's currently flung together to get this working. A robust (and hopefully more flexible) solution will emerge for sharing. I'm talking to the NS devs about the best way to tie this back in to NS if possible.

What is set out below is pretty dry if you're not at all tech-minded... If you'd rather just get a feel for what it's given us, here's a grab from Sunday night, after a weekend of general household illness, a set failure, possibly a growth spurt (again) and on the back of a recent run of dodgy Enlites (fingers crossed, the first of the new batch is doing fine!).  


We have access to the numbers literally at a glance and peace of mind (when it's available), enabling us to, I think, better manage Janki's T1D (particularly when we're both feeling unwell on top of everything). This is what Nightscout on our 640g gives us within the home.

Another pause before we dive in
We went on to the 640g in February. As mentioned in previous posts, my understanding is that (currently) the radio data-stack is not well defined or known, plus it is also encrypted. 

With a group of interested users, parents and developers sprinkled around the world, it appeared that things had stalled. There are some very clever people interested and involved - getting their brains and know-how and all the 640g kit (a pump, a Guardian 2 Link transmitter and a Bayer Contour Next Link 2.4 meter) physically together in one place has been a challenge.

The more I read and the more I saw about Nightscout, particularly the huge expansion in it's capabilities with the Funnel Cake release, the more I knew this was something I had to unlock for the 640g, particularly for classroom and overnight use.

As our four year daughter relies on her 640g insulin pump 24/7 and without a spare 640g system to test, it goes without saying that it was essential that whatever solution I came up with didn't put her (or her pump) in harms way.

Currently, the only tried and tested way of getting data out of a 640g is via CareLink. And so that's the path I've taken for this first step.

Setup Nightscout

Aim: Get our Nightscout website and associated database working

Solution: Carefully follow all the instructions set out in the setup wiki hosted by Nightscout here.

A Little More:-
By the end of the setup process, we have the following up and running
  • Mongo DB, with a unique DB name, user and password set
  • Github to fork the main Nightscout CGM Remote Monitor
  • Azure website account and website setup, including:
    • Linked to Github fork of CGM Remote Monitor
    • Correct connection strings, which must include the following names:
      • mongo
      • mongo_collection
      • API_SECRET
      • enable [for the plugins]
I didn't enter the Dexcom settings. Neither did I enable the Medtronic Connect plugin (although I'm very excited to see this being developed by Mark Wilson as I can see us using some / all of this in the months ahead!)

Nightscout (as we'll see later) expects to see glucose readings from a Dexcom G4 in mg/dL, not mmol/L so I opted to change my CareLink settings accordingly. No doubt I'll forget to change them back before the next clinic visit ;-)

Pump to CareLink -- CareLink to PC
Aim: To automatically deal with the CareLink website to request a regular data upload from the pump and then download a CSV report

Solution: Windows (7,8 or 10), Firefox, Selenium and a command line mouse clicker

A Little More:-
Firefox (along with the Firebug development tool-set) meets the requirements for CareLink uploading with its Java plugin. 

I always log in manually once a day to check all is well in CareLink Land.

The Selenium IDE enables website interactions to be recorded in a macro-like language. These instructions can then be exported to Java or Python, for example.

However, it (doesn't appear to) cope with interaction within the Java plugin used by CareLink for uploading data... Hence in the middle of the script to interact with the the CareLink site, I call a command-line based mouse clicker with a predetermined click location based on the 'Final' button location. Low tech I know (and not very robust in theory) but it works...

My script looks along these lines:-
# Goto the CareLink website (the European version in my case)
self.selenium = selenium("localhost", 4444, "*chrome", "https://carelink.minimed.eu/")

# Step along to the patient login page and pass over your username and password details for CL
sel.open("/patient/entry.jsp?bhcp=1")
sel.type("id=j_username", "YOUR_USERNAME")
sel.type("id=j_password", "YOUR_PASSWORD")
sel.click("id=loginButton")

# Once that's loaded, move to the upload page
sel.click("link=Upload Data from My Device")

# Twiddle electronic thumbs for say 30-60 seconds once Java sorts itself out
time.sleep(60)

# At this point go call your mouse clicker to left click over the Finish button

# Twiddle electronic thumbs again say for 60 seconds to allow for upload to complete
time.sleep(60)

# Now move to reports page and select CSV file download (#11)
# By default you'll get today's report (if your upload worked)
sel.click("id=toReports")
sel.click("link=Data Export (CSV)")
sel.click("css=#reportPicker11 > span.reportNav_right > #reportNav_button")

So at this point we should have downloaded the latest CSV report file from CareLink.
I do some housekeeping at this stage to make life easier later, renaming the latest file. 
In a batch file it'd look something like this:

FOR /F "delims=|" %%I IN ('DIR %DownPath%"\*.csv" /B /O:D') DO SET NewestCSV=%%I
MOVE %DownPath%\%NewestCSV% %DataPath%\%NewestCSV%
COPY %DataPath%\%NewestCSV% %DataPath%"\latest640g.csv"


Local CSV File to NightScout
Aim: Get the local CSV file, with the Sensor Glucose values, up to Nightscout

Solution: Modify Ben West's mmcsv routines; run within simple bash script using API to upload

A Little More:
Well, it turns out Ben West has already done much of ground work with some code looking at extracting details from this file and packaging them up in the JSON format Nightscout is expecting. Thank you Ben! 

His mmcsv repository has some fantastic routines scattered around, including fetch.js, that could be used to retrieve the CSV file (but not upload the pump data).

In terms of parsing the CSV data, I looked at the /lib sub-directory and the JavaScript files in the parser folder.

There are some small changes in the 640g CSV file compared to what I've seen from a Veo (ie a 530g). Fortunately the general column structure has not changed, but these tweaks alone here that may trip up some of the routines as written (before the 640g of course). At this stage four main changes were required in the JavaScript routines:
  • If you're in Europe, change the default, hardwired default time format from  MM/DD/YYTHH:mm:ss to DD/MM/YYTHH:mm:ss in /lib/utils.js, to reflect the EU CareLink format.
  • Add an Epoch date, along the lines of: function reformatDate (str) { var m = moment(str,CARELINK_TIME); return m.valueOf(); }
  • Change some of the type headings to match those expected by Nightscout
  • Change some of the pattern strings to reflect changes in the newer 640g files
As examples of the changes of type headings from Ben's code to the bits of script I run to upload our 640g data to Nightscout, I moved 'smbg' to 'mbg' (measured BG, looking for column 'BG Reading (mg/ml)') and 'cbg' to 'sgv' (sensor glucose value, looking for column 'Sensor Glucose (mg/dL)').

For each parser used I've added the epoch date (in ms) to each data packet.

As an example, here's SGV (ie one Enlite sensor 5-minute Sensor Glucose value):
{ "sgv": 100,  "type": "sgv",  "date": "1447286884000" }, ...

I run the modified code from within a bash shell script. As I'm on Windows (for CareLink), I run this within a GitHub bash shell window, which works well. Don't forget to install nodejs and update your local path accordingly. You'll also need to install mocha if you want to run the makefile and test routines.

The bash shell script is simple, running continuously looking for a suitable, new CSV file.
Once the file has been spotted (ie downloaded), I used Ben's modified JS scripts to extract the relevant data and package (in JSON) ready for Nightscout. The command is along the lines of:

./mmcsv/bin/cmd.js parse --filter=all /CSV/latest640g.csv >  /CSV/latest640g.json

I then need to get this json file (which holds each of the data packets as in the SGV example above) up to Nightscout. Whilst you could, I guess, add the records directly as Mongo DB entries, Nightscout make it easier - and safer- to do this via it's API. I use cURL to do this:

curl -vs -X POST --header "Content-Type: application/json" --header "Accept: application/json" --header "api-secret:HASH_API_SECRET" --data-binary @latest640g.json "https://YOURWEBSITE.azurewebsites.net/api/v1/entries"

NB HASH_API_SECRET is the sha1 hash of your API-SECRET, set during setup. You can use a number of online converters to do this for you (Sha1-online for example).
All being well, our SG - and any other data I've packaged accordingly will be safely and securely delivered up to our Nightscout website :-)
SG only on this one


Important Limitations
As mentioned in my first post on 640g Nightscout, it is important to remember that this is:
  • Automated for (up to a day currently) transfer of 640g CGM data into Nightscout
  • Potentially a candidate for monitoring inside the home or school classroom environment
BUT it is not:
  • Ready for prime time: this is at Proof of Principle development stage
  • Fully mobile: it is not currently as mobile as an xdrip / Dexcom receiver solution. In theory this solution would run on a small Windows 8/10 tablet.
  • Instantaneous: there is a 5-10 minute delay on SG data with the current setup
Please remember, this setup is completely reliant on the Medtronic CareLink service and its servers as well as connectivity to Nightscout:
  • I need to be able to get reliable data access to CareLink. There is no 'camping mode' fallback to avoid the need for a network connection.
  • I need to be able to take the data-hit of a 0.2-3Mb of a day's CSV file coming across my network every, say 5-10 minutes (not likely important on WiFi, but a consideration if I hook this up via 3G/4G).
  • Pump data transfers are limited in an identical way to the usual CareLink upload:
    • The transfer will fail if the pump is "busy" i.e.
      • Temp basal ongoing
      • Dual / square wave bolus ongoing

The Future
There's a ton of interesting and useful data inside each CSV file. I've used it extensively across this blog to look at how the 640g might be calibrating its Enlite Sensor Glucose readings, how SmartGuard might work (in terms of risk management) and how those pesky sensor errors pop up. Over the coming weeks I hope much of that can be transferred over to Nightscout.

I'm posting this to show other 640g users that there's NS hope, not to claim a final, polished solution exists. I'm sure there is a better way and that way will be found and developed. But I hope this represents a solid start on the journey to bringing full NS functionality to the Medtronic 640g.

None of this would be possible without the former and current Nightscout developers and the "support" team that drive CGM in the Cloud. To all of you, thank-you.

As ever, feel free to post a comment below, on Facebook or on Twitter :-)

Update: If you've landed here looking for Nightscout on your 600-series pump, thanks for stopping by :) The simplest way to get your pump on to Nightscout is to use the 600-series Android Uploader. Enjoy!

Friday, 13 November 2015

Nightscout: now on the 640g

I've been a keen follower of Nightscout and the whole We're Not Waiting movement for sometime.

However, as the Nightscout solutions have revolved around the Dexcom G4 and previous generation Medtronic pumps, we've been forced to look, but not touch the Nightscout riches.

Not any more though.

I'm sat downstairs typing this, keeping an eye on Janki's CGM readings from her Medtronic 640g upstairs via Nightscout:


And I love it as much as I thought I would :-)

What this is:

  • Automated (for up to a day currently) transfer of 640g CGM data into Nightscout
  • For remote monitoring inside the home or school classroom environment


And what it isn't:

  • Ready for prime time: this is at Proof of Principle development stage
  • Fully mobile: it is not as mobile as an xdrip / Dexcom receiver solution (read on)
  • Iinstantaneous: there is a 5-10 minute delay on SG data with the current setup
I'm posting this to show other 640g users that there's NS hope, not to claim a final, polished solution exists.


When Janki started on the 640g we knew the radio frequency would be different and that the newly minted Medtronic Nightscout port (mmcommander), then very recently released by Jesus Berian, would not work.

What I didn't realise at the time was that the radio would also be encrypted for the first time [not necessarily a bad thing as the transmitter now calculates SG as well just pushing out raw ISIG] and the radio data packet would also be shaken up...

What to do?


Well, in-between marveling at the very neat solutions - both hardware and software - coming out of Nightscout and hearing of the blood sweat and tears spent by others trying to unlock the 640g we were encouraged to read about Medtronic's MiniMed Connect launch earlier this autumn in the US (on the previous generation of pumps) and to see a community solution (led by Mark Wilson) porting that data over to Nightscout via CareLink (I did look at that code for this project, but have not included it in this solution - it does look like a great platform to develop further then Connect eventually becomes available!)

I know MM Connect exists on the 640g, at least in prototype form. However, Medtronic will not reveal a launch date for the Connect in the UK on the 640g, nor even confirm it's coming (I read a community post quoting 2017 for European release but I have no idea if that's accurate. I hope it isn't).

The Sound of Music

So I started working on a mobile solution, which focused on the pump alarms, using a sound recognition app and just required Janki to carry a small, light-weight mobile phone with her. Although that was useful and works well, particularly for monitoring in the evenings and overnight, it isn't 100% reliable and does not always relay alerts immediately.



Give me the Full Picture
But I really, really wanted Nightscout on the 640g and, after spending time with some of the wonderful UK NS Faculty and NS's one and only Wes Ton the other week, I was more determined than ever to make it work, one way or another.



Anyone reading my September blog on the remote alerts, may have picked up on my thought process of how I was going to achieve this... :-) In a nutshell, my current solution runs using a combination of batch / shell scripts to pull the CGM data from Janki's 640g via CareLink. The CSV file is then extracted from CareLink and relevant data extracted. That dataset is then sent up to our Nightscout website via the standard API using cURL. In its present form it requires a Windows 7+ laptop or tablet (due to CareLink) and an internet connection (3/4G or WiFi).

A Bayer Contour Next Link 2.4 BG meter needs to be plugged in throughout (i.e. you'd be wise to use a spare - linked - meter). The scripts are designed to run for up to 24 hours without user intervention and poll the pump every 5 minutes. [At present I'm using every 10 minutes whilst I get a better feel for any significant battery impact on the pump side - nothing of note yet].

On the Shoulders of Giants...
I'm far from the first person to do something like this in the world of CGM data.

Indeed, I believe John Costik started his remote T1D monitoring in a similar way.

I'm also indebted to Ben West who developed a small suite of utilities (mmcsv) to fetch and parse CareLink CSV files from the previous generation of Medtronic pumps. Although I wasn't able to use the fetch components, have made a number of changes to his efficient code to allow me to use it extract the CGM data from each 640g CSV file.

At the moment, I'm working through the other parameters in the CSV file. From the example data I've seen, the 640g CSV file has significantly more data locked away in it than the older Medtronic pumps. It'll be fun to get as much of that over and up into Nightscout as possible :-)

I'll try to get more info up very soon, but for now, after a week of wonky Enlite sensors and very little sleep, I'm going to leave this one here and just enjoy finally getting automated remote access to Janki's 640g CGM data.

Thank you Estelle for the spare Bayer Contour Next Link 2.4! And a huge thank-you to the developers and supporters of Nightscout who have allowed us to reclaim our T1D data.

As ever, feel free to post a comment below, on Facebook or on Twitter :-)

Update: If you've landed here looking for Nightscout on your 600-series pump, thanks for stopping by :) The simplest way to get your pump on to Nightscout is to use the 600-series Android Uploader. Enjoy!