OpenAPS 0.6.0 1st part

This commit is contained in:
Milos Kozak 2017-12-11 18:45:04 +01:00
parent c714fead24
commit b1c4f28eb7
23 changed files with 891 additions and 396 deletions

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,7 @@ public class Config {
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER;
public static final boolean displayDeviationSlope = false;
public static final boolean displayDeviationSlope = true;
public static final boolean detailedLog = true;
public static final boolean logFunctionCalls = true;

View file

@ -35,6 +35,7 @@ public class GlucoseStatus {
public double avgdelta = 0d;
public double short_avgdelta = 0d;
public double long_avgdelta = 0d;
public long date = 0L;
@Override
@ -126,6 +127,7 @@ public class GlucoseStatus {
GlucoseStatus status = new GlucoseStatus();
status.glucose = now.value;
status.date = now_date;
status.short_avgdelta = average(short_deltas);

View file

@ -24,6 +24,10 @@ public class IobTotal {
public double microBolusInsulin;
public double microBolusIOB;
public long lastBolusTime;
public long lastTempDate;
public int lastTempDuration;
public double lastTempRate;
public IobTotal iobWithZeroTemp;
public double netInsulin = 0d; // for calculations from temp basals only
public double netRatio = 0d; // net ratio at start of temp basal
@ -32,6 +36,25 @@ public class IobTotal {
long time;
public IobTotal clone() {
IobTotal copy = new IobTotal(time);
copy.iob = iob;
copy.activity = activity;
copy.bolussnooze = bolussnooze;
copy.basaliob = basaliob;
copy.netbasalinsulin = netbasalinsulin;
copy.hightempinsulin = hightempinsulin;
copy.microBolusInsulin = microBolusInsulin;
copy.microBolusIOB = microBolusIOB;
copy.lastBolusTime = lastBolusTime;
copy.lastTempDate = lastTempDate;
copy.lastTempDuration = lastTempDuration;
copy.lastTempRate = lastTempRate;
copy.iobWithZeroTemp = iobWithZeroTemp;
return copy;
}
public IobTotal(long time) {
this.iob = 0d;
this.activity = 0d;
@ -70,6 +93,10 @@ public class IobTotal {
result.microBolusInsulin = bolusIOB.microBolusInsulin + basalIob.microBolusInsulin;
result.microBolusIOB = bolusIOB.microBolusIOB + basalIob.microBolusIOB;
result.lastBolusTime = bolusIOB.lastBolusTime;
result.lastTempDate = basalIob.lastTempDate;
result.lastTempRate = basalIob.lastTempRate;
result.lastTempDuration = basalIob.lastTempDuration;
result.iobWithZeroTemp = basalIob.iobWithZeroTemp;
return result;
}
@ -107,6 +134,22 @@ public class IobTotal {
json.put("activity", activity);
json.put("lastBolusTime", lastBolusTime);
json.put("time", DateUtil.toISOString(new Date(time)));
/*
This is requested by SMB determine_basal but by based on Scott's info
it's MDT specific safety check only
It's causing rounding issues in determine_basal
JSONObject lastTemp = new JSONObject();
lastTemp.put("date", lastTempDate);
lastTemp.put("rate", lastTempRate);
lastTemp.put("duration", lastTempDuration);
json.put("lastTemp", lastTemp);
*/
if (iobWithZeroTemp != null) {
JSONObject iwzt = iobWithZeroTemp.determineBasalJson();
json.put("iobWithZeroTemp", iwzt);
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}

View file

@ -7,6 +7,8 @@ public class MealData {
public double boluses = 0d;
public double carbs = 0d;
public double mealCOB = 0.0d;
public double minDeviationSlope;
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public long lastBolusTime;
public long lastCarbTime = 0L;
}

View file

@ -46,6 +46,7 @@ public class BgReading implements DataPointWithLabelInterface {
public boolean isaCOBPrediction = false; // true when drawing predictions as bg points (aCOB)
public boolean isIOBPrediction = false; // true when drawing predictions as bg points (IOB)
public boolean isUAMPrediction = false; // true when drawing predictions as bg points (UAM)
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
public BgReading() {
}
@ -228,11 +229,13 @@ public class BgReading implements DataPointWithLabelInterface {
return 0x80FFFFFF & MainApp.sResources.getColor(R.color.cob);
if (isUAMPrediction)
return MainApp.sResources.getColor(R.color.uam);
if (isZTPrediction)
return MainApp.sResources.getColor(R.color.zt);
return R.color.mdtp_white;
}
private boolean isPrediction() {
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction;
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
}
}

View file

@ -10,16 +10,16 @@ import info.nightscout.androidaps.db.Treatment;
*/
public interface InsulinInterface {
final int FASTACTINGINSULIN = 0;
final int FASTACTINGINSULINPROLONGED = 1;
final int OREF_RAPID_ACTING = 2;
final int OREF_ULTRA_RAPID_ACTING = 3;
final int OREF_FREE_PEAK = 4;
int FASTACTINGINSULIN = 0;
int FASTACTINGINSULINPROLONGED = 1;
int OREF_RAPID_ACTING = 2;
int OREF_ULTRA_RAPID_ACTING = 3;
int OREF_FREE_PEAK = 4;
int getId();
String getFriendlyName();
String getComment();
double getDia();
public Iob iobCalcForTreatment(Treatment treatment, long time, Double dia);
Iob iobCalcForTreatment(Treatment treatment, long time, Double dia);
}

View file

@ -61,10 +61,11 @@ public class AutosensData {
public double avgDeviation = 0d;
public double autosensRatio = 1d;
public double minDeviationSlope = 999;
public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999;
public String log(long time) {
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " minDeviationSlope=" + minDeviationSlope;
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Delta=" + delta + " avgDelta=" + avgDelta + " Bgi=" + bgi + " Deviation=" + deviation + " avgDeviation=" + avgDeviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob + " autosensRatio=" + autosensRatio + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation =" + slopeFromMinDeviation ;
}
public int minOld() {

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.BasalData;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
/**
* Created by mike on 24.04.2017.
@ -402,8 +403,10 @@ public class IobCobCalculatorPlugin implements PluginBase {
double avgDeviation = Math.round((avgDelta - bgi) * 1000) / 1000;
double currentDeviation;
double minDeviationSlope = 0;
double slopeFromMaxDeviation = 0;
double slopeFromMinDeviation = 999;
double maxDeviation = 0;
double minDeviation = 999;
// https://github.com/openaps/oref0/blob/master/lib/determine-basal/cob-autosens.js#L169
if (i < bucketed_data.size() - 16) { // we need 1h of data to calculate minDeviationSlope
@ -416,10 +419,16 @@ public class IobCobCalculatorPlugin implements PluginBase {
AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
double deviationSlope = (ad.avgDeviation - currentDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) {
minDeviationSlope = Math.min(0, deviationSlope);
slopeFromMaxDeviation = Math.min(0, deviationSlope);
maxDeviation = ad.avgDeviation;
}
log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " minDeviationSlope=" + minDeviationSlope);
if (avgDeviation < minDeviation) {
slopeFromMinDeviation = Math.max(0, deviationSlope);
minDeviation = avgDeviation;
}
//if (Config.logAutosensData)
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation);
}
}
@ -454,7 +463,8 @@ public class IobCobCalculatorPlugin implements PluginBase {
autosensData.delta = delta;
autosensData.avgDelta = avgDelta;
autosensData.avgDeviation = avgDeviation;
autosensData.minDeviationSlope = minDeviationSlope;
autosensData.slopeFromMaxDeviation = slopeFromMaxDeviation;
autosensData.slopeFromMinDeviation = slopeFromMinDeviation;
// calculate autosens only without COB
if (autosensData.cob <= 0) {
@ -477,8 +487,8 @@ public class IobCobCalculatorPlugin implements PluginBase {
previous = autosensData;
autosensDataTable.put(bgTime, autosensData);
autosensData.autosensRatio = detectSensitivity(oldestTimeWithData, bgTime).ratio;
if (Config.logAutosensData)
log.debug(autosensData.log(bgTime));
//if (Config.logAutosensData)
// log.debug(autosensData.log(bgTime));
}
}
MainApp.bus().post(new EventAutosensCalculationFinished());
@ -511,6 +521,21 @@ public class IobCobCalculatorPlugin implements PluginBase {
}
IobTotal bolusIob = MainApp.getConfigBuilder().getCalculationToTimeTreatments(time).round();
IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round();
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
// Add expected zere temp basal for next 240 mins
IobTotal basalIobWithZeroTemp = basalIob.clone();
TemporaryBasal t = new TemporaryBasal();
t.date = now + 60 * 1000L;
t.durationInMinutes = 240;
t.isAbsolute = true;
t.absoluteRate = 0;
if (t.date < time) {
IobTotal calc = t.iobCalc(time);
basalIobWithZeroTemp.plus(calc);
}
basalIob.iobWithZeroTemp = basalIobWithZeroTemp;
}
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
if (time < System.currentTimeMillis()) {
@ -605,6 +630,23 @@ public class IobCobCalculatorPlugin implements PluginBase {
return array;
}
public static IobTotal[] calculateIobArrayForSMB() {
Profile profile = MainApp.getConfigBuilder().getProfile();
// predict IOB out to DIA plus 30m
long time = System.currentTimeMillis();
time = roundUpTime(time);
int len = (4 * 60) / 5;
IobTotal[] array = new IobTotal[len];
int pos = 0;
for (int i = 0; i < len; i++) {
long t = time + i * 5 * 60000;
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t);
array[pos] = iob;
pos++;
}
return array;
}
public static AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
synchronized (dataLock) {
return detectSensitivity(fromTime, toTime);

View file

@ -143,6 +143,16 @@ public class APSResult {
array.add(bg);
}
}
if (predBGs.has("ZT")) {
JSONArray iob = predBGs.getJSONArray("ZT");
for (int i = 1; i < iob.length(); i++) {
BgReading bg = new BgReading();
bg.value = iob.getInt(i);
bg.date = startTime + i * 5 * 60 * 1000L;
bg.isZTPrediction = true;
array.add(bg);
}
}
}
} catch (JSONException e) {
e.printStackTrace();
@ -172,6 +182,10 @@ public class APSResult {
JSONArray iob = predBGs.getJSONArray("UAM");
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
}
if (predBGs.has("ZT")) {
JSONArray iob = predBGs.getJSONArray("ZT");
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
}
}
} catch (JSONException e) {
e.printStackTrace();

View file

@ -29,6 +29,7 @@ import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
import info.nightscout.utils.SP;
public class DetermineBasalAdapterAMAJS {
@ -189,8 +190,7 @@ public class DetermineBasalAdapterAMAJS {
GlucoseStatus glucoseStatus,
MealData mealData,
double autosensDataRatio,
boolean tempTargetSet,
double min_5m_carbimpact) throws JSONException {
boolean tempTargetSet) throws JSONException {
String units = profile.getUnits();
@ -211,7 +211,7 @@ public class DetermineBasalAdapterAMAJS {
mProfile.put("current_basal", basalrate);
mProfile.put("temptargetSet", tempTargetSet);
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
mProfile.put("min_5m_carbimpact", SP.getInt("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
if (units.equals(Constants.MMOL)) {
mProfile.put("out_units", "mmol/L");

View file

@ -233,8 +233,7 @@ public class OpenAPSAMAPlugin implements PluginBase, APSInterface {
try {
determineBasalAdapterAMAJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio
isTempTarget,
SafeParse.stringToDouble(SP.getString("openapsama_min_5m_carbimpact", "3.0"))//min_5m_carbimpact
isTempTarget
);
} catch (JSONException e) {
log.error("Unable to set data: " + e.toString());

View file

@ -17,7 +17,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
@ -25,14 +24,13 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.GlucoseStatus;
import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
import info.nightscout.androidaps.plugins.Loop.ScriptReader;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.plugins.OpenAPSAMA.DetermineBasalResultAMA;
import info.nightscout.androidaps.plugins.OpenAPSMA.LoggerCallback;
import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse;
public class DetermineBasalAdapterSMBJS {
private static Logger log = LoggerFactory.getLogger(DetermineBasalAdapterSMBJS.class);
@ -216,7 +214,7 @@ public class DetermineBasalAdapterSMBJS {
String units = profile.getUnits();
mProfile = new JSONObject();
;
mProfile.put("max_iob", maxIob);
mProfile.put("dia", profile.getDia());
mProfile.put("type", "current");
@ -229,26 +227,32 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("sens", Profile.toMgdl(profile.getIsf().doubleValue(), units));
mProfile.put("max_daily_safety_multiplier", SP.getInt("openapsama_max_daily_safety_multiplier", 3));
mProfile.put("current_basal_safety_multiplier", SP.getInt("openapsama_current_basal_safety_multiplier", 4));
mProfile.put("skip_neutral_temps", true);
mProfile.put("high_temptarget_raises_sensitivity", SMBDefaults.high_temptarget_raises_sensitivity);
mProfile.put("low_temptarget_lowers_sensitivity", SMBDefaults.low_temptarget_lowers_sensitivity);
mProfile.put("sensitivity_raises_target", SMBDefaults.sensitivity_raises_target);
mProfile.put("resistance_lowers_target", SMBDefaults.resistance_lowers_target);
mProfile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments);
mProfile.put("exercise_mode", SMBDefaults.exercise_mode);
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
mProfile.put("maxCOB", SMBDefaults.maxCOB);
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
mProfile.put("min_5m_carbimpact", SP.getInt("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_use_smb, false) && SMBDefaults.enableSMB_with_COB);
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SMBDefaults.enableSMB_with_temptarget);
mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_use_smb, false) && SMBDefaults.enableSMB_after_carbs);
mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_use_smb, false) && SMBDefaults.allowSMB_with_high_temptarget);
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
mProfile.put("current_basal", basalrate);
mProfile.put("temptargetSet", tempTargetSet);
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", 3d));
mProfile.put("enableSMB_with_bolus", SP.getBoolean(R.string.key_use_smb, false));
mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_use_smb, false));
mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_use_smb, false));
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("adv_target_adjustments", true); // lower target automatically when BG and eventualBG are high
// create maxCOB and default it to 120 because that's the most a typical body can absorb over 4 hours.
// (If someone enters more carbs or stacks more; OpenAPS will just truncate dosing based on 120.
// Essentially, this just limits AMA as a safety cap against weird COB calculations)
mProfile.put("maxCOB", 120);
mProfile.put("autotune_isf_adjustmentFraction", 0.5); // keep autotune ISF closer to pump ISF via a weighted average of fullNewISF and pumpISF. 1.0 allows full adjustment, 0 is no adjustment from pump ISF.
mProfile.put("remainingCarbsFraction", 1.0d); // fraction of carbs we'll assume will absorb over 4h if we don't yet see carb absorption
mProfile.put("remainingCarbsCap", 90); // max carbs we'll assume will absorb over 4h if we don't yet see carb absorption
mProfile.put("autosens_max", SafeParse.stringToDouble(SP.getString("openapsama_autosens_max", "1.2")));
mCurrentTemp = new JSONObject();
;
mCurrentTemp.put("temp", "absolute");
mCurrentTemp.put("duration", MainApp.getConfigBuilder().getTempBasalRemainingMinutesFromHistory());
mCurrentTemp.put("rate", MainApp.getConfigBuilder().getTempBasalAbsoluteRateHistory());
@ -262,7 +266,6 @@ public class DetermineBasalAdapterSMBJS {
mIobData = IobCobCalculatorPlugin.convertToJSONArray(iobArray);
mGlucoseStatus = new JSONObject();
;
mGlucoseStatus.put("glucose", glucoseStatus.glucose);
if (SP.getBoolean("always_use_shortavg", false)) {
@ -272,14 +275,17 @@ public class DetermineBasalAdapterSMBJS {
}
mGlucoseStatus.put("short_avgdelta", glucoseStatus.short_avgdelta);
mGlucoseStatus.put("long_avgdelta", glucoseStatus.long_avgdelta);
mGlucoseStatus.put("date", glucoseStatus.date);
mMealData = new JSONObject();
;
mMealData.put("carbs", mealData.carbs);
mMealData.put("boluses", mealData.boluses);
mMealData.put("mealCOB", mealData.mealCOB);
mMealData.put("minDeviationSlope", mealData.minDeviationSlope);
mMealData.put("slopeFromMaxDeviation", mealData.slopeFromMaxDeviation);
mMealData.put("slopeFromMinDeviation", mealData.slopeFromMinDeviation);
mMealData.put("lastBolusTime", mealData.lastBolusTime);
mMealData.put("lastCarbTime", mealData.lastCarbTime);
if (MainApp.getConfigBuilder().isAMAModeEnabled()) {
mAutosensData = new JSONObject();

View file

@ -65,8 +65,8 @@ public class OpenAPSSMBFragment extends SubscriberFragment implements View.OnCli
public void onClick(View view) {
switch (view.getId()) {
case R.id.openapsma_run:
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSAMA button");
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_AMA_Run"));
OpenAPSSMBPlugin.getPlugin().invoke("OpenAPSSMB button");
Answers.getInstance().logCustom(new CustomEvent("OpenAPS_SMB_Run"));
break;
}

View file

@ -110,7 +110,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
@Override
public int getPreferencesId() {
return R.xml.pref_openapsama;
return R.xml.pref_openapssmb;
}
@Override
@ -188,7 +188,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
Date start = new Date();
Date startPart = new Date();
IobTotal[] iobArray = IobCobCalculatorPlugin.calculateIobArrayInDia();
IobTotal[] iobArray = IobCobCalculatorPlugin.calculateIobArrayForSMB();
Profiler.log(log, "calculateIobArrayInDia()", startPart);
startPart = new Date();
@ -229,7 +229,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
lastAutosensResult = new AutosensResult();
}
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
Profiler.log(log, "AMA data gathering", start);
Profiler.log(log, "SMB data gathering", start);
start = new Date();
try {
@ -263,7 +263,7 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
try {
determineBasalResultSMB.json.put("timestamp", DateUtil.toISOString(now));
} catch (JSONException e) {
e.printStackTrace();
log.error("Unhandled exception", e);
}
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;

View file

@ -0,0 +1,64 @@
package info.nightscout.androidaps.plugins.OpenAPSSMB;
/**
* Created by mike on 10.12.2017.
*/
public class SMBDefaults {
// CALCULATED OR FROM PREFS
// max_iob: 0 // if max_iob is not provided, will default to zero
// max_daily_safety_multiplier:3
// current_basal_safety_multiplier:4
// autosens_max:1.2
// autosens_min:0.7
// USED IN AUTOSENS
public final static boolean rewind_resets_autosens = true; // reset autosensitivity to neutral for awhile after each pump rewind
// USED IN TARGETS
// by default the higher end of the target range is used only for avoiding bolus wizard overcorrections
// use wide_bg_target_range: true to force neutral temps over a wider range of eventualBGs
public final static boolean wide_bg_target_range = false; // by default use only the low end of the pump's BG target range as OpenAPS target
// USED IN AUTOTUNE
public final static double autotune_isf_adjustmentFraction = 1.0; // keep autotune ISF closer to pump ISF via a weighted average of fullNewISF and pumpISF. 1.0 allows full adjustment, 0 is no adjustment from pump ISF.
public final static double remainingCarbsFraction = 1.0; // fraction of carbs we'll assume will absorb over 4h if we don't yet see carb absorption
// USED IN DETERMINE_BASAL
public final static boolean low_temptarget_lowers_sensitivity = false; // lower sensitivity for temptargets <= 99.
public final static boolean high_temptarget_raises_sensitivity = false; // raise sensitivity for temptargets >= 111. synonym for exercise_mode
public final static boolean sensitivity_raises_target = true; // raise BG target when autosens detects sensitivity
public final static boolean resistance_lowers_target = false; // lower BG target when autosens detects resistance
public final static boolean adv_target_adjustments = false; // lower target automatically when BG and eventualBG are high
public final static boolean exercise_mode = false; // when true, > 105 mg/dL high temp target adjusts sensitivityRatio for exercise_mode. This majorly changes the behavior of high temp targets from before. synonmym for high_temptarget_raises_sensitivity
public final static int half_basal_exercise_target = 160; // when temptarget is 160 mg/dL *and* exercise_mode=true, run 50% basal at this level (120 = 75%; 140 = 60%)
// create maxCOB and default it to 120 because that's the most a typical body can absorb over 4 hours.
// (If someone enters more carbs or stacks more; OpenAPS will just truncate dosing based on 120.
// Essentially, this just limits AMA/SMB as a safety cap against excessive COB entry)
public final static int maxCOB = 120;
public final static boolean skip_neutral_temps = true; // ***** default false in oref1 ***** if true, don't set neutral temps
// unsuspend_if_no_temp:false // if true, pump will un-suspend after a zero temp finishes
// bolussnooze_dia_divisor:2 // bolus snooze decays after 1/2 of DIA
public final static int min_5m_carbimpact = 8; // mg/dL per 5m (8 mg/dL/5m corresponds to 24g/hr at a CSF of 4 mg/dL/g (x/5*60/4))
public final static int remainingCarbsCap = 90; // max carbs we'll assume will absorb over 4h if we don't yet see carb absorption
// WARNING: use SMB with caution: it can and will automatically bolus up to max_iob worth of extra insulin
// enableUAM:true // enable detection of unannounced meal carb absorption
public final static boolean A52_risk_enable = false;
public final static boolean enableSMB_with_COB = true; // ***** default false in oref1 ***** enable supermicrobolus while COB is positive
public final static boolean enableSMB_with_temptarget = true; // ***** default false in oref1 ***** enable supermicrobolus for eating soon temp targets
// *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar
// xDrip+, LimiTTer, etc. do not properly filter out high-noise SGVs
// Using SMB overnight with such data sources risks causing a dangerous overdose of insulin
// if the CGM sensor reads falsely high and doesn't come down as actual BG does
public final static boolean enableSMB_always = false; // always enable supermicrobolus (unless disabled by high temptarget)
// *** WARNING *** DO NOT USE enableSMB_always or enableSMB_after_carbs with xDrip+, Libre, or similar
public final static boolean enableSMB_after_carbs = false; // enable supermicrobolus for 6h after carbs, even with 0 COB
public final static boolean allowSMB_with_high_temptarget = false; // allow supermicrobolus (if otherwise enabled) even with high temp targets
public final static int maxSMBBasalMinutes = 30; // maximum minutes of basal that can be delivered as a single SMB with uncovered COB
// curve:"rapid-acting" // Supported curves: "bilinear", "rapid-acting" (Novolog, Novorapid, Humalog, Apidra) and "ultra-rapid" (Fiasp)
// useCustomPeakTime:false // allows changing insulinPeakTime
// insulinPeakTime:75 // number of minutes after a bolus activity peaks. defaults to 55m for Fiasp if useCustomPeakTime: false
public final static int carbsReqThreshold = 1; // grams of carbsReq to trigger a pushover
// offline_hotspot:false // enabled an offline-only local wifi hotspot if no Internet available
}

View file

@ -398,21 +398,21 @@ public class GraphData {
// scale in % of vertical size (like 0.3)
public void addRatio(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) {
LineGraphSeries<DataPoint> ratioSeries;
List<DataPoint> ratioArray = new ArrayList<>();
LineGraphSeries<ScaledDataPoint> ratioSeries;
List<ScaledDataPoint> ratioArray = new ArrayList<>();
Double maxRatioValueFound = 0d;
Scale ratioScale = new Scale(-1d);
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
if (autosensData != null) {
ratioArray.add(new DataPoint(time, autosensData.autosensRatio));
ratioArray.add(new ScaledDataPoint(time, autosensData.autosensRatio, ratioScale));
maxRatioValueFound = Math.max(maxRatioValueFound, Math.abs(autosensData.autosensRatio));
}
}
// RATIOS
DataPoint[] ratioData = new DataPoint[ratioArray.size()];
ScaledDataPoint[] ratioData = new ScaledDataPoint[ratioArray.size()];
ratioData = ratioArray.toArray(ratioData);
ratioSeries = new LineGraphSeries<>(ratioData);
ratioSeries.setColor(MainApp.sResources.getColor(R.color.ratio));
@ -428,32 +428,46 @@ public class GraphData {
// scale in % of vertical size (like 0.3)
public void addDeviationSlope(GraphView graph, long fromTime, long toTime, boolean useForScale, double scale) {
LineGraphSeries<DataPoint> dsSeries;
List<DataPoint> dsArray = new ArrayList<>();
Double maxDSValueFound = 0d;
Scale dsScale = new Scale();
LineGraphSeries<ScaledDataPoint> dsMaxSeries;
LineGraphSeries<ScaledDataPoint> dsMinSeries;
List<ScaledDataPoint> dsMaxArray = new ArrayList<>();
List<ScaledDataPoint> dsMinArray = new ArrayList<>();
Double maxFromMaxValueFound = 0d;
Double maxFromMinValueFound = 0d;
Scale dsMaxScale = new Scale();
Scale dsMinScale = new Scale();
for (long time = fromTime; time <= toTime; time += 5 * 60 * 1000L) {
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
if (autosensData != null) {
dsArray.add(new DataPoint(time, autosensData.minDeviationSlope));
maxDSValueFound = Math.max(maxDSValueFound, Math.abs(autosensData.minDeviationSlope));
dsMaxArray.add(new ScaledDataPoint(time, autosensData.slopeFromMaxDeviation, dsMaxScale));
dsMinArray.add(new ScaledDataPoint(time, autosensData.slopeFromMinDeviation, dsMinScale));
maxFromMaxValueFound = Math.max(maxFromMaxValueFound, Math.abs(autosensData.slopeFromMaxDeviation));
maxFromMinValueFound = Math.max(maxFromMinValueFound, Math.abs(autosensData.slopeFromMinDeviation));
}
}
// RATIOS
DataPoint[] ratioData = new DataPoint[dsArray.size()];
ratioData = dsArray.toArray(ratioData);
dsSeries = new LineGraphSeries<>(ratioData);
dsSeries.setColor(Color.MAGENTA);
dsSeries.setThickness(3);
// Slopes
ScaledDataPoint[] ratioMaxData = new ScaledDataPoint[dsMaxArray.size()];
ratioMaxData = dsMaxArray.toArray(ratioMaxData);
dsMaxSeries = new LineGraphSeries<>(ratioMaxData);
dsMaxSeries.setColor(Color.MAGENTA);
dsMaxSeries.setThickness(3);
ScaledDataPoint[] ratioMinData = new ScaledDataPoint[dsMinArray.size()];
ratioMinData = dsMinArray.toArray(ratioMinData);
dsMinSeries = new LineGraphSeries<>(ratioMinData);
dsMinSeries.setColor(Color.YELLOW);
dsMinSeries.setThickness(3);
if (useForScale)
maxY = maxDSValueFound;
maxY = Math.max(maxFromMaxValueFound, maxFromMinValueFound);
dsScale.setMultiplier(maxY * scale / maxDSValueFound);
dsMaxScale.setMultiplier(maxY * scale / maxFromMaxValueFound);
dsMinScale.setMultiplier(maxY * scale / maxFromMinValueFound);
addSeriesWithoutInvalidate(graph, dsSeries);
addSeriesWithoutInvalidate(graph, dsMaxSeries);
addSeriesWithoutInvalidate(graph, dsMinSeries);
}
// scale in % of vertical size (like 0.3)

View file

@ -250,6 +250,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
if (t > dia_ago && t <= now) {
if (treatment.carbs >= 1) {
result.carbs += treatment.carbs;
result.lastCarbTime = t;
}
if (treatment.insulin > 0 && treatment.mealBolus) {
result.boluses += treatment.insulin;
@ -260,7 +261,8 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
AutosensData autosensData = IobCobCalculatorPlugin.getLastAutosensData();
if (autosensData != null) {
result.mealCOB = autosensData.cob;
result.minDeviationSlope = autosensData.minDeviationSlope;
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation;
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation;
}
result.lastBolusTime = getLastBolusTime();
return result;
@ -349,6 +351,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
IobTotal calc = t.iobCalc(time);
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob);
total.plus(calc);
if (!t.isEndingEvent()) {
total.lastTempDate = t.date;
total.lastTempDuration = t.durationInMinutes;
total.lastTempRate = t.tempBasalConvertedToAbsolute(t.date);
}
}
}
if (ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) {
@ -359,6 +367,12 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
if (e.date > time) continue;
IobTotal calc = e.iobCalc(time);
totalExt.plus(calc);
TemporaryBasal t = new TemporaryBasal(e);
if (!t.isEndingEvent() && t.date > total.lastTempDate) {
total.lastTempDate = t.date;
total.lastTempDuration = t.durationInMinutes;
total.lastTempRate = t.tempBasalConvertedToAbsolute(t.date);
}
}
}
// Convert to basal iob

View file

@ -6,6 +6,7 @@
<color name="bolus">#FFFFCC03</color>
<color name="cob">#8BC34A</color>
<color name="uam">#ffea00</color>
<color name="zt">#ff9500</color>
<color name="ratio">#FFFFFF</color>
<color name="inrange">#00FF00</color>
<color name="low">#FF0000</color>

View file

@ -792,6 +792,9 @@
<string name="customapp">Customized APK for download</string>
<string name="wear_detailed_delta_title">Show detailed delta</string>
<string name="wear_detailed_delta_summary">Show delta with one more decimal place</string>
<string name="smbmaxminutes">45 60 75 90 105 120</string>
<string name="smbmaxminutes_summary">Max minutes of basal to limit SMB to</string>
<string name="key_smbmaxminutes" translatable="false">smbmaxminutes</string>
<string name="unsupportedfirmware">Unsupported pump firmware</string>
</resources>

View file

@ -35,18 +35,6 @@
android:summary="@string/always_use_shortavg_summary"
android:title="@string/always_use_shortavg" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/openapssmb">
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_use_smb"
android:summary="@string/enablesmb_summary"
android:title="@string/enablesmb" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_use_uam"
android:summary="@string/enableuam_summary"
android:title="@string/enableuam" />
</PreferenceCategory>
<PreferenceCategory android:title="OpenAPS preferences.json">
<Preference android:summary="@string/openapsama_link_to_preferncejson_doc_txt">
<intent
@ -103,11 +91,6 @@
validate:floatmaxNumber="1.0"
validate:floatminNumber="0.1"
validate:testType="floatNumericRange" />
<SwitchPreference
android:defaultValue="true"
android:key="openapsama_autosens_adjusttargets"
android:summary="@string/openapsama_autosens_adjusttargets_summary"
android:title="@string/openapsama_autosens_adjusttargets" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="2"
android:dialogMessage="@string/openapsama_bolussnooze_dia_divisor_summary"

View file

@ -21,6 +21,11 @@
android:defaultValue="false"
android:key="openapsama_useautosens"
android:title="@string/openapsama_useautosens" />
<SwitchPreference
android:defaultValue="true"
android:key="openapsama_autosens_adjusttargets"
android:summary="@string/openapsama_autosens_adjusttargets_summary"
android:title="@string/openapsama_autosens_adjusttargets" />
</PreferenceCategory>

View file

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:validate="http://schemas.android.com/apk/res-auto">
<PreferenceCategory
android:key="openapssmb"
android:title="@string/openapssmb">
<EditTextPreference
android:defaultValue="1"
android:key="openapsma_max_basal"
android:numeric="decimal"
android:dialogMessage="@string/openapsma_maxbasal_summary"
android:title="@string/openapsma_maxbasal_title" />
<EditTextPreference
android:defaultValue="1.5"
android:key="openapsma_max_iob"
android:numeric="decimal"
android:dialogMessage="@string/openapsma_maxiob_summary"
android:title="@string/openapsma_maxiob_title" />
<SwitchPreference
android:defaultValue="false"
android:key="openapsama_useautosens"
android:title="@string/openapsama_useautosens" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_use_smb"
android:summary="@string/enablesmb_summary"
android:title="@string/enablesmb" />
<com.andreabaccega.widget.ValidatingEditTextPreference
android:defaultValue="30"
android:dialogMessage="@string/smbmaxminutes"
android:digits="0123456789"
android:inputType="number"
android:key="key_smbmaxminutes"
android:maxLines="20"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/smbmaxminutes_summary"
validate:maxNumber="120"
validate:minNumber="15"
validate:testType="numericRange" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/key_use_uam"
android:summary="@string/enableuam_summary"
android:title="@string/enableuam" />
</PreferenceCategory>
</PreferenceScreen>