Fully closed loop with an Open Source AID system. A possibility?

As faster insulins have become available and people have started to modify the existing code for oref1, a range of approaches are starting to be taken to try and create a fully closed loop that requires no interaction from a user in day to day life. Before we get there though, let’s take a look at the definition of “Fully Closed Loop” and compare that to what’s currently being done…

Definitions of closed loops

Back in 2009, the JDRF produced this:

It’s safe to say that with the current set of options from CamAPS, Diabeloop, Medtronic and Tandem, we’re firmly in blocks three and four. Commercially, at least, we now have closed loops that run at all times and one with assistance for mealtime manual bolusing. Additionally, DIY systems have been operating within block four for a couple of years.

Getting to block five has been, in many ways, limited by the way the insulins that have been available work. There’s been very little point in trying to eradicate the mealtime bolus when the end result is significant post prandial highs.

But as I’ve written before, Lyumjev (and perhaps to a lesser extent, Fiasp) does appear to change that.

Before we proceed, I’d like to highlight that what’s being described is highly experimental, and is not in any of the released code available within DIYAPS systems. It also uses insulin in an off-label fashion. But it does highlight the benefits of open source access to the codebase that’s in use.

What is the DIY community doing?

Back in October 2020, I published this article, written by an AndroidAPS user that had successfully started to run AndroidAPS as a fully closed loop. With some careful adjustment of standard tools within AndroidAPS and an additional piece of code, he’d finally managed to run without bolusing.

I and many others looked on and wondered whether this would work for us, and indeed, started to play with the AndroidAPS app to see if there were things that we could do.

It turned out that in it’s standard form, for many of us, the adjustments that the author of the quoted article had made didn’t really work. The main reason being that they didn’t deliver enough insulin early enough to stop those post prandial highs. So different groups went away and tried out new approaches, modifying the code of oref1 to see if there were ways that this might work.

I personally went away and tried to make oref1 work like I had previously manually used the UAM functionality in OpenAPS. This meant that I changed it to try and recognise rises that were linked to food, and therefore allow it to dose additional insulin to handle those rises, as well as other functionality to cope with periods where, post a rise, glucose levels stayed level, but on a higher value than I (or most people) would like.

And as with any experimental code, there are hits and misses. My personal approach was to try and create a “Boost” function to dose insulin early in a climb cycle, but also to try and avoid overdosing insulin, or doing so at inopportune moments. These things are much harder than you’d think, and while I’m not 100% happy that this is at a stage where it isn’t going to do something outside of when I want it to, I’m seeing results that are working very well in general. Others are taking different approaches as to how they deal with this.

Indeed, yesterday, the algorithm managed the below statistics:

Yup, not quite 100% TIR, but 99% isn’t bad. And it managed that on a day when this was what I had for breakfast:

That image comes from UnderMyFork, which allows you to take a photo of food and observe how your glucose levels change in response to it.

Overall, yesterday worked very effectively, with modified oref1 managing to maintain great glucose levels.

So it’s possible to get there, but it’s not the whole story. There are times, as you’d expect with experimental code, where thing don’t quite go according to plan, so there are safeguards built in to try and ensure that safety is maintained.

Much of the code here uses the oref1 outputs to make adjustments and then uses some of them to allow accelerated bolusing and push more insulin than oref1 would normally do.

This is being used alongside Lyumjev U200, which I’ve found works more effectively than U100 does. Even though it’s not approved for pump use, and is therefore off label, I find the smaller size doses seem to absorb more quickly than the large doses of the same number of units that U100 provides, even though historically, the pharmacokinetics woudl suggest otherwise.

But that’s just one day. What of more days than that?

A week in review…

The last week shows the following statistics:

Now I’d like to say that was with leaving the system to do it all on its own. But that wouldn’t be true. If we look at the day by day statistics, it looks a little different:

Some days are as low as 70% TIR (70-180). That’s not to say it’s not working, but cannula issues, and the phenomenon where insulin appears to become like water once glucose levels get above a certain level do come in to play, and knowledge is required to deal with it and fix those problems.

But overall it’s very promising.

It can’t all be happy and dandy?

No, there are some areas where physiology and pharmacokinetics come into play, and when the two of them collide, no post prandially dosing algorithm is going to win with the current performance of the insulins we have available.

  • High GI, high carb foods: Now I’m partial to cake and dessert. Never a good trait, and especially not where exogenous insulin is involved. And with the best will in the world, the lack of ability to get insulin directly to the liver on detection of the meal means that post prandial bolusing just doesn’t work with the tools available in DIY. Manual boluses are required to deal with these foods effectively.
  • Exercise: Unfortunately, none of these algorithms is prescient, and therefore can’t work out when you’re going to do exercise. Under a normal dosing model, you’d be recommended to reduce the amount of insulin with a meal if exercise is anticipated soon afterwards. That’s a challenge for an algorithm. You can help it out by setting higher temp targets to reduce the insulin it can deliver, but you’re then interacting and reducing that “fully closed loop” perspective.

Both of the above really require some level of human involvement in handling an almost fully closed loop, because it’s very difficult to predict unexpected things. Scheduled things, on the other hand, can be handled in a relatively straightforward manner. By the judicious use of scheduled “eating soon” and “exercise” temp targets, you can get the system to act as though it knew what was coming next. This can take some of the pressure off the user.

Additionally, you can integrate Autotune into your set-up in some cases, to try and ensure that your settings maintain sensible levels, but this doesn’t work for everyone.

But, and there is a big but, the reality is that with DIY systems, this is about as far as you can go with the current codebase. Additional functionality and insulin development is required to make a fully closed loop, where no human interaction is required.

Commercial systems have the capacity to make use of machine learning to understand patterns of highs, lows and requirements to boost or ease off insulin, so can learn about eating patterns and exercise patterns, without the need of a user to guide them. Similarly, they are supposed to make adjustments to “settings” automatically so that again, the user doesn’t need to be involved.

Is it good enough?

That’s entirely dependent on what outcomes you’re happy with.

For me, this outcome with eating a pizza:

And a predicted Hba1C of ~6% doesn’t seem too bad at all. Especially if I have to do much less to get to it.

It also highlights the benefits of open source access to the insulin dosing code within DIY systems.

But it’s not all bells and whistles, and right now, if you want to get to this, I think you have to accept that there are times where, with DIY systems at least, anticipation gets significantly better outcomes than reaction. But until then, I’m pretty happy with where this is going.


  1. Really Interesting, Keep going! I’m just trying to start out with basic looping with DIYAPS and will be happy if I get better control even with mealtime bolusing, but this has to be the ultimate aim!

  2. Great work! Do you think its possible to use automation within AndroidAPS to predict exercise based on heart rate rise, similar to the way you’ve predicted carbohydrates based on blood sugar rise? Please send me a contact to talk this through if you see a way forward.

    • Not really.

      What you’re doing with the glucose rises is allowing the algorithm to make an educated guess and react to it. The insulin involved is fast enough to just about cover this.

      With an insulin only system, you can’t remove insulin for exercise, so by the time the heart rate is up, any insulin that’s been previously applied is in action, and you can only stop additional insulin. Even the newer ones still have a long tail.

      This is where the dual hormone systems benefit, because they can deliver glucagon to counter the effects of insulin, which is what the body would normally do.

      You’d also have to fine tune a lot more carefully and use more signals than simply “heart rate rises”, as an increased heart rate isn’t only a sign of exercise and also doesn’t distinguish between exercise types, so potentially triggers when you don’t want it.

      • Thanks for the great insights. What other signals do you think could be used to predict heart rate? And what special cases would you want to put around the heart rate rising signal, to protect against unwanted “exercise predicted” actions?

1 Trackback / Pingback

  1. Review AI.APS – Cyber Type 1

Leave a Reply

Your email address will not be published.