Merge pull request #898 from MilosKozak/cob-rework
Please review: Cob rework
This commit is contained in:
commit
2f299bc670
|
@ -59,6 +59,7 @@ public class Constants {
|
||||||
|
|
||||||
//Autosens
|
//Autosens
|
||||||
public static final double DEVIATION_TO_BE_EQUAL = 2.0;
|
public static final double DEVIATION_TO_BE_EQUAL = 2.0;
|
||||||
|
public static final double DEFAULT_MAX_ABSORPTION_TIME = 6.0;
|
||||||
|
|
||||||
// Pump
|
// Pump
|
||||||
public static final int PUMP_MAX_CONNECTION_TIME_IN_SECONDS = 120 - 1;
|
public static final int PUMP_MAX_CONNECTION_TIME_IN_SECONDS = 120 - 1;
|
||||||
|
|
|
@ -11,4 +11,5 @@ public class MealData {
|
||||||
public double slopeFromMinDeviation = 999;
|
public double slopeFromMinDeviation = 999;
|
||||||
public long lastBolusTime;
|
public long lastBolusTime;
|
||||||
public long lastCarbTime = 0L;
|
public long lastCarbTime = 0L;
|
||||||
|
public double usedMinCarbsImpact = 0d;
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,8 +195,7 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getSize() {
|
public float getSize() {
|
||||||
boolean isTablet = MainApp.sResources.getBoolean(R.bool.isTablet);
|
return 1;
|
||||||
return isTablet ? 8 : 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,20 +7,25 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.DataPointWithLabelInterface;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
|
import info.nightscout.androidaps.plugins.Overview.graphExtensions.Scale;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 25.04.2017.
|
* Created by mike on 25.04.2017.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class AutosensData {
|
public class AutosensData implements DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(AutosensData.class);
|
private static Logger log = LoggerFactory.getLogger(AutosensData.class);
|
||||||
|
|
||||||
static class CarbsInPast {
|
static class CarbsInPast {
|
||||||
|
@ -34,14 +39,14 @@ public class AutosensData {
|
||||||
carbs = t.carbs;
|
carbs = t.carbs;
|
||||||
remaining = t.carbs;
|
remaining = t.carbs;
|
||||||
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, 4d);
|
double maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||||
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
|
Profile profile = MainApp.getConfigBuilder().getProfile(t.date);
|
||||||
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
|
double sens = Profile.toMgdl(profile.getIsf(t.date), profile.getUnits());
|
||||||
double ic = profile.getIc(t.date);
|
double ic = profile.getIc(t.date);
|
||||||
min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic;
|
min5minCarbImpact = t.carbs / (maxAbsorptionHours * 60 / 5) * sens / ic;
|
||||||
log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
|
log.debug("Min 5m carbs impact for " + carbs + "g @" + new Date(t.date).toLocaleString() + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
|
||||||
} else {
|
} else {
|
||||||
min5minCarbImpact = SP.getDouble("openapsama_min_5m_carbimpact", 3.0);
|
min5minCarbImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,25 +68,33 @@ public class AutosensData {
|
||||||
public double autosensRatio = 1d;
|
public double autosensRatio = 1d;
|
||||||
public double slopeFromMaxDeviation = 0;
|
public double slopeFromMaxDeviation = 0;
|
||||||
public double slopeFromMinDeviation = 999;
|
public double slopeFromMinDeviation = 999;
|
||||||
|
public double usedMinCarbsImpact = 0d;
|
||||||
|
public boolean failoverToMinAbsorbtionRate = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
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 ;
|
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() {
|
public int minOld() {
|
||||||
return (int) ((System.currentTimeMillis() - time) / 1000 / 60);
|
return (int) ((System.currentTimeMillis() - time) / 1000 / 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove carbs older than 4h
|
// remove carbs older than timeframe
|
||||||
public void removeOldCarbs(long toTime) {
|
public void removeOldCarbs(long toTime) {
|
||||||
|
double maxAbsorptionHours = Constants.DEFAULT_MAX_ABSORPTION_TIME;
|
||||||
|
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
|
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||||
|
} else {
|
||||||
|
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||||
|
}
|
||||||
for (int i = 0; i < activeCarbsList.size(); i++) {
|
for (int i = 0; i < activeCarbsList.size(); i++) {
|
||||||
CarbsInPast c = activeCarbsList.get(i);
|
CarbsInPast c = activeCarbsList.get(i);
|
||||||
if (c.time + 4 * 60 * 60 * 1000L < toTime) {
|
if (c.time + maxAbsorptionHours * 60 * 60 * 1000L < toTime) {
|
||||||
activeCarbsList.remove(i--);
|
activeCarbsList.remove(i--);
|
||||||
if (c.remaining > 0)
|
if (c.remaining > 0)
|
||||||
cob -= c.remaining;
|
cob -= c.remaining;
|
||||||
log.debug("Removing carbs at "+ new Date(toTime).toLocaleString() + " + after 4h :" + new Date(c.time).toLocaleString());
|
log.debug("Removing carbs at " + new Date(toTime).toLocaleString() + " + after " + maxAbsorptionHours + "h :" + new Date(c.time).toLocaleString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,4 +111,57 @@ public class AutosensData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------- DataPointWithLabelInterface ------
|
||||||
|
|
||||||
|
private Scale scale;
|
||||||
|
|
||||||
|
public void setScale(Scale scale) {
|
||||||
|
this.scale = scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getX() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getY() {
|
||||||
|
return scale.transform(cob);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setY(double y) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLabel() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getDuration() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PointsWithLabelGraphSeries.Shape getShape() {
|
||||||
|
return PointsWithLabelGraphSeries.Shape.COBFAILOVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getSize() {
|
||||||
|
return 1f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColor() {
|
||||||
|
return MainApp.gc(R.color.cob);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSecondColor() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
.neverVisible(true)
|
.neverVisible(true)
|
||||||
.alwaysEnabled(true)
|
.alwaysEnabled(true)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
|
@ -548,7 +548,9 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
}
|
}
|
||||||
if (ev.isChanged(R.string.key_openapsama_autosens_period) ||
|
if (ev.isChanged(R.string.key_openapsama_autosens_period) ||
|
||||||
ev.isChanged(R.string.key_age) ||
|
ev.isChanged(R.string.key_age) ||
|
||||||
ev.isChanged(R.string.key_absorption_maxtime)
|
ev.isChanged(R.string.key_absorption_maxtime) ||
|
||||||
|
ev.isChanged(R.string.key_openapsama_min_5m_carbimpact) ||
|
||||||
|
ev.isChanged(R.string.key_absorption_cutoff)
|
||||||
) {
|
) {
|
||||||
stopCalculation("onEventPreferenceChange");
|
stopCalculation("onEventPreferenceChange");
|
||||||
synchronized (dataLock) {
|
synchronized (dataLock) {
|
||||||
|
|
|
@ -17,15 +17,21 @@ import info.nightscout.androidaps.BuildConfig;
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
|
||||||
|
import info.nightscout.androidaps.plugins.OpenAPSSMB.SMBDefaults;
|
||||||
|
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.Treatments.Treatment;
|
||||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.FabricPrivacy;
|
import info.nightscout.utils.FabricPrivacy;
|
||||||
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by mike on 23.01.2018.
|
* Created by mike on 23.01.2018.
|
||||||
|
@ -199,18 +205,27 @@ public class IobCobThread extends Thread {
|
||||||
if (previous != null && previous.cob > 0) {
|
if (previous != null && previous.cob > 0) {
|
||||||
// calculate sum of min carb impact from all active treatments
|
// calculate sum of min carb impact from all active treatments
|
||||||
double totalMinCarbsImpact = 0d;
|
double totalMinCarbsImpact = 0d;
|
||||||
for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) {
|
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii);
|
//when the impact depends on a max time, sum them up as smaller carb sizes make them smaller
|
||||||
totalMinCarbsImpact += c.min5minCarbImpact;
|
for (int ii = 0; ii < autosensData.activeCarbsList.size(); ++ii) {
|
||||||
|
AutosensData.CarbsInPast c = autosensData.activeCarbsList.get(ii);
|
||||||
|
totalMinCarbsImpact += c.min5minCarbImpact;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Oref sensitivity
|
||||||
|
totalMinCarbsImpact = SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
|
||||||
}
|
}
|
||||||
|
|
||||||
// figure out how many carbs that represents
|
// figure out how many carbs that represents
|
||||||
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
|
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
|
||||||
double ci = Math.max(deviation, totalMinCarbsImpact);
|
double ci = Math.max(deviation, totalMinCarbsImpact);
|
||||||
|
if (ci != deviation)
|
||||||
|
autosensData.failoverToMinAbsorbtionRate = true;
|
||||||
autosensData.absorbed = ci * profile.getIc(bgTime) / sens;
|
autosensData.absorbed = ci * profile.getIc(bgTime) / sens;
|
||||||
// and add that to the running total carbsAbsorbed
|
// and add that to the running total carbsAbsorbed
|
||||||
autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d);
|
autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d);
|
||||||
autosensData.substractAbosorbedCarbs();
|
autosensData.substractAbosorbedCarbs();
|
||||||
|
autosensData.usedMinCarbsImpact = totalMinCarbsImpact;
|
||||||
}
|
}
|
||||||
autosensData.removeOldCarbs(bgTime);
|
autosensData.removeOldCarbs(bgTime);
|
||||||
autosensData.cob += autosensData.carbsFromBolus;
|
autosensData.cob += autosensData.carbsFromBolus;
|
||||||
|
|
|
@ -213,8 +213,12 @@ public class DetermineBasalAdapterAMAJS {
|
||||||
mProfile.put("current_basal", basalrate);
|
mProfile.put("current_basal", basalrate);
|
||||||
mProfile.put("temptargetSet", tempTargetSet);
|
mProfile.put("temptargetSet", tempTargetSet);
|
||||||
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
|
mProfile.put("autosens_adjust_targets", SP.getBoolean("openapsama_autosens_adjusttargets", true));
|
||||||
//TODO: align with max-absorption model in AMA sensitivity
|
//align with max-absorption model in AMA sensitivity
|
||||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
|
if(mealData.usedMinCarbsImpact > 0){
|
||||||
|
mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
|
||||||
|
} else {
|
||||||
|
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
||||||
|
}
|
||||||
|
|
||||||
if (units.equals(Constants.MMOL)) {
|
if (units.equals(Constants.MMOL)) {
|
||||||
mProfile.put("out_units", "mmol/L");
|
mProfile.put("out_units", "mmol/L");
|
||||||
|
|
|
@ -243,9 +243,12 @@ public class DetermineBasalAdapterSMBJS {
|
||||||
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
|
mProfile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target);
|
||||||
mProfile.put("maxCOB", SMBDefaults.maxCOB);
|
mProfile.put("maxCOB", SMBDefaults.maxCOB);
|
||||||
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
|
mProfile.put("skip_neutral_temps", SMBDefaults.skip_neutral_temps);
|
||||||
//TODO: align with max-absorption model in AMA sensitivity
|
//align with max-absorption model in AMA sensitivity
|
||||||
mProfile.put("min_5m_carbimpact", SP.getDouble("openapsama_min_5m_carbimpact", SMBDefaults.min_5m_carbimpact));
|
if(mealData.usedMinCarbsImpact > 0){
|
||||||
;
|
mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
|
||||||
|
} else {
|
||||||
|
mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
||||||
|
}
|
||||||
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
|
||||||
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
|
||||||
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
|
||||||
|
|
|
@ -365,6 +365,7 @@ public class GraphData {
|
||||||
|
|
||||||
// scale in % of vertical size (like 0.3)
|
// scale in % of vertical size (like 0.3)
|
||||||
public void addCob(long fromTime, long toTime, boolean useForScale, double scale) {
|
public void addCob(long fromTime, long toTime, boolean useForScale, double scale) {
|
||||||
|
List<DataPointWithLabelInterface> minFailoverActiveList = new ArrayList<>();
|
||||||
FixedLineGraphSeries<ScaledDataPoint> cobSeries;
|
FixedLineGraphSeries<ScaledDataPoint> cobSeries;
|
||||||
List<ScaledDataPoint> cobArray = new ArrayList<>();
|
List<ScaledDataPoint> cobArray = new ArrayList<>();
|
||||||
Double maxCobValueFound = 0d;
|
Double maxCobValueFound = 0d;
|
||||||
|
@ -382,6 +383,10 @@ public class GraphData {
|
||||||
maxCobValueFound = Math.max(maxCobValueFound, cob);
|
maxCobValueFound = Math.max(maxCobValueFound, cob);
|
||||||
lastCob = cob;
|
lastCob = cob;
|
||||||
}
|
}
|
||||||
|
if (autosensData.failoverToMinAbsorbtionRate) {
|
||||||
|
autosensData.setScale(cobScale);
|
||||||
|
minFailoverActiveList.add(autosensData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +405,10 @@ public class GraphData {
|
||||||
cobScale.setMultiplier(maxY * scale / maxCobValueFound);
|
cobScale.setMultiplier(maxY * scale / maxCobValueFound);
|
||||||
|
|
||||||
addSeries(cobSeries);
|
addSeries(cobSeries);
|
||||||
|
|
||||||
|
DataPointWithLabelInterface[] minFailover = new DataPointWithLabelInterface[minFailoverActiveList.size()];
|
||||||
|
minFailover = minFailoverActiveList.toArray(minFailover);
|
||||||
|
addSeries(new PointsWithLabelGraphSeries<>(minFailover));
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale in % of vertical size (like 0.3)
|
// scale in % of vertical size (like 0.3)
|
||||||
|
|
|
@ -3,42 +3,46 @@ package info.nightscout.androidaps.plugins.Overview.graphExtensions;
|
||||||
/**
|
/**
|
||||||
* GraphView
|
* GraphView
|
||||||
* Copyright (C) 2014 Jonas Gehring
|
* Copyright (C) 2014 Jonas Gehring
|
||||||
*
|
* <p>
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License,
|
* the Free Software Foundation; either version 2 of the License,
|
||||||
* with the "Linking Exception", which can be found at the license.txt
|
* with the "Linking Exception", which can be found at the license.txt
|
||||||
* file in this program.
|
* file in this program.
|
||||||
*
|
* <p>
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
* <p>
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* with the "Linking Exception" along with this program; if not,
|
* with the "Linking Exception" along with this program; if not,
|
||||||
* write to the author Jonas Gehring <g.jjoe64@gmail.com>.
|
* write to the author Jonas Gehring <g.jjoe64@gmail.com>.
|
||||||
|
* <p>
|
||||||
|
* Added by mike
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Added by mike
|
* Added by mike
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.util.TypedValue;
|
|
||||||
// Added by Rumen for scalable text
|
|
||||||
import android.content.Context;
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import com.jjoe64.graphview.GraphView;
|
import com.jjoe64.graphview.GraphView;
|
||||||
import com.jjoe64.graphview.series.BaseSeries;
|
import com.jjoe64.graphview.series.BaseSeries;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
|
||||||
|
// Added by Rumen for scalable text
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Series that plots the data as points.
|
* Series that plots the data as points.
|
||||||
* The points can be different shapes or a
|
* The points can be different shapes or a
|
||||||
|
@ -74,7 +78,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
OPENAPSOFFLINE,
|
OPENAPSOFFLINE,
|
||||||
EXERCISE,
|
EXERCISE,
|
||||||
GENERAL,
|
GENERAL,
|
||||||
GENERALWITHDURATION
|
GENERALWITHDURATION,
|
||||||
|
COBFAILOVER
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,7 +153,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
|
|
||||||
float scaleX = (float) (graphWidth / diffX);
|
float scaleX = (float) (graphWidth / diffX);
|
||||||
|
|
||||||
int i=0;
|
int i = 0;
|
||||||
while (values.hasNext()) {
|
while (values.hasNext()) {
|
||||||
E value = values.next();
|
E value = values.next();
|
||||||
|
|
||||||
|
@ -182,7 +187,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix a bug that continue to show the DOT after Y axis */
|
/* Fix a bug that continue to show the DOT after Y axis */
|
||||||
if(x < 0) {
|
if (x < 0) {
|
||||||
overdraw = true;
|
overdraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,10 +202,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
|
|
||||||
// draw data point
|
// draw data point
|
||||||
if (!overdraw) {
|
if (!overdraw) {
|
||||||
if (value.getShape() == Shape.BG) {
|
if (value.getShape() == Shape.BG || value.getShape() == Shape.COBFAILOVER) {
|
||||||
mPaint.setStyle(Paint.Style.FILL);
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
canvas.drawCircle(endX, endY, scaledPxSize, mPaint);
|
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
|
||||||
} else if (value.getShape() == Shape.PREDICTION) {
|
} else if (value.getShape() == Shape.PREDICTION) {
|
||||||
mPaint.setColor(value.getColor());
|
mPaint.setColor(value.getColor());
|
||||||
mPaint.setStyle(Paint.Style.FILL);
|
mPaint.setStyle(Paint.Style.FILL);
|
||||||
|
@ -211,20 +216,20 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint);
|
canvas.drawCircle(endX, endY, scaledPxSize / 3, mPaint);
|
||||||
} else if (value.getShape() == Shape.RECTANGLE) {
|
} else if (value.getShape() == Shape.RECTANGLE) {
|
||||||
canvas.drawRect(endX-scaledPxSize, endY-scaledPxSize, endX+scaledPxSize, endY+scaledPxSize, mPaint);
|
canvas.drawRect(endX - scaledPxSize, endY - scaledPxSize, endX + scaledPxSize, endY + scaledPxSize, mPaint);
|
||||||
} else if (value.getShape() == Shape.TRIANGLE) {
|
} else if (value.getShape() == Shape.TRIANGLE) {
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
Point[] points = new Point[3];
|
Point[] points = new Point[3];
|
||||||
points[0] = new Point((int)endX, (int)(endY-scaledPxSize));
|
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
|
||||||
points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67));
|
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||||
points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67));
|
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||||
drawArrows(points, canvas, mPaint);
|
drawArrows(points, canvas, mPaint);
|
||||||
} else if (value.getShape() == Shape.BOLUS) {
|
} else if (value.getShape() == Shape.BOLUS) {
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
Point[] points = new Point[3];
|
Point[] points = new Point[3];
|
||||||
points[0] = new Point((int)endX, (int)(endY-scaledPxSize));
|
points[0] = new Point((int) endX, (int) (endY - scaledPxSize));
|
||||||
points[1] = new Point((int)(endX+scaledPxSize), (int)(endY+scaledPxSize*0.67));
|
points[1] = new Point((int) (endX + scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||||
points[2] = new Point((int)(endX-scaledPxSize), (int)(endY+scaledPxSize*0.67));
|
points[2] = new Point((int) (endX - scaledPxSize), (int) (endY + scaledPxSize * 0.67));
|
||||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
drawArrows(points, canvas, mPaint);
|
drawArrows(points, canvas, mPaint);
|
||||||
if (value.getLabel() != null) {
|
if (value.getLabel() != null) {
|
||||||
|
@ -234,15 +239,15 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
mPaint.setStrokeWidth(2);
|
mPaint.setStrokeWidth(2);
|
||||||
Point[] points = new Point[3];
|
Point[] points = new Point[3];
|
||||||
float size = value.getSize() * scaledPxSize;
|
float size = value.getSize() * scaledPxSize;
|
||||||
points[0] = new Point((int)endX, (int)(endY-size));
|
points[0] = new Point((int) endX, (int) (endY - size));
|
||||||
points[1] = new Point((int)(endX+size), (int)(endY+size*0.67));
|
points[1] = new Point((int) (endX + size), (int) (endY + size * 0.67));
|
||||||
points[2] = new Point((int)(endX-size), (int)(endY+size*0.67));
|
points[2] = new Point((int) (endX - size), (int) (endY + size * 0.67));
|
||||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
drawArrows(points, canvas, mPaint);
|
drawArrows(points, canvas, mPaint);
|
||||||
} else if (value.getShape() == Shape.EXTENDEDBOLUS) {
|
} else if (value.getShape() == Shape.EXTENDEDBOLUS) {
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
if (value.getLabel() != null) {
|
if (value.getLabel() != null) {
|
||||||
Rect bounds = new Rect((int)endX, (int)endY + 3, (int) (xpluslength), (int) endY + 8);
|
Rect bounds = new Rect((int) endX, (int) endY + 3, (int) (xpluslength), (int) endY + 8);
|
||||||
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||||
canvas.drawRect(bounds, mPaint);
|
canvas.drawRect(bounds, mPaint);
|
||||||
mPaint.setTextSize((float) (scaledTextSize));
|
mPaint.setTextSize((float) (scaledTextSize));
|
||||||
|
@ -254,7 +259,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
mPaint.setStrokeWidth(0);
|
mPaint.setStrokeWidth(0);
|
||||||
if (value.getLabel() != null) {
|
if (value.getLabel() != null) {
|
||||||
//mPaint.setTextSize((int) (scaledPxSize * 3));
|
//mPaint.setTextSize((int) (scaledPxSize * 3));
|
||||||
mPaint.setTextSize((float) (scaledTextSize*1.2));
|
mPaint.setTextSize((float) (scaledTextSize * 1.2));
|
||||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
|
||||||
Rect bounds = new Rect();
|
Rect bounds = new Rect();
|
||||||
mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds);
|
mPaint.getTextBounds(value.getLabel(), 0, value.getLabel().length(), bounds);
|
||||||
|
@ -355,7 +360,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
* @param paint paint object
|
* @param paint paint object
|
||||||
*/
|
*/
|
||||||
private void drawArrows(Point[] point, Canvas canvas, Paint paint) {
|
private void drawArrows(Point[] point, Canvas canvas, Paint paint) {
|
||||||
float [] points = new float[8];
|
float[] points = new float[8];
|
||||||
points[0] = point[0].x;
|
points[0] = point[0].x;
|
||||||
points[1] = point[0].y;
|
points[1] = point[0].y;
|
||||||
points[2] = point[1].x;
|
points[2] = point[1].x;
|
||||||
|
@ -368,10 +373,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint);
|
canvas.drawVertices(Canvas.VertexMode.TRIANGLES, 8, points, 0, null, 0, null, 0, null, 0, 0, paint);
|
||||||
Path path = new Path();
|
Path path = new Path();
|
||||||
path.moveTo(point[0].x , point[0].y);
|
path.moveTo(point[0].x, point[0].y);
|
||||||
path.lineTo(point[1].x,point[1].y);
|
path.lineTo(point[1].x, point[1].y);
|
||||||
path.lineTo(point[2].x,point[2].y);
|
path.lineTo(point[2].x, point[2].y);
|
||||||
canvas.drawPath(path,paint);
|
canvas.drawPath(path, paint);
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +386,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
float py = endY + scaledPxSize;
|
float py = endY + scaledPxSize;
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.rotate(-45, px, py);
|
canvas.rotate(-45, px, py);
|
||||||
mPaint.setTextSize((float) (scaledTextSize*0.8));
|
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||||
mPaint.setFakeBoldText(true);
|
mPaint.setFakeBoldText(true);
|
||||||
mPaint.setTextAlign(Paint.Align.RIGHT);
|
mPaint.setTextAlign(Paint.Align.RIGHT);
|
||||||
|
@ -393,7 +398,7 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
||||||
float py = endY - scaledPxSize;
|
float py = endY - scaledPxSize;
|
||||||
canvas.save();
|
canvas.save();
|
||||||
canvas.rotate(-45, px, py);
|
canvas.rotate(-45, px, py);
|
||||||
mPaint.setTextSize((float) (scaledTextSize*0.8));
|
mPaint.setTextSize((float) (scaledTextSize * 0.8));
|
||||||
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
mPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
|
||||||
mPaint.setFakeBoldText(true);
|
mPaint.setFakeBoldText(true);
|
||||||
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
|
canvas.drawText(value.getLabel(), px + scaledPxSize, py, mPaint);
|
||||||
|
|
|
@ -40,6 +40,8 @@ import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
||||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
import info.nightscout.androidaps.plugins.Overview.events.EventDismissNotification;
|
||||||
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.Overview.notifications.Notification;
|
||||||
|
import info.nightscout.androidaps.plugins.SensitivityAAPS.SensitivityAAPSPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.SensitivityWeightedAverage.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.utils.DateUtil;
|
import info.nightscout.utils.DateUtil;
|
||||||
import info.nightscout.utils.NSUpload;
|
import info.nightscout.utils.NSUpload;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
@ -211,22 +213,35 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
||||||
if (profile == null) return result;
|
if (profile == null) return result;
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * T.hours(1).msecs())).longValue();
|
long dia_ago = now - (Double.valueOf(profile.getDia() * T.hours(1).msecs())).longValue();
|
||||||
|
|
||||||
|
double maxAbsorptionHours = Constants.DEFAULT_MAX_ABSORPTION_TIME;
|
||||||
|
if (SensitivityAAPSPlugin.getPlugin().isEnabled(PluginType.SENSITIVITY) || SensitivityWeightedAveragePlugin.getPlugin().isEnabled(PluginType.SENSITIVITY)) {
|
||||||
|
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||||
|
} else {
|
||||||
|
maxAbsorptionHours = SP.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||||
|
}
|
||||||
|
long absorptionTime_ago = now - (Double.valueOf(maxAbsorptionHours * T.hours(1).msecs())).longValue();
|
||||||
|
|
||||||
synchronized (treatments) {
|
synchronized (treatments) {
|
||||||
for (Treatment treatment : treatments) {
|
for (Treatment treatment : treatments) {
|
||||||
if (!treatment.isValid)
|
if (!treatment.isValid)
|
||||||
continue;
|
continue;
|
||||||
long t = treatment.date;
|
long t = treatment.date;
|
||||||
|
|
||||||
if (t > dia_ago && t <= now) {
|
if (t > dia_ago && t <= now) {
|
||||||
if (treatment.carbs >= 1) {
|
|
||||||
result.carbs += treatment.carbs;
|
|
||||||
result.lastCarbTime = t;
|
|
||||||
}
|
|
||||||
if (treatment.insulin > 0 && treatment.mealBolus) {
|
if (treatment.insulin > 0 && treatment.mealBolus) {
|
||||||
result.boluses += treatment.insulin;
|
result.boluses += treatment.insulin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (t > absorptionTime_ago && t <= now) {
|
||||||
|
if (treatment.carbs >= 1) {
|
||||||
|
result.carbs += treatment.carbs;
|
||||||
|
if(t > result.lastCarbTime)
|
||||||
|
result.lastCarbTime = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,6 +250,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
||||||
result.mealCOB = autosensData.cob;
|
result.mealCOB = autosensData.cob;
|
||||||
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation;
|
result.slopeFromMinDeviation = autosensData.slopeFromMinDeviation;
|
||||||
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation;
|
result.slopeFromMaxDeviation = autosensData.slopeFromMaxDeviation;
|
||||||
|
result.usedMinCarbsImpact = autosensData.usedMinCarbsImpact;
|
||||||
}
|
}
|
||||||
result.lastBolusTime = getLastBolusTime();
|
result.lastBolusTime = getLastBolusTime();
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -619,6 +619,8 @@
|
||||||
<string name="sensitivityaaps">Sensitivity AAPS</string>
|
<string name="sensitivityaaps">Sensitivity AAPS</string>
|
||||||
<string name="absorptionsettings_title">Absorption settings</string>
|
<string name="absorptionsettings_title">Absorption settings</string>
|
||||||
<string name="key_absorption_maxtime" translatable="false">absorption_maxtime</string>
|
<string name="key_absorption_maxtime" translatable="false">absorption_maxtime</string>
|
||||||
|
<string name="key_absorption_cutoff" translatable="false">absorption_cutoff</string>
|
||||||
|
|
||||||
<string name="absorption_maxtime_title">Meal max absorption time [h]</string>
|
<string name="absorption_maxtime_title">Meal max absorption time [h]</string>
|
||||||
<string name="absorption_maxtime_summary">Time in hours where is expected all carbs from meal will be absorbed</string>
|
<string name="absorption_maxtime_summary">Time in hours where is expected all carbs from meal will be absorbed</string>
|
||||||
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
|
<string name="key_rangetodisplay" translatable="false">rangetodisplay</string>
|
||||||
|
@ -997,7 +999,10 @@
|
||||||
<string name="key_openapssmb_max_iob" translatable="false">openapsmb_max_iob</string>
|
<string name="key_openapssmb_max_iob" translatable="false">openapsmb_max_iob</string>
|
||||||
<string name="openapssmb_maxiob_title">Maximum total IOB OpenAPS can\'t go over [U]</string>
|
<string name="openapssmb_maxiob_title">Maximum total IOB OpenAPS can\'t go over [U]</string>
|
||||||
<string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string>
|
<string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string>
|
||||||
|
<string name="absorption_cutoff_title">Meal max absorption time [h]</string>
|
||||||
|
<string name="absorption_cutoff_summary">Time at which any meal is considered absorbed. Remaining carbs will be cut off.</string>
|
||||||
<string name="time">Time</string>
|
<string name="time">Time</string>
|
||||||
<string name="key_show_notes_entry_dialogs">show_notes_entry_dialogs</string>
|
<string name="key_show_notes_entry_dialogs">show_notes_entry_dialogs</string>
|
||||||
<string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string>
|
<string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string>
|
||||||
|
<string name="key_openapsama_min_5m_carbimpact" translatable="false">openapsama_min_5m_carbimpact</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
android:title="@string/absorptionsettings_title">
|
android:title="@string/absorptionsettings_title">
|
||||||
<com.andreabaccega.widget.ValidatingEditTextPreference
|
<com.andreabaccega.widget.ValidatingEditTextPreference
|
||||||
validate:testType="numericRange"
|
validate:testType="numericRange"
|
||||||
validate:minNumber="1"
|
validate:minNumber="4"
|
||||||
validate:maxNumber="10"
|
validate:maxNumber="10"
|
||||||
android:digits="0123456789.,"
|
android:digits="0123456789.,"
|
||||||
android:defaultValue="3"
|
android:defaultValue="6"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:maxLines="20"
|
android:maxLines="20"
|
||||||
|
|
|
@ -8,14 +8,27 @@
|
||||||
validate:testType="floatNumericRange"
|
validate:testType="floatNumericRange"
|
||||||
validate:floatminNumber="0.1"
|
validate:floatminNumber="0.1"
|
||||||
validate:floatmaxNumber="12.0"
|
validate:floatmaxNumber="12.0"
|
||||||
android:defaultValue="3.0"
|
android:defaultValue="8.0"
|
||||||
android:selectAllOnFocus="true"
|
android:selectAllOnFocus="true"
|
||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:inputType="numberDecimal"
|
android:inputType="numberDecimal"
|
||||||
android:maxLines="20"
|
android:maxLines="20"
|
||||||
android:title="@string/openapsama_min_5m_carbimpact"
|
android:title="@string/openapsama_min_5m_carbimpact"
|
||||||
android:dialogMessage="@string/openapsama_min_5m_carbimpact_summary"
|
android:dialogMessage="@string/openapsama_min_5m_carbimpact_summary"
|
||||||
android:key="openapsama_min_5m_carbimpact" />
|
android:key="@string/key_openapsama_min_5m_carbimpact" />
|
||||||
|
|
||||||
|
<com.andreabaccega.widget.ValidatingEditTextPreference
|
||||||
|
validate:testType="numericRange"
|
||||||
|
validate:minNumber="4"
|
||||||
|
validate:maxNumber="10"
|
||||||
|
android:digits="0123456789.,"
|
||||||
|
android:defaultValue="6"
|
||||||
|
android:selectAllOnFocus="true"
|
||||||
|
android:inputType="number"
|
||||||
|
android:maxLines="20"
|
||||||
|
android:title="@string/absorption_cutoff_title"
|
||||||
|
android:dialogMessage="@string/absorption_cutoff_summary"
|
||||||
|
android:key="@string/key_absorption_cutoff" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
Loading…
Reference in a new issue