Git Product home page Git Product logo

Comments (3)

scottleibrand avatar scottleibrand commented on June 30, 2024

Need to merge dev into AMA, or merge the branch @bewest used to write the new Nightscout tools.

from oref0.

bewest avatar bewest commented on June 30, 2024

Usually feature branches will keep up to date with dev/master by merging them in. In this case there some conflicts relating to mealAssist I'm not sure how to deal with.

diff --cc bin/oref0-get-profile.js
index a2fa312,e430ffc..0000000
--- a/bin/oref0-get-profile.js
+++ b/bin/oref0-get-profile.js
@@@ -17,6 -17,9 +17,9 @@@
  */

  var generate = require('oref0/lib/profile/');
+ function usage ( ) {
 -        console.log('usage: ', process.argv.slice(0, 2), '<pump_settings.json> <bg_targets.json> <insulin_sensitivities.json> <basal_profile.json> [<preferences.json>] [<carb_ratios.json>]');
++        console.log('usage: ', process.argv.slice(0, 2), '<pump_settings.json> <bg_targets.json> <insulin_sensitivities.json> <basal_profile.json> [<preferences.json>] [<carb_ratios.json>] [<temptargets.json>]');
+ }

  if (!module.parent) {

@@@ -24,12 -31,11 +31,12 @@@
      var bgtargets_input = process.argv.slice(3, 4).pop()
      var isf_input = process.argv.slice(4, 5).pop()
      var basalprofile_input = process.argv.slice(5, 6).pop()
-     var maxiob_input = process.argv.slice(6, 7).pop()
+     var preferences_input = process.argv.slice(6, 7).pop()
      var carbratio_input = process.argv.slice(7, 8).pop()
 +    var temptargets_input = process.argv.slice(8, 9).pop()

      if (!pumpsettings_input || !bgtargets_input || !isf_input || !basalprofile_input) {
-         console.log('usage: ', process.argv.slice(0, 2), '<pump_settings.json> <bg_targets.json> <insulin_sensitivities.json> <basal_profile.json> [<max_iob.json>] [<carb_ratios.json>] [<temptargets.json>]');
+         usage( );
          process.exit(1);
      }

@@@ -59,27 -65,40 +66,49 @@@
      if (typeof carbratio_input != 'undefined') {
          try {
              carbratio_data = JSON.parse(fs.readFileSync(carbratio_input, 'utf8'));
+ 
          } catch (e) {
-             console.error("Could not parse carbratio_data. Optional feature Meal Assist disabled.");
+             var msg = { error: e, msg: "Could not parse carbratio_data. Feature Meal Assist enabled but cannot find required carb_ratios.", file: carbratio_input };
+             console.error(msg.msg);
+             console.log(JSON.stringify(msg));
+             process.exit(1);
+         }
+         var errors = [ ];
+ 
+         if (!(carbratio_data.schedule && carbratio_data.schedule[0].start && carbratio_data.schedule[0].ratio)) {
+           errors.push({msg: "Carb ratio data should have an array called schedule with a start and ratio fields.", file: carbratio_input, data: carbratio_data});
+         } else {
+         }
+         if (carbratio_data.units != 'grams') {
+           errors.push({msg: "Carb ratio should have units field set to 'grams'.", file: carbratio_input, data: carbratio_data});
+         }
+         if (errors.length) {
+ 
+           errors.forEach(function (msg) {
+             console.error(msg.msg);
+           });
+           console.log(JSON.stringify(errors));
+           process.exit(1);
          }
      }
 +    var temptargets_data = { };
 +    if (typeof temptargets_input != 'undefined') {
 +        try {
 +            temptargets_data = JSON.parse(fs.readFileSync(temptargets_input, 'utf8'));
 +        } catch (e) {
 +            //console.error("Could not parse carbratio_data. Optional feature Meal Assist disabled.");
 +        }
 +    }
      //console.log(carbratio_data);
      var inputs = {
        settings: pumpsettings_data
      , targets: bgtargets_data
      , basals: basalprofile_data
      , isf: isf_data
-     , max_iob: maxiob_data.max_iob || 0
+     , max_iob: preferences.max_iob || 0
+     , skip_neutral_temps: preferences.skip_neutral_temps || false
      , carbratio: carbratio_data
 +    , temptargets: temptargets_data
      };

      var profile = generate(inputs);
diff --cc bin/oref0-meal.js
index b8222ef,785e8a3..0000000
--- a/bin/oref0-meal.js
+++ b/bin/oref0-meal.js
@@@ -20,6 -20,9 +20,9 @@@
  */

  var generate = require('oref0/lib/meal');
+ function usage ( ) {
 -        console.log('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <clock.json> [carbhistory.json]');
++        console.log('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <clock.json> [carbhistory.json] [glucose.json] [basalprofile.json]');
+ }

  if (!module.parent) {
      var pumphistory_input = process.argv.slice(2, 3).pop();
@@@ -26,12 -33,9 +33,12 @@@
      var profile_input = process.argv.slice(3, 4).pop();
      var clock_input = process.argv.slice(4, 5).pop();
      var carb_input = process.argv.slice(5, 6).pop();
 +    var glucose_input = process.argv.slice(6, 7).pop();
 +    var basalprofile_input = process.argv.slice(7, 8).pop()
 +    //var isf_input = process.argv.slice(4, 5).pop()

      if (!pumphistory_input || !profile_input) {
-         console.log('usage: ', process.argv.slice(0, 2), '<pumphistory.json> <profile.json> <clock.json> [carbhistory.json] [glucose.json] [basalprofile.json]');
+         usage( );
          process.exit(1);
      }

diff --cc lib/determine-basal/determine-basal.js
index 9d3c480,f58e772..0000000
--- a/lib/determine-basal/determine-basal.js
+++ b/lib/determine-basal/determine-basal.js
@@@ -146,95 -131,59 +146,121 @@@ var determine_basal = function determin
      if (iob_data.basaliob) { basaliob = iob_data.basaliob; }
      else { basaliob = iob_data.iob - iob_data.bolussnooze; }

 -    // net amount of basal insulin delivered over the last DIA hours
 -    var hightempinsulin = iob_data.hightempinsulin;
 -
 -    var wtfAssist=0;
 -    var mealAssist=0;
 -    var mealAssistPct = 0;
 -    //var wtfAssistPct = 0;
 -    // if BG is high (more than DIA hours of basal above max_bg, i.e. above about 220mg/dL) and rising, wtf-assist
 -    var high = profile.max_bg + ( basal * (profile.dia) * sens );
 -    if ( bg > high && minDelta > Math.max(0,bgi) ) {
 -        wtfAssist=1;
 +    // generate predicted future BGs based on IOB, COB, and current absortpion rate
 +
 +    var COBpredBGs = [];
 +    var aCOBpredBGs = [];
 +    var IOBpredBGs = [];
 +    COBpredBGs.push(bg);
 +    aCOBpredBGs.push(bg);
 +    IOBpredBGs.push(bg);
 +    //console.error(meal_data);
 +    // carb impact and duration are 0 unless changed below
 +    var ci = 0;
 +    var cid = 0;
 +    // calculate current carb absorption rate, and how long to absorb all carbs
 +    // CI = current carb impact on BG in mg/dL/5m
 +    ci = Math.round((minDelta - bgi)*10)/10;
 +    aci = 10;
 +    //5m data points = g * (1U/10g) * (40mg/dL/1U) / (mg/dL/5m)
 +    cid = meal_data.mealCOB * ( sens / profile.carb_ratio ) / ci;
 +    acid = meal_data.mealCOB * ( sens / profile.carb_ratio ) / aci;
 +    console.error("Carb Impact:",ci,"mg/dL per 5m; CI Duration:",Math.round(10*cid/6)/10,"hours");
 +    console.error("Accel. Carb Impact:",aci,"mg/dL per 5m; ACI Duration:",Math.round(10*acid/6)/10,"hours");
 +    var minPredBG = 999;
 +    var maxPredBG = bg;
 +    var eventualPredBG = bg;
 +    try {
 +        iobArray.forEach(function(iobTick) {
 +            //console.error(iobTick);
 +            predBGI = Math.round(( -iobTick.activity * sens * 5 )*100)/100;
 +            // predicted deviation impact drops linearly from current deviation down to zero
 +            // over 60 minutes (data points every 5m)
 +            predDev = ci * ( 1 - Math.min(1,IOBpredBGs.length/(60/5)) );
 +            IOBpredBG = IOBpredBGs[IOBpredBGs.length-1] + predBGI + predDev;
 +            //IOBpredBG = IOBpredBGs[IOBpredBGs.length-1] + predBGI;
 +            // predicted carb impact drops linearly from current carb impact down to zero
 +            // eventually accounting for all carbs (if they can be absorbed over DIA)
 +            predCI = Math.max(0, ci * ( 1 - COBpredBGs.length/Math.max(cid*2,1) ) );
 +            predACI = Math.max(0, aci * ( 1 - COBpredBGs.length/Math.max(acid*2,1) ) );
 +            COBpredBG = COBpredBGs[COBpredBGs.length-1] + predBGI + Math.min(0,predDev) + predCI;
 +            aCOBpredBG = aCOBpredBGs[aCOBpredBGs.length-1] + predBGI + Math.min(0,predDev) + predACI;
 +            //console.error(predBGI, predCI, predBG);
 +            IOBpredBGs.push(IOBpredBG);
 +            COBpredBGs.push(COBpredBG);
 +            aCOBpredBGs.push(aCOBpredBG);
 +            // wait 30m before setting minPredBG
 +            if ( COBpredBGs.length > 6 && (COBpredBG < minPredBG) ) { minPredBG = COBpredBG; }
 +            if ( COBpredBG > maxPredBG ) { maxPredBG = COBpredBG; }
 +        });
 +        // set eventualBG to include effect of carbs
 +        //console.error("PredBGs:",JSON.stringify(predBGs));
 +    } catch (e) {
 +        console.error("Problem with iobArray.  Optional feature Advanced Meal Assist disabled.");
      }
 -    // minDelta is > 12 and devation is > 50 wtf-assist and meal-assist
 -    var wtfDeviation=50;
 -    var wtfDelta=12;
 -    if ( deviation > wtfDeviation && minDelta > wtfDelta ) {
 -        wtfAssist=1;
 -        mealAssist=1;
 -    } else {
 -        // phase in mealAssist, as a fraction
 -        mealAssist = Math.max(0, Math.round( Math.min(deviation/wtfDeviation,minDelta/wtfDelta)*100)/100 );
 +    rT.predBGs = {};
 +    IOBpredBGs.forEach(function(p, i, theArray) {
 +        theArray[i] = Math.round(Math.min(401,Math.max(39,p)));
 +    });
 +    for (var i=IOBpredBGs.length-1; i > 12; i--) {
 +        if (IOBpredBGs[i-1] != IOBpredBGs[i]) { break; }
 +        else { IOBpredBGs.pop(); }
      }
 -    var remainingMealBolus = Math.round( (1.1 * meal_data.carbs/profile.carb_ratio - ( meal_data.boluses + Math.max(0,hightempinsulin) ) )*10)/10;
 -        // if minDelta is >3 and >BGI, and there are uncovered carbs, meal-assist
 -    if ( minDelta > Math.max(3, bgi) && meal_data.carbs > 0 && remainingMealBolus > 0 ) {
 -        mealAssist=1;
 +    rT.predBGs.IOB = IOBpredBGs;
 +    if (meal_data.mealCOB > 0) {
 +        aCOBpredBGs.forEach(function(p, i, theArray) {
 +            theArray[i] = Math.round(Math.min(401,Math.max(39,p)));
 +        });
 +        for (var i=aCOBpredBGs.length-1; i > 12; i--) {
 +            if (aCOBpredBGs[i-1] != aCOBpredBGs[i]) { break; }
 +            else { aCOBpredBGs.pop(); }
 +        }
 +        rT.predBGs.aCOB = aCOBpredBGs;
      }
++<<<<<<< HEAD
 +    if (meal_data.mealCOB > 0 && minDelta > bgi ) {
 +        COBpredBGs.forEach(function(p, i, theArray) {
 +            theArray[i] = Math.round(Math.min(401,Math.max(39,p)));
 +        });
 +        for (var i=COBpredBGs.length-1; i > 12; i--) {
 +            if (COBpredBGs[i-1] != COBpredBGs[i]) { break; }
 +            else { COBpredBGs.pop(); }
 +        }
 +        rT.predBGs.COB = COBpredBGs;
 +        eventualBG = Math.max(eventualBG, Math.round(COBpredBGs[COBpredBGs.length-1]) );
 +        rT.eventualBG = eventualBG;
 +        minPredBG = Math.min(minPredBG, eventualBG);
 +        // set snoozeBG to minPredBG
 +        snoozeBG = Math.round(Math.max(snoozeBG,minPredBG));
 +        rT.snoozeBG = snoozeBG;
++=======
+     // when rising with carbs or rising fast for no good reason, meal-assist (ignore bolus IOB)
+     if (typeof(meal_data.carbs) == 'undefined') {
+         var wtfAssist=0;
+         var mealAssist=0;
+     }
+     if (mealAssist > 0) {
+         // ignore all covered IOB, and just set eventualBG to the current bg
+         mAeventualBG = Math.max(bg,eventualBG) + deviation;
+         eventualBG = Math.round(mealAssist*mAeventualBG + (1-mealAssist)*eventualBG);
+         rT.eventualBG = eventualBG;
+         //console.error("eventualBG: "+eventualBG+", mAeventualBG: "+mAeventualBG+", rT.eventualBG: "+rT.eventualBG);
+     }
+     // lower target for meal-assist or wtf-assist (high and rising)
+     wtfAssist = Math.round( Math.max(wtfAssist, mealAssist) *100)/100;
+     if (wtfAssist > 0) {
+         min_bg = wtfAssist*80 + (1-wtfAssist)*min_bg;
+         target_bg = (min_bg + profile.max_bg) / 2;
+         expectedDelta = Math.round(( bgi + ( target_bg - eventualBG ) / ( profile.dia * 60 / 5 ) )*10)/10;
+         mealAssistPct = Math.round(mealAssist*100);
+         wtfAssistPct = Math.round(wtfAssist*100);
+         rT.mealAssist = "On: "+mealAssistPct+"%, "+wtfAssistPct+"%, Carbs: " + meal_data.carbs + " Boluses: " + meal_data.boluses + " ISF: " + sens + ", Target: " + Math.round(target_bg) + " Deviation: " + deviation + " BGI: " + bgi;
+     } else {
+         rT.mealAssist = "Off: Carbs: " + meal_data.carbs + " Boluses: " + meal_data.boluses + " ISF: " + sens + ", Target: " + Math.round(target_bg) + " Deviation: " + deviation + " BGI: " + bgi;
++>>>>>>> dev
      }

 -    rT.reason="";
 +    rT.reason="COB: " + meal_data.mealCOB + ", Dev: " + deviation + ", BGI: " + bgi + ", ISF: " + sens + ", Target: " + target_bg + "; ";
      if (bg < threshold) { // low glucose suspend mode: BG is < ~80
          rT.reason += "BG " + bg + "<" + threshold;
          if ((glucose_status.delta <= 0 && minDelta <= 0) || (glucose_status.delta < expectedDelta && minDelta < expectedDelta) || bg < 60 ) {
diff --cc lib/profile/targets.js
index 35b9235,2a696b0..0000000
--- a/lib/profile/targets.js
+++ b/lib/profile/targets.js
@@@ -56,11 -25,10 +56,16 @@@ function lookup (inputs) 

  function bound_target_range (target) {
      // hard-code lower bounds for min_bg and max_bg in case pump is set too low, or units are wrong
++<<<<<<< HEAD
 +    target.max_bg = Math.max(80, target.high);
 +    target.min_bg = Math.max(80, target.low);
++=======
+     target.max_bg = Math.max(90, target.high);
+     target.min_bg = Math.max(90, target.low);
++>>>>>>> dev
      // hard-code upper bound for min_bg in case pump is set too high
      target.min_bg = Math.min(200, target.min_bg);
 +    target.max_bg = Math.min(200, target.max_bg);
      return target
  }

from oref0.

bewest avatar bewest commented on June 30, 2024

Fixed by #125

from oref0.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.