diff --git a/app/build.gradle b/app/build.gradle index 8366358e50..53928d4c0d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -24,6 +24,7 @@ ext { repositories { maven { url 'https://maven.fabric.io/public' } + jcenter { url "https://jcenter.bintray.com/" } } def generateGitBuild = { -> @@ -62,7 +63,7 @@ android { targetSdkVersion 23 multiDexEnabled true versionCode 1500 - version "1.60a-dev" + version "1.60b-dev" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", generateGitBuild() @@ -210,6 +211,7 @@ dependencies { compile "com.google.guava:guava:20.0" compile "net.danlew:android.joda:2.9.9.1" + compile "uk.com.robust-it:cloning:1.9.9" compile 'org.mozilla:rhino:1.7.7.2' diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index a2bf64b7ae..8e45bcecea 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -24,7 +24,7 @@ public class Config { public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; - public static final boolean displayDeviationSlope = true; + public static final boolean displayDeviationSlope = false; public static final boolean detailedLog = true; public static final boolean logFunctionCalls = true; diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index f9fa7480cd..089ffa255e 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -31,7 +31,6 @@ import info.nightscout.androidaps.interfaces.InsulinInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.plugins.Actions.ActionsFragment; import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; -import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; @@ -188,7 +187,7 @@ public class MainApp extends Application { pluginsList.add(new PersistentNotificationPlugin(this)); pluginsList.add(NSClientPlugin.getPlugin()); - pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin()); + pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin()); MainApp.getConfigBuilder().initialize(); } @@ -389,6 +388,8 @@ public class MainApp extends Application { } public static boolean isEngineeringModeOrRelease() { + if (!BuildConfig.APS) + return true; return engineeringMode || !devBranch; } diff --git a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java index 5faa288d77..a9df24798e 100644 --- a/app/src/main/java/info/nightscout/androidaps/Services/DataService.java +++ b/app/src/main/java/info/nightscout/androidaps/Services/DataService.java @@ -64,31 +64,31 @@ public class DataService extends IntentService { if (Config.logFunctionCalls) log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras())); - if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { + if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { xDripEnabled = true; nsClientEnabled = false; mm640gEnabled = false; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { xDripEnabled = false; nsClientEnabled = true; mm640gEnabled = false; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = true; glimpEnabled = false; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = false; glimpEnabled = true; dexcomG5Enabled = false; - } else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { + } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { xDripEnabled = false; nsClientEnabled = false; mm640gEnabled = false; diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java index d984e3277f..6c13075a3c 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -4,9 +4,11 @@ import java.util.ArrayList; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; /** * Created by mike on 19.03.2018. @@ -41,6 +43,10 @@ public class ConstraintChecker implements ConstraintsInterface { return isSMBModeEnabled(new Constraint<>(true)); } + public Constraint isAdvancedFilteringEnabled() { + return isAdvancedFilteringEnabled(new Constraint<>(true)); + } + public Constraint getMaxBasalAllowed(Profile profile) { return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile); } @@ -121,6 +127,17 @@ public class ConstraintChecker implements ConstraintsInterface { return value; } + @Override + public Constraint isAdvancedFilteringEnabled(Constraint value) { + ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + for (PluginBase p : constraintsPlugins) { + ConstraintsInterface constraint = (ConstraintsInterface) p; + if (!p.isEnabled(PluginBase.CONSTRAINTS)) continue; + constraint.isAdvancedFilteringEnabled(value); + } + return value; + } + @Override public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); diff --git a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java index d8c0bea28a..3935b17b8a 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java +++ b/app/src/main/java/info/nightscout/androidaps/data/DetailedBolusInfo.java @@ -2,6 +2,8 @@ package info.nightscout.androidaps.data; import android.content.Context; +import com.rits.cloning.Cloner; + import org.json.JSONObject; import java.util.Date; @@ -30,21 +32,22 @@ public class DetailedBolusInfo { public long deliverAt = 0; // SMB should be delivered within 1 min from this time public DetailedBolusInfo copy() { - DetailedBolusInfo copy = new DetailedBolusInfo(); - copy.date = this.date; - copy.eventType = this.eventType; - copy.insulin = this.insulin; - copy.carbs = this.carbs; - copy.source = this.source; - copy.isValid = this.isValid; - copy.glucose = this.glucose; - copy.glucoseType = this.glucoseType; - copy.carbTime = this.carbTime; - copy.boluscalc = this.boluscalc; - copy.context = this.context; - copy.pumpId = this.pumpId; - copy.isSMB = this.isSMB; - return copy; + DetailedBolusInfo n = new DetailedBolusInfo(); + n.date = date; + n.eventType = eventType; + n.insulin = insulin; + n.carbs = carbs; + n.source = source; + n.isValid = isValid; + n.glucose = glucose; + n.glucoseType = glucoseType; + n.carbTime = carbTime; + n.boluscalc = boluscalc; + n.context = context; + n.pumpId = pumpId; + n.isSMB = isSMB; + n.deliverAt = deliverAt; + return n; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java index 1a5094253f..d8ee55b73a 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java @@ -21,6 +21,7 @@ import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.utils.DateUtil; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.Round; @@ -40,17 +41,10 @@ public class GlucoseStatus { @Override public String toString() { - return MainApp.sResources.getString(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" + - MainApp.sResources.getString(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" + - MainApp.sResources.getString(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" + - MainApp.sResources.getString(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"; - } - - public Spanned toSpanned() { - return Html.fromHtml("" + MainApp.sResources.getString(R.string.glucose) + ": " + DecimalFormatter.to0Decimal(glucose) + " mg/dl
" + - "" + MainApp.sResources.getString(R.string.delta) + ": " + DecimalFormatter.to0Decimal(delta) + " mg/dl
" + - "" + MainApp.sResources.getString(R.string.short_avgdelta) + ": " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl
" + - "" + MainApp.sResources.getString(R.string.long_avgdelta) + ": " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"); + return MainApp.gs(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" + + MainApp.gs(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" + + MainApp.gs(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" + + MainApp.gs(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"; } public GlucoseStatus() { @@ -75,11 +69,15 @@ public class GlucoseStatus { @Nullable public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) { // load 45min - long fromtime = (long) (System.currentTimeMillis() - 60 * 1000L * 45); + long fromtime = DateUtil.now() - 60 * 1000L * 45; List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); int sizeRecords = data.size(); - if (sizeRecords < 1 || (data.get(0).date < System.currentTimeMillis() - 7 * 60 * 1000L && !allowOldData)) { + if (sizeRecords == 0) { + return null; + } + + if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) { return null; } @@ -87,13 +85,14 @@ public class GlucoseStatus { long now_date = now.date; double change; - if (sizeRecords < 2) { + if (sizeRecords == 1) { GlucoseStatus status = new GlucoseStatus(); status.glucose = now.value; status.short_avgdelta = 0d; status.delta = 0d; status.long_avgdelta = 0d; status.avgdelta = 0d; // for OpenAPS MA + status.date = now_date; return status.round(); } diff --git a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java index 108b4060e0..66d567d9bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Intervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Intervals.java @@ -16,7 +16,11 @@ import info.nightscout.androidaps.interfaces.Interval; public abstract class Intervals { - LongSparseArray rawData = new LongSparseArray(); // oldest at index 0 + LongSparseArray rawData; // oldest at index 0 + + public Intervals() { + rawData = new LongSparseArray(); + } public synchronized Intervals reset() { rawData = new LongSparseArray(); @@ -27,8 +31,7 @@ public abstract class Intervals { /** * The List must be sorted by `T.start()` in ascending order - * - * */ + */ public synchronized void add(List list) { for (T interval : list) { rawData.put(interval.start(), interval); @@ -36,6 +39,10 @@ public abstract class Intervals { merge(); } + public synchronized void add(T interval) { + rawData.put(interval.start(), interval); + merge(); + } public synchronized List getList() { @@ -47,7 +54,7 @@ public abstract class Intervals { public synchronized List getReversedList() { List list = new ArrayList<>(); - for (int i = rawData.size() -1; i>=0; i--) + for (int i = rawData.size() - 1; i >= 0; i--) list.add(rawData.valueAt(i)); return list; } @@ -86,5 +93,4 @@ public abstract class Intervals { } - } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/data/Iob.java b/app/src/main/java/info/nightscout/androidaps/data/Iob.java index 762352782b..d48cdf627c 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/Iob.java +++ b/app/src/main/java/info/nightscout/androidaps/data/Iob.java @@ -7,6 +7,16 @@ public class Iob { public double iobContrib = 0d; public double activityContrib = 0d; + public Iob iobContrib(double iobContrib) { + this.iobContrib = iobContrib; + return this; + } + + public Iob activityContrib(double activityContrib) { + this.activityContrib = activityContrib; + return this; + } + public Iob plus(Iob iob) { iobContrib += iob.iobContrib; activityContrib += iob.activityContrib; diff --git a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java index 4bb55b0095..889d842ccf 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java +++ b/app/src/main/java/info/nightscout/androidaps/data/IobTotal.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.data; +import com.rits.cloning.Cloner; + import org.json.JSONException; import org.json.JSONObject; import org.slf4j.Logger; @@ -35,20 +37,9 @@ 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.lastBolusTime = lastBolusTime; - copy.lastTempDate = lastTempDate; - copy.lastTempDuration = lastTempDuration; - copy.lastTempRate = lastTempRate; - copy.iobWithZeroTemp = iobWithZeroTemp; - return copy; + public IobTotal copy() { + Cloner cloner = new Cloner(); + return cloner.deepClone(this); } public IobTotal(long time) { @@ -82,6 +73,8 @@ public class IobTotal { result.basaliob = bolusIOB.basaliob + basalIob.basaliob; result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin; result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin; + result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin; + result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin; result.lastBolusTime = bolusIOB.lastBolusTime; result.lastTempDate = basalIob.lastTempDate; result.lastTempRate = basalIob.lastTempRate; @@ -97,6 +90,8 @@ public class IobTotal { this.basaliob = Round.roundTo(this.basaliob, 0.001); this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001); this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001); + this.netInsulin = Round.roundTo(this.netInsulin, 0.001); + this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001); return this; } diff --git a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java index 385eeb9594..8e0c286e7e 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java @@ -2,7 +2,9 @@ package info.nightscout.androidaps.data; import android.support.annotation.Nullable; +import android.support.v4.util.LongSparseArray; +import info.nightscout.androidaps.db.TemporaryBasal; import info.nightscout.androidaps.interfaces.Interval; /** @@ -11,6 +13,14 @@ import info.nightscout.androidaps.interfaces.Interval; public class NonOverlappingIntervals extends Intervals { + public NonOverlappingIntervals() { + super(); + } + + public NonOverlappingIntervals (Intervals other) { + rawData = other.rawData.clone(); + } + protected synchronized void merge() { for (int index = 0; index < rawData.size() - 1; index++) { Interval i = rawData.valueAt(index); @@ -27,4 +37,5 @@ public class NonOverlappingIntervals extends Intervals { if (index >= 0) return rawData.valueAt(index); return null; } + } diff --git a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java index 070426cca0..76c2ff3615 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java @@ -11,18 +11,26 @@ import info.nightscout.androidaps.interfaces.Interval; public class OverlappingIntervals extends Intervals { + public OverlappingIntervals() { + super(); + } + + public OverlappingIntervals(Intervals other) { + rawData = other.rawData.clone(); + } + protected synchronized void merge() { boolean needToCut = false; long cutTime = 0; - for (int index = rawData.size()-1; index >= 0; index--) { //begin with newest + for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest Interval cur = rawData.valueAt(index); - if (cur.isEndingEvent()){ + if (cur.isEndingEvent()) { needToCut = true; cutTime = cur.start(); } else { //event that is no EndingEvent might need to be stopped by an ending event - if(needToCut&&cur.end() > cutTime){ + if (needToCut && cur.end() > cutTime) { cur.cutEndTo(cutTime); } } @@ -31,9 +39,9 @@ public class OverlappingIntervals extends Intervals { @Nullable public synchronized T getValueByInterval(long time) { - for (int index = rawData.size()-1; index >= 0; index--) { //begin with newest + for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest T cur = rawData.valueAt(index); - if (cur.match(time)){ + if (cur.match(time)) { return cur; } } diff --git a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java index 8ea89e2a5b..9343596eee 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java @@ -22,7 +22,15 @@ import info.nightscout.utils.DateUtil; public class ProfileIntervals { private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class); - private LongSparseArray rawData = new LongSparseArray<>(); // oldest at index 0 + private LongSparseArray rawData; // oldest at index 0 + + public ProfileIntervals () { + rawData = new LongSparseArray<>(); + } + + public ProfileIntervals (ProfileIntervals other) { + rawData = other.rawData.clone(); + } public synchronized ProfileIntervals reset() { rawData = new LongSparseArray<>(); @@ -30,8 +38,10 @@ public class ProfileIntervals { } public synchronized void add(T newInterval) { - rawData.put(newInterval.start(), newInterval); - merge(); + if (newInterval.isValid()) { + rawData.put(newInterval.start(), newInterval); + merge(); + } } public synchronized void add(List list) { @@ -56,10 +66,12 @@ public class ProfileIntervals { public synchronized Interval getValueToTime(long time) { int index = binarySearch(time); if (index >= 0) return rawData.valueAt(index); - // if we request data older than first record, use oldest instead - if (rawData.size() > 0) { - log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); - return rawData.valueAt(0); + // if we request data older than first record, use oldest with zero duration instead + for (index = 0; index < rawData.size(); index++) { + if (rawData.valueAt(index).durationInMsec() == 0) { + //log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); + return rawData.valueAt(index); + } } return null; } @@ -117,4 +129,9 @@ public class ProfileIntervals { public synchronized T getReversed(int index) { return rawData.valueAt(size() - 1 - index); } + + @Override + public String toString() { + return rawData.toString(); + } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index 68b506b37a..8432824068 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -58,7 +58,7 @@ import info.nightscout.utils.PercentageSplitter; /** * This Helper contains all resource to provide a central DB management functionality. Only methods handling * data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL). - * + *

* This class can safely be called from Services, but should not call Services to avoid circular dependencies. * One major issue with this (right now) are the scheduled events, which are put into the service. Therefor all * direct calls to the corresponding methods (eg. resetDatabases) should be done by a central service. @@ -893,14 +893,14 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { public void createTemptargetFromJsonIfNotExists(JSONObject trJson) { try { String units = MainApp.getConfigBuilder().getProfileUnits(); - TempTarget tempTarget = new TempTarget(); - tempTarget.date = trJson.getLong("mills"); - tempTarget.durationInMinutes = trJson.getInt("duration"); - tempTarget.low = Profile.toMgdl(trJson.getDouble("targetBottom"), units); - tempTarget.high = Profile.toMgdl(trJson.getDouble("targetTop"), units); - tempTarget.reason = trJson.getString("reason"); - tempTarget._id = trJson.getString("_id"); - tempTarget.source = Source.NIGHTSCOUT; + TempTarget tempTarget = new TempTarget() + .date(trJson.getLong("mills")) + .duration(trJson.getInt("duration")) + .low(Profile.toMgdl(trJson.getDouble("targetBottom"), units)) + .high(Profile.toMgdl(trJson.getDouble("targetTop"), units)) + .reason(trJson.getString("reason")) + ._id(trJson.getString("_id")) + .source(Source.NIGHTSCOUT); createOrUpdate(tempTarget); } catch (JSONException e) { log.error("Unhandled exception", e); @@ -1169,10 +1169,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { } createOrUpdate(extendedBolus); } else { - TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = trJson.getLong("mills"); - tempBasal.source = Source.NIGHTSCOUT; - tempBasal.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0; + TemporaryBasal tempBasal = new TemporaryBasal() + .date(trJson.getLong("mills")) + .source(Source.NIGHTSCOUT) + .pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0); if (trJson.has("duration")) { tempBasal.durationInMinutes = trJson.getInt("duration"); } diff --git a/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java b/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java index ba2f2758e2..9dca91c595 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java +++ b/app/src/main/java/info/nightscout/androidaps/db/ProfileSwitch.java @@ -61,6 +61,31 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface { private Profile profile = null; + public ProfileSwitch date(long date) { + this.date = date; + return this; + } + + public ProfileSwitch profileName(String profileName) { + this.profileName = profileName; + return this; + } + + public ProfileSwitch profile(Profile profile) { + this.profile = profile; + return this; + } + + public ProfileSwitch source(int source) { + this.source = source; + return this; + } + + public ProfileSwitch duration(int duration) { + this.durationInMinutes = duration; + return this; + } + @Nullable public Profile getProfileObject() { if (profile == null) diff --git a/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java b/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java index 980ce1c03c..ae016a0f29 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TempTarget.java @@ -71,6 +71,41 @@ public class TempTarget implements Interval { reason = t.reason; } + public TempTarget date(long date) { + this.date = date; + return this; + } + + public TempTarget low(double low) { + this.low = low; + return this; + } + + public TempTarget high(double high) { + this.high = high; + return this; + } + + public TempTarget duration(int duration) { + this.durationInMinutes = duration; + return this; + } + + public TempTarget reason(String reason) { + this.reason = reason; + return this; + } + + public TempTarget _id(String _id) { + this._id = _id; + return this; + } + + public TempTarget source(int source) { + this.source = source; + return this; + } + // -------- Interval interface --------- Long cuttedEnd = null; diff --git a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java index 9679a5e63d..e2303bac53 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -60,8 +60,36 @@ public class TemporaryBasal implements Interval { public TemporaryBasal() { } - public TemporaryBasal(long date) { + public TemporaryBasal date(long date) { this.date = date; + return this; + } + + public TemporaryBasal duration(int durationInMinutes) { + this.durationInMinutes = durationInMinutes; + return this; + } + + public TemporaryBasal absolute(double absoluteRate) { + this.absoluteRate = absoluteRate; + this.isAbsolute = true; + return this; + } + + public TemporaryBasal percent(int percentRate) { + this.percentRate = percentRate; + this.isAbsolute = false; + return this; + } + + public TemporaryBasal source(int source) { + this.source = source; + return this; + } + + public TemporaryBasal pumpId(long pumpId) { + this.pumpId = pumpId; + return this; } public TemporaryBasal(ExtendedBolus extendedBolus) { diff --git a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java index 4b4bfcb08d..31df191387 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/Treatment.java +++ b/app/src/main/java/info/nightscout/androidaps/db/Treatment.java @@ -128,7 +128,7 @@ public class Treatment implements DataPointWithLabelInterface { @Override public String getLabel() { String label = ""; - if (insulin > 0) label += DecimalFormatter.to2Decimal(insulin) + "U"; + if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin) + "U"; if (carbs > 0) label += "~" + DecimalFormatter.to0Decimal(carbs) + "g"; return label; @@ -149,7 +149,7 @@ public class Treatment implements DataPointWithLabelInterface { @Override public float getSize() { - return 10; + return 2; } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java index 4918cbfacf..a1daa08a56 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/ConstraintsInterface.java @@ -27,6 +27,10 @@ public interface ConstraintsInterface { return value; } + default Constraint isAdvancedFilteringEnabled(Constraint value) { + return value; + } + default Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { return absoluteRate; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java index 8bc79e3ddc..9a14471318 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/ActionsFragment.java @@ -116,9 +116,14 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL activity.runOnUiThread(new Runnable() { @Override public void run() { - if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) { - tempTarget.setVisibility(View.GONE); + if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) { + profileSwitch.setVisibility(View.VISIBLE); + } else { profileSwitch.setVisibility(View.GONE); + } + + if (MainApp.getConfigBuilder().getProfile() == null) { + tempTarget.setVisibility(View.GONE); extendedBolus.setVisibility(View.GONE); extendedBolusCancel.setVisibility(View.GONE); tempBasal.setVisibility(View.GONE); @@ -126,6 +131,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL fill.setVisibility(View.GONE); return; } + final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease() && pump.getPumpDescription().isSetBasalProfileCapable; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java index c0e668439c..b3b15bf7fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Actions/dialogs/FillDialog.java @@ -1,11 +1,11 @@ package info.nightscout.androidaps.plugins.Actions.dialogs; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.support.v7.app.AlertDialog; +import android.text.Html; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -13,17 +13,23 @@ import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager; import android.widget.Button; +import android.widget.CheckBox; import com.crashlytics.android.answers.CustomEvent; +import com.google.common.base.Joiner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import info.nightscout.androidaps.Constants; import java.text.DecimalFormat; +import java.util.LinkedList; +import java.util.List; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; +import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; @@ -31,6 +37,7 @@ import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -38,13 +45,13 @@ import info.nightscout.utils.SafeParse; public class FillDialog extends DialogFragment implements OnClickListener { private static Logger log = LoggerFactory.getLogger(FillDialog.class); - Button deliverButton; - double amount1 = 0d; double amount2 = 0d; double amount3 = 0d; NumberPicker editInsulin; + CheckBox pumpSiteChangeCheckbox; + CheckBox insulinCartridgeChangeCheckbox; public FillDialog() { } @@ -54,22 +61,24 @@ public class FillDialog extends DialogFragment implements OnClickListener { Bundle savedInstanceState) { View view = inflater.inflate(R.layout.actions_fill_dialog, null, false); - deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton); + view.findViewById(R.id.ok).setOnClickListener(this); + view.findViewById(R.id.cancel).setOnClickListener(this); - deliverButton.setOnClickListener(this); getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE); getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); + pumpSiteChangeCheckbox = view.findViewById(R.id.catheter_change); + insulinCartridgeChangeCheckbox = view.findViewById(R.id.cartridge_change); + Double maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value(); double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; - editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); - editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false); + editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount); + editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false); //setup preset buttons Button button1 = (Button) view.findViewById(R.id.fill_preset_button1); Button button2 = (Button) view.findViewById(R.id.fill_preset_button2); Button button3 = (Button) view.findViewById(R.id.fill_preset_button3); - View divider = view.findViewById(R.id.fill_preset_divider); amount1 = SP.getDouble("fill_button1", 0.3); amount2 = SP.getDouble("fill_button2", 0d); @@ -77,103 +86,109 @@ public class FillDialog extends DialogFragment implements OnClickListener { if (amount1 > 0) { button1.setVisibility(View.VISIBLE); - button1.setText(DecimalFormatter.to2Decimal(amount1) + "U"); + button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U"); button1.setOnClickListener(this); } else { button1.setVisibility(View.GONE); } if (amount2 > 0) { button2.setVisibility(View.VISIBLE); - button2.setText(DecimalFormatter.to2Decimal(amount2) + "U"); + button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U"); button2.setOnClickListener(this); } else { button2.setVisibility(View.GONE); } if (amount3 > 0) { button3.setVisibility(View.VISIBLE); - button3.setText(DecimalFormatter.to2Decimal(amount3) + "U"); + button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U"); button3.setOnClickListener(this); } else { button3.setVisibility(View.GONE); } - if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) { - divider.setVisibility(View.GONE); - } - setCancelable(true); getDialog().setCanceledOnTouchOutside(false); return view; } - @Override - public void onResume() { - super.onResume(); - if (getDialog() != null) - getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); - } - @Override public void onClick(View view) { switch (view.getId()) { - case R.id.treatments_newtreatment_deliverbutton: - Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString()); - confirmAndDeliver(insulin); + case R.id.ok: + confirmAndDeliver(); + break; + case R.id.cancel: + dismiss(); break; case R.id.fill_preset_button1: - confirmAndDeliver(amount1); + editInsulin.setValue(amount1); break; case R.id.fill_preset_button2: - confirmAndDeliver(amount2); + editInsulin.setValue(amount2); break; case R.id.fill_preset_button3: - confirmAndDeliver(amount3); + editInsulin.setValue(amount3); break; } } - private void confirmAndDeliver(Double insulin) { + private void confirmAndDeliver() { try { + Double insulin = SafeParse.stringToDouble(editInsulin.getText()); - String confirmMessage = getString(R.string.fillwarning) + "\n"; + List confirmMessage = new LinkedList<>(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); - confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U"; - if (insulinAfterConstraints - insulin != 0) - confirmMessage += "\n" + getString(R.string.constraintapllied); + if (insulinAfterConstraints > 0) { + confirmMessage.add(MainApp.gs(R.string.fillwarning)); + confirmMessage.add(""); + confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "" + insulinAfterConstraints + "U" + ""); + if (!insulinAfterConstraints.equals(insulin)) + confirmMessage.add("" + MainApp.gs(R.string.bolusconstraintapplied) + ""); + } + + if (pumpSiteChangeCheckbox.isChecked()) + confirmMessage.add("" + "" + getString(R.string.record_pump_site_change) + ""); + + if (insulinCartridgeChangeCheckbox.isChecked()) + confirmMessage.add("" + "" + getString(R.string.record_insulin_cartridge_change) + ""); final Double finalInsulinAfterConstraints = insulinAfterConstraints; final Context context = getContext(); AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(this.getContext().getString(R.string.confirmation)); - builder.setMessage(confirmMessage); - builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - if (finalInsulinAfterConstraints > 0) { - DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); - detailedBolusInfo.insulin = finalInsulinAfterConstraints; - detailedBolusInfo.context = context; - detailedBolusInfo.source = Source.USER; - detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) - ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { - @Override - public void run() { - if (!result.success) { - Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); - i.putExtra("soundid", R.raw.boluserror); - i.putExtra("status", result.comment); - i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror)); - i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - MainApp.instance().startActivity(i); - } + if (confirmMessage.isEmpty()) + confirmMessage.add(MainApp.gs(R.string.no_action_selected)); + + builder.setTitle(MainApp.gs(R.string.confirmation)); + builder.setMessage(Html.fromHtml(Joiner.on("
").join(confirmMessage))); + builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> { + if (finalInsulinAfterConstraints > 0) { + DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); + detailedBolusInfo.insulin = finalInsulinAfterConstraints; + detailedBolusInfo.context = context; + detailedBolusInfo.source = Source.USER; + detailedBolusInfo.isValid = false; // do not count it in IOB (for pump history) + ConfigBuilderPlugin.getCommandQueue().bolus(detailedBolusInfo, new Callback() { + @Override + public void run() { + if (!result.success) { + Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); + i.putExtra("soundid", R.raw.boluserror); + i.putExtra("status", result.comment); + i.putExtra("title", MainApp.sResources.getString(R.string.treatmentdeliveryerror)); + i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + MainApp.instance().startActivity(i); } - }); - FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); - } + } + }); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Fill")); } + long now = System.currentTimeMillis(); + if (pumpSiteChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.SITECHANGE, now); + if (insulinCartridgeChangeCheckbox.isChecked()) NSUpload.uploadEvent(CareportalEvent.INSULINCHANGE, now + 1000); }); builder.setNegativeButton(getString(R.string.cancel), null); builder.show(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java index 3c77532e11..7aea403941 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Careportal/Dialogs/NewNSTreatmentDialog.java @@ -51,13 +51,13 @@ import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventNewBasalProfile; -import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.HardLimits; import info.nightscout.utils.NSUpload; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; @@ -108,6 +108,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick Date eventTime; + private static Integer seconds = null; + public void setOptions(OptionsToShow options, int event) { this.options = options; this.event = MainApp.sResources.getString(event); @@ -115,6 +117,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public NewNSTreatmentDialog() { super(); + + if (seconds == null) { + seconds = new Double(Math.random() * 59).intValue(); + } } @Override @@ -327,7 +333,9 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } }; - Double maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); + Double maxAbsolute = HardLimits.maxBasal(); + if (profile != null) + maxAbsolute = MainApp.getConstraintChecker().getMaxBasalAllowed(profile).value(); editAbsolute = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput); editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher); @@ -340,19 +348,19 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick editTimeshift = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_timeshift); editTimeshift.setParams(0d, (double) Constants.CPP_MIN_TIMESHIFT, (double) Constants.CPP_MAX_TIMESHIFT, 1d, new DecimalFormat("0"), false); - ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(System.currentTimeMillis()); + ProfileSwitch ps = MainApp.getConfigBuilder().getProfileSwitchFromHistory(DateUtil.now()); if (ps != null && ps.isCPP) { final int percentage = ps.percentage; final int timeshift = ps.timeshift; reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h"); - reuseButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - editPercentage.setValue((double) percentage); - editTimeshift.setValue((double) timeshift); - } + reuseButton.setOnClickListener(v -> { + editPercentage.setValue((double) percentage); + editTimeshift.setValue((double) timeshift); }); } + if (ps == null) { + options.duration = false; + } showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_eventtime_layout), options.date); showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg); @@ -421,8 +429,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick long millis = eventTime.getTime() - (150 * 1000L); // 2,5 * 60 * 1000 List data = MainApp.getDbHelper().getBgreadingsDataFromTime(millis, true); if ((data.size() > 0) && - (data.get(0).date > millis - 7 * 60 * 1000L) && - (data.get(0).date < millis + 7 * 60 * 1000L)) { + (data.get(0).date > millis - 7 * 60 * 1000L) && + (data.get(0).date < millis + 7 * 60 * 1000L)) { editBg.setValue(Profile.fromMgdlToUnits(data.get(0).value, profile != null ? profile.getUnits() : Constants.MGDL)); } } @@ -440,7 +448,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { eventTime.setHours(hourOfDay); eventTime.setMinutes(minute); - eventTime.setSeconds(second); + eventTime.setSeconds(this.seconds++); // randomize seconds to prevent creating record of the same time, if user choose time manually timeButton.setText(DateUtil.timeString(eventTime)); updateBGforDateTime(); } @@ -692,17 +700,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick } else if (options.executeTempTarget) { try { if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = eventTime.getTime(); - tempTarget.durationInMinutes = data.getInt("duration"); - tempTarget.reason = data.getString("reason"); - tempTarget.source = Source.USER; + TempTarget tempTarget = new TempTarget() + .date(eventTime.getTime()) + .duration(data.getInt("duration")) + .reason(data.getString("reason")) + .source(Source.USER); if (tempTarget.durationInMinutes != 0) { - tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()); - tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()); + tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits())) + .high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits())); } else { - tempTarget.low = 0; - tempTarget.high = 0; + tempTarget.low(0).high(0); } log.debug("Creating new TempTarget db record: " + tempTarget.toString()); MainApp.getDbHelper().createOrUpdate(tempTarget); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java index fd224531b4..da3dba05a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderFragment.java @@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.support.v4.app.Fragment; +import android.support.annotation.NonNull; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -17,11 +17,13 @@ import android.widget.ListAdapter; import android.widget.ListView; import android.widget.TextView; - import com.crashlytics.android.answers.CustomEvent; import java.util.ArrayList; +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.PreferencesActivity; import info.nightscout.androidaps.R; @@ -35,6 +37,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface; +import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.Insulin.InsulinFastactingPlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; @@ -43,33 +46,46 @@ import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.PasswordProtection; -public class ConfigBuilderFragment extends Fragment { - - static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin(); - - static public ConfigBuilderPlugin getPlugin() { - return configBuilderPlugin; - } +public class ConfigBuilderFragment extends SubscriberFragment { + @BindView(R.id.configbuilder_insulinlistview) ListView insulinListView; + @BindView(R.id.configbuilder_sensitivitylistview) ListView sensitivityListView; + @BindView(R.id.configbuilder_bgsourcelistview) ListView bgsourceListView; + @BindView(R.id.configbuilder_bgsourcelabel) TextView bgsourceLabel; + @BindView(R.id.configbuilder_pumplistview) ListView pumpListView; + @BindView(R.id.configbuilder_pumplabel) TextView pumpLabel; + @BindView(R.id.configbuilder_looplistview) ListView loopListView; + @BindView(R.id.configbuilder_looplabel) TextView loopLabel; + @BindView(R.id.configbuilder_treatmentslistview) ListView treatmentsListView; + @BindView(R.id.configbuilder_treatmentslabel) TextView treatmentsLabel; + @BindView(R.id.configbuilder_profilelistview) ListView profileListView; + @BindView(R.id.configbuilder_profilelabel) TextView profileLabel; + @BindView(R.id.configbuilder_apslistview) ListView apsListView; + @BindView(R.id.configbuilder_apslabel) TextView apsLabel; + @BindView(R.id.configbuilder_constraintslistview) ListView constraintsListView; + @BindView(R.id.configbuilder_constraintslabel) TextView constraintsLabel; + @BindView(R.id.configbuilder_generallistview) ListView generalListView; + @BindView(R.id.configbuilder_mainlayout) LinearLayout mainLayout; + @BindView(R.id.configbuilder_unlock) Button unlock; PluginCustomAdapter insulinDataAdapter = null; @@ -84,51 +100,17 @@ public class ConfigBuilderFragment extends Fragment { PluginCustomAdapter generalDataAdapter = null; @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { try { View view = inflater.inflate(R.layout.configbuilder_fragment, container, false); - insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview); - sensitivityListView = (ListView) view.findViewById(R.id.configbuilder_sensitivitylistview); - bgsourceListView = (ListView) view.findViewById(R.id.configbuilder_bgsourcelistview); - bgsourceLabel = (TextView) view.findViewById(R.id.configbuilder_bgsourcelabel); - pumpListView = (ListView) view.findViewById(R.id.configbuilder_pumplistview); - pumpLabel = (TextView) view.findViewById(R.id.configbuilder_pumplabel); - loopListView = (ListView) view.findViewById(R.id.configbuilder_looplistview); - loopLabel = (TextView) view.findViewById(R.id.configbuilder_looplabel); - treatmentsListView = (ListView) view.findViewById(R.id.configbuilder_treatmentslistview); - treatmentsLabel = (TextView) view.findViewById(R.id.configbuilder_treatmentslabel); - profileListView = (ListView) view.findViewById(R.id.configbuilder_profilelistview); - profileLabel = (TextView) view.findViewById(R.id.configbuilder_profilelabel); - apsListView = (ListView) view.findViewById(R.id.configbuilder_apslistview); - apsLabel = (TextView) view.findViewById(R.id.configbuilder_apslabel); - constraintsListView = (ListView) view.findViewById(R.id.configbuilder_constraintslistview); - constraintsLabel = (TextView) view.findViewById(R.id.configbuilder_constraintslabel); - generalListView = (ListView) view.findViewById(R.id.configbuilder_generallistview); + unbinder = ButterKnife.bind(this, view); - mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout); - unlock = (Button) view.findViewById(R.id.configbuilder_unlock); - - setViews(); - - if (PasswordProtection.isLocked("settings_password")) { + if (PasswordProtection.isLocked("settings_password")) mainLayout.setVisibility(View.GONE); - unlock.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - mainLayout.setVisibility(View.VISIBLE); - unlock.setVisibility(View.GONE); - } - }, null); - } - }); - } else { + else unlock.setVisibility(View.GONE); - } return view; } catch (Exception e) { FabricPrivacy.logException(e); @@ -137,7 +119,18 @@ public class ConfigBuilderFragment extends Fragment { return null; } - void setViews() { + @OnClick(R.id.configbuilder_unlock) + public void onClickUnlock() { + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + mainLayout.setVisibility(View.VISIBLE); + unlock.setVisibility(View.GONE); + }, null); + } + + + @Override + protected void updateGUI() { + insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN); insulinListView.setAdapter(insulinDataAdapter); setListViewHeightBasedOnChildren(insulinListView); @@ -182,7 +175,6 @@ public class ConfigBuilderFragment extends Fragment { generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL); generalListView.setAdapter(generalDataAdapter); setListViewHeightBasedOnChildren(generalListView); - } /* @@ -194,8 +186,8 @@ public class ConfigBuilderFragment extends Fragment { private ArrayList pluginList; final private int type; - public PluginCustomAdapter(Context context, int textViewResourceId, - ArrayList pluginList, int type) { + PluginCustomAdapter(Context context, int textViewResourceId, + ArrayList pluginList, int type) { super(context, textViewResourceId, pluginList); this.pluginList = new ArrayList<>(); this.pluginList.addAll(pluginList); @@ -209,10 +201,11 @@ public class ConfigBuilderFragment extends Fragment { ImageView settings; } + @NonNull @Override - public View getView(int position, View view, ViewGroup parent) { + public View getView(int position, View view, @NonNull ViewGroup parent) { - PluginViewHolder holder = null; + PluginViewHolder holder; PluginBase plugin = pluginList.get(position); if (view == null) { @@ -231,60 +224,45 @@ public class ConfigBuilderFragment extends Fragment { view.setTag(holder); - holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - CheckBox cb = (CheckBox) v; - PluginBase plugin = (PluginBase) cb.getTag(); - plugin.setPluginEnabled(type, cb.isChecked()); - plugin.setFragmentVisible(type, cb.isChecked()); - onEnabledCategoryChanged(plugin, type); - configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui()); - MainApp.bus().post(new EventConfigBuilderChange()); - getPlugin().logPluginStatus(); - FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); - } + holder.checkboxEnabled.setOnClickListener(v -> { + CheckBox cb = (CheckBox) v; + PluginBase plugin1 = (PluginBase) cb.getTag(); + plugin1.setPluginEnabled(type, cb.isChecked()); + plugin1.setFragmentVisible(type, cb.isChecked()); + onEnabledCategoryChanged(plugin1, type); + ConfigBuilderPlugin.getPlugin().storeSettings(); + MainApp.bus().post(new EventRefreshGui()); + MainApp.bus().post(new EventConfigBuilderChange()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); + FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); }); - holder.checkboxVisible.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - CheckBox cb = (CheckBox) v; - PluginBase plugin = (PluginBase) cb.getTag(); - plugin.setFragmentVisible(type, cb.isChecked()); - configBuilderPlugin.storeSettings(); - MainApp.bus().post(new EventRefreshGui()); - getPlugin().logPluginStatus(); - } + holder.checkboxVisible.setOnClickListener(v -> { + CheckBox cb = (CheckBox) v; + PluginBase plugin12 = (PluginBase) cb.getTag(); + plugin12.setFragmentVisible(type, cb.isChecked()); + ConfigBuilderPlugin.getPlugin().storeSettings(); + MainApp.bus().post(new EventRefreshGui()); + ConfigBuilderPlugin.getPlugin().logPluginStatus(); }); - holder.settings.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - final PluginBase plugin = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin.getPreferencesId()); - startActivity(i); - } - }, null); - } + holder.settings.setOnClickListener(v -> { + final PluginBase plugin13 = (PluginBase) v.getTag(); + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(getContext(), PreferencesActivity.class); + i.putExtra("id", plugin13.getPreferencesId()); + startActivity(i); + }, null); }); - holder.name.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - final PluginBase plugin = (PluginBase) v.getTag(); - PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() { - @Override - public void run() { - Intent i = new Intent(getContext(), PreferencesActivity.class); - i.putExtra("id", plugin.getPreferencesId()); - startActivity(i); - } - }, null); - return false; - } + holder.name.setOnLongClickListener(v -> { + final PluginBase plugin14 = (PluginBase) v.getTag(); + PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> { + Intent i = new Intent(getContext(), PreferencesActivity.class); + i.putExtra("id", plugin14.getPreferencesId()); + startActivity(i); + }, null); + return false; }); } else { @@ -317,7 +295,7 @@ public class ConfigBuilderFragment extends Fragment { if (pluginList.size() < 2) { holder.checkboxEnabled.setEnabled(false); plugin.setPluginEnabled(type, true); - getPlugin().storeSettings(); + ConfigBuilderPlugin.getPlugin().storeSettings(); } // Constraints cannot be disabled @@ -396,17 +374,17 @@ public class ConfigBuilderFragment extends Fragment { } } else { // enable first plugin in list if (type == PluginBase.PUMP) - MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setPluginEnabled(type, true); + VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.INSULIN) - MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setPluginEnabled(type, true); + InsulinFastactingPlugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.SENSITIVITY) - MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setPluginEnabled(type, true); + SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true); else if (type == PluginBase.PROFILE) - MainApp.getSpecificPlugin(NSProfilePlugin.class).setPluginEnabled(type, true); + NSProfilePlugin.getPlugin().setPluginEnabled(type, true); else pluginsInCategory.get(0).setPluginEnabled(type, true); } - setViews(); + updateGUI(); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java index 8818c11921..51d91732ca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConfigBuilder/ConfigBuilderPlugin.java @@ -4,12 +4,15 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.annotation.Nullable; +import com.crashlytics.android.answers.CustomEvent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.List; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -20,6 +23,7 @@ import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileIntervals; +import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.ExtendedBolus; @@ -45,6 +49,7 @@ import info.nightscout.androidaps.plugins.Overview.notifications.Notification; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.CommandQueue; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NSUpload; import info.nightscout.utils.ToastUtils; @@ -54,7 +59,15 @@ import info.nightscout.utils.ToastUtils; public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class); - private static BgSourceInterface activeBgSource; + private static ConfigBuilderPlugin configBuilderPlugin; + + static public ConfigBuilderPlugin getPlugin() { + if (configBuilderPlugin == null) + configBuilderPlugin = new ConfigBuilderPlugin(); + return configBuilderPlugin; + } + + private BgSourceInterface activeBgSource; private static PumpInterface activePump; private static ProfileInterface activeProfile; private static TreatmentsInterface activeTreatments; @@ -193,7 +206,7 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { return commandQueue; } - public static BgSourceInterface getActiveBgSource() { + public BgSourceInterface getActiveBgSource() { return activeBgSource; } @@ -653,9 +666,12 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { if (profileSwitch.profileJson != null) { return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; } else { - Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); - if (profile != null) - return profileSwitch.profileName; + ProfileStore profileStore = activeProfile.getProfile(); + if (profileStore != null) { + Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); + if (profile != null) + return profileSwitch.profileName; + } } } return MainApp.gs(R.string.noprofileselected); @@ -692,6 +708,14 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { return profile; } } + if (getProfileSwitchesFromHistory().size() > 0) { + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("time", time) + .putCustomAttribute("getProfileSwitchesFromHistory", getProfileSwitchesFromHistory().toString()) + ); + } log.debug("getProfile at the end: returning null"); return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java index 5c792c9405..e76be9a32c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ConstraintsSafety/SafetyPlugin.java @@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; +import info.nightscout.androidaps.data.ConstraintChecker; import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.interfaces.BgSourceInterface; import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; @@ -126,6 +128,21 @@ public class SafetyPlugin implements PluginBase, ConstraintsInterface { boolean enabled = SP.getBoolean(R.string.key_use_smb, false); if (!enabled) value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this); + ConstraintChecker constraintChecker = MainApp.getConstraintChecker(); + Constraint closedLoop = constraintChecker.isClosedLoopAllowed(); + if (!closedLoop.value()) + value.set(false, MainApp.gs(R.string.smbnotallowedinopenloopmode), this); + return value; + } + + @Override + public Constraint isAdvancedFilteringEnabled(Constraint value) { + BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource(); + + if (bgSource != null) { + if (!bgSource.advancedFilteringSupported()) + value.set(false, MainApp.gs(R.string.smbalwaysdisabled), this); + } return value; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java index dddea570be..7a79b62c3a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/AutosensData.java @@ -64,7 +64,8 @@ public class AutosensData { public double slopeFromMaxDeviation = 0; public double slopeFromMinDeviation = 999; - public String log(long time) { + @Override + 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 ; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java index 0009287354..6128dffadd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobCalculatorPlugin.java @@ -351,12 +351,11 @@ public class IobCobCalculatorPlugin implements PluginBase { 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; + IobTotal basalIobWithZeroTemp = basalIob.copy(); + TemporaryBasal t = new TemporaryBasal() + .date(now + 60 * 1000L) + .duration(240) + .absolute(0); if (t.date < time) { IobTotal calc = t.iobCalc(time); basalIobWithZeroTemp.plus(calc); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java index 1a4c499c59..5da63ad2f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/IobCobCalculator/IobCobThread.java @@ -4,6 +4,9 @@ import android.content.Context; import android.os.PowerManager; import android.support.v4.util.LongSparseArray; +import com.crashlytics.android.Crashlytics; +import com.crashlytics.android.answers.CustomEvent; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,6 +14,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -22,6 +26,7 @@ import info.nightscout.androidaps.events.Event; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.queue.QueueThread; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.FabricPrivacy; /** * Created by mike on 23.01.2018. @@ -151,21 +156,34 @@ public class IobCobThread extends Thread { AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); if (hourAgoData != null) { int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); + log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()); + int past = 1; + try { + for (; past < 12; past++) { + AutosensData ad = autosensDataTable.valueAt(initialIndex + past); + double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; + if (ad.avgDeviation > maxDeviation) { + slopeFromMaxDeviation = Math.min(0, deviationSlope); + maxDeviation = ad.avgDeviation; + } + if (ad.avgDeviation < minDeviation) { + slopeFromMinDeviation = Math.max(0, deviationSlope); + minDeviation = ad.avgDeviation; + } - for (int past = 1; past < 12; past++) { - AutosensData ad = autosensDataTable.valueAt(initialIndex + past); - double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; - if (ad.avgDeviation > maxDeviation) { - slopeFromMaxDeviation = Math.min(0, deviationSlope); - maxDeviation = ad.avgDeviation; + //if (Config.logAutosensData) + // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); } - if (ad.avgDeviation < minDeviation) { - slopeFromMinDeviation = Math.max(0, deviationSlope); - minDeviation = ad.avgDeviation; - } - - //if (Config.logAutosensData) - // log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); + } catch (Exception e) { + log.error("Unhandled exception", e); + FabricPrivacy.logException(e); + FabricPrivacy.getInstance().logCustom(new CustomEvent("CatchedError") + .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) + .putCustomAttribute("version", BuildConfig.VERSION) + .putCustomAttribute("autosensDataTable", iobCobCalculatorPlugin.getAutosensDataTable().toString()) + .putCustomAttribute("for_data", ">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString()) + .putCustomAttribute("past", past) + ); } } } @@ -228,7 +246,7 @@ public class IobCobThread extends Thread { log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime)); autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio; if (Config.logAutosensData) - log.debug(autosensData.log(bgTime)); + log.debug(autosensData.toString()); } } MainApp.bus().post(new EventAutosensCalculationFinished(cause)); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java index 9b851c64c1..7a9c4deae9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Loop/APSResult.java @@ -62,7 +62,7 @@ public class APSResult { // smb if (smb != 0) - ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n"); + ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U\n"); // reason ret += MainApp.sResources.getString(R.string.reason) + ": " + reason; @@ -87,7 +87,7 @@ public class APSResult { // smb if (smb != 0) - ret += ("" + "SMB" + ": " + DecimalFormatter.to2Decimal(smb) + " U
"); + ret += ("" + "SMB" + ": " + DecimalFormatter.toPumpSupportedBolus(smb) + " U
"); // reason ret += "" + MainApp.sResources.getString(R.string.reason) + ": " + reason.replace("<", "<").replace(">", ">"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java index e644b13dc9..12c3122a76 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/DetermineBasalAdapterSMBJS.java @@ -46,6 +46,7 @@ public class DetermineBasalAdapterSMBJS { private JSONObject mCurrentTemp; private JSONObject mAutosensData = null; private boolean mMicrobolusAllowed; + private boolean mSMBAlwaysAllowed; private String storedCurrentTemp = null; private String storedIobData = null; @@ -55,6 +56,7 @@ public class DetermineBasalAdapterSMBJS { private String storedMeal_data = null; private String storedAutosens_data = null; private String storedMicroBolusAllowed = null; + private String storedSMBAlwaysAllowed = null; private String scriptDebug = ""; @@ -82,6 +84,7 @@ public class DetermineBasalAdapterSMBJS { log.debug("Autosens data: " + (storedAutosens_data = "undefined")); log.debug("Reservoir data: " + "undefined"); log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed)); + log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed)); DetermineBasalResultSMB determineBasalResultSMB = null; @@ -210,7 +213,8 @@ public class DetermineBasalAdapterSMBJS { MealData mealData, double autosensDataRatio, boolean tempTargetSet, - boolean microBolusAllowed + boolean microBolusAllowed, + boolean smbAlwaysAllowed ) throws JSONException { String units = profile.getUnits(); @@ -244,12 +248,11 @@ public class DetermineBasalAdapterSMBJS { 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); - boolean SMBEnabled = MainApp.getConstraintChecker().isSMBModeEnabled().value() && MainApp.getConstraintChecker().isClosedLoopAllowed().value(); - mProfile.put("enableSMB_with_COB", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_COB, false)); - mProfile.put("enableSMB_with_temptarget", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_with_temptarget, false)); - mProfile.put("allowSMB_with_high_temptarget", SMBEnabled && SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false)); - mProfile.put("enableSMB_always", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported()); - mProfile.put("enableSMB_after_carbs", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported()); + mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false)); + mProfile.put("enableSMB_with_temptarget", SP.getBoolean(R.string.key_enableSMB_with_temptarget, false)); + mProfile.put("allowSMB_with_high_temptarget", SP.getBoolean(R.string.key_allowSMB_with_high_temptarget, false)); + mProfile.put("enableSMB_always", SP.getBoolean(R.string.key_enableSMB_always, false) && smbAlwaysAllowed); + mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && smbAlwaysAllowed); mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes)); mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold); @@ -308,6 +311,7 @@ public class DetermineBasalAdapterSMBJS { mAutosensData.put("ratio", 1.0); } mMicrobolusAllowed = microBolusAllowed; + mSMBAlwaysAllowed = smbAlwaysAllowed; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java index dcba600fb4..c35e229354 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBFragment.java @@ -95,26 +95,26 @@ public class OpenAPSSMBFragment extends SubscriberFragment { } DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS; if (determineBasalAdapterSMBJS != null) { - glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam())); - currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam())); + glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim()); + currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim()); try { JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam()); - iobDataView.setText(String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))); + iobDataView.setText((String.format(MainApp.sResources.getString(R.string.array_of_elements), iobArray.length()) + "\n" + JSONFormatter.format(iobArray.getString(0))).trim()); } catch (JSONException e) { - e.printStackTrace(); - iobDataView.setText("JSONException"); + log.error("Unhandled exception", e); + iobDataView.setText("JSONException see log for details"); } - profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam())); - mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam())); - scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug()); + profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim()); + mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim()); + scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim()); if (lastAPSResult != null && lastAPSResult.inputConstraints != null) - constraintsView.setText(lastAPSResult.inputConstraints.getReasons()); + constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim()); } if (plugin.lastAPSRun != null) { - lastRunView.setText(plugin.lastAPSRun.toLocaleString()); + lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim()); } if (plugin.lastAutosensResult != null) { - autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json())); + autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim()); } } }); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java index c0b57a80d4..2f50d72335 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/OpenAPSSMB/OpenAPSSMBPlugin.java @@ -231,6 +231,15 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { } else { lastAutosensResult = new AutosensResult(); } + + Constraint smbAllowed = new Constraint<>(true); + MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed); + inputConstraints.copyReasons(smbAllowed); + + Constraint smbAlwaysEnabled = new Constraint<>(true); + MainApp.getConstraintChecker().isAdvancedFilteringEnabled(smbAlwaysEnabled); + inputConstraints.copyReasons(smbAlwaysEnabled); + Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); Profiler.log(log, "SMB data gathering", start); @@ -239,7 +248,8 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface { determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData, lastAutosensResult.ratio, //autosensDataRatio isTempTarget, - true //microBolusAllowed + smbAllowed.value(), + smbAlwaysEnabled.value() ); } catch (JSONException e) { log.error(e.getMessage()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java index a17470eb2c..8c23c072cf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewCarbsDialog.java @@ -380,31 +380,31 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D accepted = true; if (startActivityTTCheckbox.isChecked()) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = System.currentTimeMillis(); - tempTarget.durationInMinutes = finalActivityTTDuration; - tempTarget.reason = MainApp.gs(R.string.activity); - tempTarget.source = Source.USER; - tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); - tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(finalActivityTTDuration) + .reason(MainApp.gs(R.string.activity)) + .source(Source.USER) + .low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits())) + .high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits())); MainApp.getDbHelper().createOrUpdate(tempTarget); } else if (startEatingSoonTTCheckbox.isChecked()) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = System.currentTimeMillis(); - tempTarget.durationInMinutes = finalEatingSoonTTDuration; - tempTarget.reason = MainApp.gs(R.string.eatingsoon); - tempTarget.source = Source.USER; - tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); - tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(finalEatingSoonTTDuration) + .reason(MainApp.gs(R.string.eatingsoon)) + .source(Source.USER) + .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())) + .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits())); MainApp.getDbHelper().createOrUpdate(tempTarget); } else if (startHypoTTCheckbox.isChecked()) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = System.currentTimeMillis(); - tempTarget.durationInMinutes = finalHypoTTDuration; - tempTarget.reason = MainApp.gs(R.string.hypo); - tempTarget.source = Source.USER; - tempTarget.low = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); - tempTarget.high = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(finalHypoTTDuration) + .reason(MainApp.gs(R.string.hypo)) + .source(Source.USER) + .low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits())) + .high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits())); MainApp.getDbHelper().createOrUpdate(tempTarget); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java index 11eabfb3c6..8b4d74ebba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/NewInsulinDialog.java @@ -20,7 +20,6 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.TextView; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.google.common.base.Joiner; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; @@ -48,6 +47,8 @@ import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.queue.Callback; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.DecimalFormatter; +import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.NumberPicker; import info.nightscout.utils.SP; import info.nightscout.utils.SafeParse; @@ -124,7 +125,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newinsulin_amount); - editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, new DecimalFormat("0.00"), false, textWatcher); + editInsulin.setParams(0d, 0d, maxInsulin, ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate); timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime); @@ -160,7 +161,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, } private String toSignedString(double value) { - return value > 0 ? "+" + value : String.valueOf(value); + String formatted = DecimalFormatter.toPumpSupportedBolus(value); + return value > 0 ? "+" + formatted : formatted; } @Override @@ -279,13 +281,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, accepted = true; if (startESMCheckbox.isChecked()) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = System.currentTimeMillis(); - tempTarget.durationInMinutes = (int) ttDuration; - tempTarget.reason = "Eating soon"; - tempTarget.source = Source.USER; - tempTarget.low = (int) finalTT; - tempTarget.high = (int) finalTT; + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration((int) ttDuration) + .reason("Eating soon") + .source(Source.USER) + .low((int) finalTT) + .high((int) finalTT); MainApp.getDbHelper().createOrUpdate(tempTarget); } @@ -319,7 +321,7 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener, } } }); - Answers.getInstance().logCustom(new CustomEvent("Bolus")); + FabricPrivacy.getInstance().logCustom(new CustomEvent("Bolus")); } } }); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java index 34980b054a..d48b2ccf34 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/Dialogs/WizardDialog.java @@ -243,7 +243,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com editBg.setParams(0d, 0d, 500d, 0.1d, new DecimalFormat("0.0"), false, textWatcher); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher); double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; - editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, new DecimalFormat("0.00"), false, textWatcher); + editCorr.setParams(0d, -maxCorrection, maxCorrection, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false, textWatcher); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false); initDialog(); @@ -260,19 +260,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } private void saveCheckedStates() { - //SP.putBoolean(getString(R.string.key_wizard_include_bg), bgCheckbox.isChecked()); SP.putBoolean(getString(R.string.key_wizard_include_cob), cobCheckbox.isChecked()); SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.isChecked()); - //SP.putBoolean(getString(R.string.key_wizard_include_bolus_iob), bolusIobCheckbox.isChecked()); - //SP.putBoolean(getString(R.string.key_wizard_include_basal_iob), basalIobCheckbox.isChecked()); } private void loadCheckedStates() { - //bgCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bg), true)); bgtrendCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_trend_bg), false)); cobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_cob), false)); - //bolusIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_bolus_iob), true)); - //basalIobCheckbox.setChecked(SP.getBoolean(getString(R.string.key_wizard_include_basal_iob), true)); } @Override @@ -461,7 +455,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com Double c_bg = SafeParse.stringToDouble(editBg.getText()); Integer c_carbs = SafeParse.stringToInt(editCarbs.getText()); Double c_correction = SafeParse.stringToDouble(editCorr.getText()); - Double corrAfterConstraint = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); + Double corrAfterConstraint = c_correction; + if (c_correction > 0) + c_correction = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(c_correction)).value(); if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work editCorr.setValue(0d); ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); @@ -534,7 +530,7 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com } if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) { - String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.to2Decimal(calculatedTotalInsulin) + "U") : ""; + String insulinText = calculatedTotalInsulin > 0d ? (DecimalFormatter.toPumpSupportedBolus(calculatedTotalInsulin) + "U") : ""; String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : ""; total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText); okButton.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java index dc0cb27ed7..e6f4772d7a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/OverviewFragment.java @@ -288,13 +288,28 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, llm = new LinearLayoutManager(view.getContext()); notificationsView.setLayoutManager(llm); + int axisWidth = 50; + + if (dm.densityDpi <= 120) + axisWidth = 3; + else if (dm.densityDpi <= 160) + axisWidth = 10; + else if (dm.densityDpi <= 320) + axisWidth = 35; + else if (dm.densityDpi <= 420) + axisWidth = 50; + else if (dm.densityDpi <= 560) + axisWidth = 70; + else + axisWidth = 80; + bgGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); bgGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); iobGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); - bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50); - iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); + bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); + iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth); iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6); @@ -1166,7 +1181,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, extendedBolusView.setText(extendedBolusText); } if (extendedBolusText.equals("")) - extendedBolusView.setVisibility(View.GONE); + extendedBolusView.setVisibility(View.INVISIBLE); else extendedBolusView.setVisibility(View.VISIBLE); } @@ -1194,7 +1209,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, quickWizardButton.setVisibility(View.VISIBLE); String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false); - text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U"; + text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U"; quickWizardButton.setText(text); if (wizard.calculatedTotalInsulin <= 0) quickWizardButton.setVisibility(View.GONE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java index 0051518bb4..9c8e312fb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Overview/graphExtensions/PointsWithLabelGraphSeries.java @@ -48,11 +48,11 @@ import java.util.Iterator; */ public class PointsWithLabelGraphSeries extends BaseSeries { // Default spSize - int spSize = 12; + int spSize = 14; // Convert the sp to pixels Context context = MainApp.instance().getApplicationContext(); float scaledTextSize = spSize * context.getResources().getDisplayMetrics().scaledDensity; - float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 1.5f; + float scaledPxSize = context.getResources().getDisplayMetrics().scaledDensity * 3f; /** * choose a predefined shape to render for @@ -233,9 +233,10 @@ public class PointsWithLabelGraphSeries e } else if (value.getShape() == Shape.SMB) { mPaint.setStrokeWidth(2); Point[] points = new Point[3]; - points[0] = new Point((int)endX, (int)(endY-value.getSize())); - points[1] = new Point((int)(endX+value.getSize()), (int)(endY+value.getSize()*0.67)); - points[2] = new Point((int)(endX-value.getSize()), (int)(endY+value.getSize()*0.67)); + float size = value.getSize() * scaledPxSize; + points[0] = new Point((int)endX, (int)(endY-size)); + points[1] = 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); drawArrows(points, canvas, mPaint); } else if (value.getShape() == Shape.EXTENDEDBOLUS) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java index b99a9f0799..95e938a066 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/ProfileNS/NSProfileFragment.java @@ -7,6 +7,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; +import android.widget.Button; import android.widget.Spinner; import android.widget.TextView; @@ -16,16 +17,19 @@ import java.util.ArrayList; import butterknife.BindView; import butterknife.ButterKnife; +import butterknife.OnClick; import butterknife.OnItemSelected; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; +import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialog; import info.nightscout.androidaps.plugins.Common.SubscriberFragment; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph; import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.FabricPrivacy; +import info.nightscout.utils.OKDialog; import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED; @@ -53,6 +57,8 @@ public class NSProfileFragment extends SubscriberFragment { TextView target; @BindView(R.id.basal_graph) ProfileGraph basalGraph; + @BindView(R.id.nsprofile_profileswitch) + Button activateButton; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, @@ -79,13 +85,6 @@ public class NSProfileFragment extends SubscriberFragment { @Override protected void updateGUI() { - if (MainApp.getConfigBuilder().getProfile() == null) { - noProfile.setVisibility(View.VISIBLE); - return; - } else { - noProfile.setVisibility(View.GONE); - } - ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile(); if (profileStore != null) { ArrayList profileList = profileStore.getProfileList(); @@ -97,6 +96,9 @@ public class NSProfileFragment extends SubscriberFragment { if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName())) profileSpinner.setSelection(p); } + noProfile.setVisibility(View.GONE); + } else { + noProfile.setVisibility(View.VISIBLE); } } @@ -117,10 +119,15 @@ public class NSProfileFragment extends SubscriberFragment { target.setText(profile.getTargetList()); basalGraph.show(profile); } - if (profile.isValid("NSProfileFragment")) + if (profile.isValid("NSProfileFragment")) { invalidProfile.setVisibility(View.GONE); - else + activateButton.setVisibility(View.VISIBLE); + } else { invalidProfile.setVisibility(View.VISIBLE); + activateButton.setVisibility(View.GONE); + } + } else { + activateButton.setVisibility(View.GONE); } } @@ -135,5 +142,20 @@ public class NSProfileFragment extends SubscriberFragment { isf.setText(""); basal.setText(""); target.setText(""); + activateButton.setVisibility(View.GONE); + } + + @OnClick(R.id.nsprofile_profileswitch) + public void onClickProfileSwitch() { + String name = profileSpinner.getSelectedItem() != null ? profileSpinner.getSelectedItem().toString() : ""; + ProfileStore store = NSProfilePlugin.getPlugin().getProfile(); + if (store != null) { + Profile profile = store.getSpecificProfile(name); + if (profile != null) { + OKDialog.showConfirmation(getActivity(), MainApp.gs(R.string.activate_profile) + ": " + name + " ?", () -> + NewNSTreatmentDialog.doProfileSwitch(store, name, 0, 100, 0) + ); + } + } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index c8e5fcdbe4..525d9c638c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -109,10 +109,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf @NonNull private static final ComboPump pump = new ComboPump(); - /** This is used to determine when to pass a bolus cancel request to the scripter */ + /** + * This is used to determine when to pass a bolus cancel request to the scripter + */ private volatile boolean scripterIsBolusing; - /** This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)} - * will reset this flag. */ + /** + * This is set to true to request a bolus cancellation. {@link #deliverBolus(DetailedBolusInfo)} + * will reset this flag. + */ private volatile boolean cancelBolus; /** @@ -131,10 +135,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf */ private volatile boolean pumpHistoryChanged = false; - /** Cache of the last <=2 boluses on the pump. Used to detect changes in pump history, + /** + * Cache of the last <=2 boluses on the pump. Used to detect changes in pump history, * requiring reading pump more history. This is read/set in {@link #checkHistory()} when changed * pump history was detected and was read, as well as in {@link #deliverBolus(DetailedBolusInfo)} - * after bolus delivery. Newest record is the first one. */ + * after bolus delivery. Newest record is the first one. + */ private volatile List recentBoluses = new ArrayList<>(0); public static ComboPlugin getPlugin() { @@ -373,7 +379,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return new Date(pump.lastSuccessfulCmdTime); } - /** Runs pump initializing if needed and reads the pump state from the main screen. */ + /** + * Runs pump initializing if needed and reads the pump state from the main screen. + */ @Override public synchronized void getPumpStatus() { log.debug("getPumpStatus called"); @@ -445,7 +453,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf MainApp.bus().post(new EventComboPumpUpdateGUI()); } - /** Updates local cache with state (reservoir level, last bolus ...) returned from the pump */ + /** + * Updates local cache with state (reservoir level, last bolus ...) returned from the pump + */ private void updateLocalData(CommandResult result) { if (result.reservoirLevel != PumpState.UNKNOWN) { pump.reservoirLevel = result.reservoirLevel; @@ -556,7 +566,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // reject a bolus if one with the exact same size was successfully delivered // within the last 1-2 minutes if (Math.abs(previousBolus.amount - detailedBolusInfo.insulin) < 0.01 - && previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) { + && previousBolus.timestamp + 60 * 1000 > System.currentTimeMillis()) { log.debug("Bolu request rejected, same bolus was successfully delivered very recently"); return new PumpEnactResult().success(false).enacted(false) .comment(MainApp.gs(R.string.bolus_frequency_exceeded)); @@ -737,7 +747,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf cancelBolus = true; } - /** Note: AAPS calls this solely to enact OpenAPS suggestions + /** + * Note: AAPS calls this solely to enact OpenAPS suggestions * * @param force the force parameter isn't used currently since we always set the tbr - * there might be room for optimization to first test the currently running tbr @@ -804,12 +815,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf PumpState state = commandResult.state; if (state.tbrActive && state.tbrPercent == adjustedPercent && (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) { - TemporaryBasal tempStart = new TemporaryBasal(); - tempStart.date = state.timestamp; - tempStart.durationInMinutes = state.tbrRemainingDuration; - tempStart.percentRate = state.tbrPercent; - tempStart.isAbsolute = false; - tempStart.source = Source.USER; + TemporaryBasal tempStart = new TemporaryBasal() + .date(state.timestamp) + .duration(state.tbrRemainingDuration) + .percent(state.tbrPercent) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart); MainApp.bus().post(new EventComboPumpUpdateGUI()); @@ -825,7 +835,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return OPERATION_NOT_SUPPORTED; } - /** Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED + /** + * Cancel an active Temp Basal. Mostly sets a fake Temp Basal to avoid a TBR CANCELLED * alert. This relies on TemporaryBasal objects to properly reflect the pumps state, * which is ensured by {@link #checkAndResolveTbrMismatch(PumpState)}, which runs on each * connect. When a hard cancel is requested, the pump is queried for it's TBR state to @@ -850,10 +861,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return new PumpEnactResult().success(false).enacted(false); } if (!cancelResult.state.tbrActive) { - TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = cancelResult.state.timestamp; - tempBasal.durationInMinutes = 0; - tempBasal.source = Source.USER; + TemporaryBasal tempBasal = new TemporaryBasal() + .date(cancelResult.state.timestamp) + .duration(0) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); return new PumpEnactResult().isTempCancel(true).success(true).enacted(true); } else { @@ -995,12 +1006,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now); if (aapsTbr == null || aapsTbr.percentRate != 0) { log.debug("Creating 15m zero temp since pump is suspended"); - TemporaryBasal newTempBasal = new TemporaryBasal(); - newTempBasal.date = now; - newTempBasal.percentRate = 0; - newTempBasal.isAbsolute = false; - newTempBasal.durationInMinutes = 15; - newTempBasal.source = Source.USER; + TemporaryBasal newTempBasal = new TemporaryBasal() + .date(now) + .percent(0) + .duration(15) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); } } @@ -1047,8 +1057,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } } - /** Check pump time (on the main menu) and raise notification if time is off. - * (setting clock is not supported by ruffy) */ + /** + * Check pump time (on the main menu) and raise notification if time is off. + * (setting clock is not supported by ruffy) + */ private void checkPumpTime(PumpState state) { if (state.pumpTime == 0) { // time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field) @@ -1124,12 +1136,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("type", "new TBR on pump")); - TemporaryBasal newTempBasal = new TemporaryBasal(); - newTempBasal.date = now; - newTempBasal.percentRate = state.tbrPercent; - newTempBasal.isAbsolute = false; - newTempBasal.durationInMinutes = state.tbrRemainingDuration; - newTempBasal.source = Source.USER; + TemporaryBasal newTempBasal = new TemporaryBasal() + .date(now) + .percent(state.tbrPercent) + .duration(state.tbrRemainingDuration) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); } else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) { log.debug("Ending AAPS-TBR since pump has no TBR active"); @@ -1137,10 +1148,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("type", "TBR cancelled on pump")); - TemporaryBasal tempStop = new TemporaryBasal(); - tempStop.date = now; - tempStop.durationInMinutes = 0; - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal() + .date(now) + .duration(0) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); } else if (aapsTbr != null && state.tbrActive && (aapsTbr.percentRate != state.tbrPercent || @@ -1150,23 +1161,24 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("type", "TBR on pump differs from AAPS TBR")); - TemporaryBasal tempStop = new TemporaryBasal(); - tempStop.date = now - 1000; - tempStop.durationInMinutes = 0; - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal() + .date(now - 1000) + .duration(0) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); - TemporaryBasal newTempBasal = new TemporaryBasal(); - newTempBasal.date = now; - newTempBasal.percentRate = state.tbrPercent; - newTempBasal.isAbsolute = false; - newTempBasal.durationInMinutes = state.tbrRemainingDuration; - newTempBasal.source = Source.USER; + TemporaryBasal newTempBasal = new TemporaryBasal() + .date(now) + .percent(state.tbrPercent) + .duration(state.tbrRemainingDuration) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); } } - /**Reads the pump's history and updates the DB accordingly. */ + /** + * Reads the pump's history and updates the DB accordingly. + */ private boolean readHistory(@Nullable PumpHistoryRequest request) { CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request)); if (!historyResult.success) { @@ -1203,7 +1215,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return updated; } - /** Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same + /** + * Adds the bolus to the timestamp to be able to differentiate multiple boluses in the same * minute. Best effort, since this covers only boluses up to 6.0 U and relies on other code * to prevent a boluses with the same amount to be delivered within the same minute. * Should be good enough, even with command mode, it's a challenge to create that situation @@ -1220,7 +1233,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // ConfigBuilderPlugin.getCommandQueue().custom(new Callback() { // @Override // public void run() { - readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL)); + readHistory(new PumpHistoryRequest().tddHistory(PumpHistoryRequest.FULL)); // } // }, post); if (post != null) { @@ -1237,7 +1250,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // ConfigBuilderPlugin.getCommandQueue().custom(new Callback() { // @Override // public void run() { - readHistory(new PumpHistoryRequest().pumpErrorHistory(PumpHistoryRequest.FULL)); + readHistory(new PumpHistoryRequest().pumpErrorHistory(PumpHistoryRequest.FULL)); // } // }, post); if (post != null) { @@ -1254,14 +1267,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf // ConfigBuilderPlugin.getCommandQueue().custom(new Callback() { // @Override // public void run() { - readHistory(new PumpHistoryRequest() - .bolusHistory(PumpHistoryRequest.FULL) - .pumpErrorHistory(PumpHistoryRequest.FULL) - .tddHistory(PumpHistoryRequest.FULL)); - CommandResult readBasalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile); - if (readBasalResult.success) { - pump.basalProfile = readBasalResult.basalProfile; - } + readHistory(new PumpHistoryRequest() + .bolusHistory(PumpHistoryRequest.FULL) + .pumpErrorHistory(PumpHistoryRequest.FULL) + .tddHistory(PumpHistoryRequest.FULL)); + CommandResult readBasalResult = runCommand(MainApp.gs(R.string.combo_actvity_reading_basal_profile), 2, ruffyScripter::readBasalProfile); + if (readBasalResult.success) { + pump.basalProfile = readBasalResult.basalProfile; + } // } // }, post); if (post != null) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java index 8b923d51ff..1e7e542e5f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ruffyscripter/RuffyScripter.java @@ -10,7 +10,6 @@ import android.os.SystemClock; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import com.crashlytics.android.answers.Answers; import com.crashlytics.android.answers.CustomEvent; import com.google.common.base.Joiner; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java index 725bed1220..f47ad0d924 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaR/comm/MsgStatusTempBasal.java @@ -68,33 +68,29 @@ public class MsgStatusTempBasal extends MessageBase { if (danaRPump.isTempBasalInProgress) { if (tempBasal.percentRate != danaRPump.tempBasalPercent) { // Close current temp basal - TemporaryBasal tempStop = new TemporaryBasal(danaRPump.tempBasalStart.getTime() - 1000); - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart.getTime() - 1000).source(Source.USER); treatmentsInterface.addToHistoryTempBasal(tempStop); // Create new - TemporaryBasal newTempBasal = new TemporaryBasal(); - newTempBasal.date = danaRPump.tempBasalStart.getTime(); - newTempBasal.percentRate = danaRPump.tempBasalPercent; - newTempBasal.isAbsolute = false; - newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; - newTempBasal.source = Source.USER; + TemporaryBasal newTempBasal = new TemporaryBasal() + .date(danaRPump.tempBasalStart.getTime()) + .percent(danaRPump.tempBasalPercent) + .duration(danaRPump.tempBasalTotalSec / 60) + .source(Source.USER); treatmentsInterface.addToHistoryTempBasal(newTempBasal); } } else { // Close current temp basal - TemporaryBasal tempStop = new TemporaryBasal(now); - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal().date(now).source(Source.USER); treatmentsInterface.addToHistoryTempBasal(tempStop); } } else { if (danaRPump.isTempBasalInProgress) { // Create new - TemporaryBasal newTempBasal = new TemporaryBasal(); - newTempBasal.date = danaRPump.tempBasalStart.getTime(); - newTempBasal.percentRate = danaRPump.tempBasalPercent; - newTempBasal.isAbsolute = false; - newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; - newTempBasal.source = Source.USER; + TemporaryBasal newTempBasal = new TemporaryBasal() + .date(danaRPump.tempBasalStart.getTime()) + .percent(danaRPump.tempBasalPercent) + .duration(danaRPump.tempBasalTotalSec / 60) + .source(Source.USER); treatmentsInterface.addToHistoryTempBasal(newTempBasal); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java index c11b75764c..91d4abb1fe 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRS/comm/DanaRS_Packet_APS_History_Events.java @@ -85,10 +85,7 @@ public class DanaRS_Packet_APS_History_Events extends DanaRS_Packet { int param1 = ((intFromBuff(data, 7, 1) << 8) & 0xFF00) + (intFromBuff(data, 8, 1) & 0xFF); int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF); - TemporaryBasal temporaryBasal = new TemporaryBasal(); - temporaryBasal.date = datetime.getTime(); - temporaryBasal.source = Source.PUMP; - temporaryBasal.pumpId = datetime.getTime(); + TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime.getTime()).source(Source.PUMP).pumpId(datetime.getTime()); ExtendedBolus extendedBolus = new ExtendedBolus(); extendedBolus.date = datetime.getTime(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java index 922047e5cb..7663bd9f9e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpDanaRv2/comm/MsgHistoryEvents_v2.java @@ -56,10 +56,10 @@ public class MsgHistoryEvents_v2 extends MessageBase { int param1 = intFromBuff(bytes, 7, 2); int param2 = intFromBuff(bytes, 9, 2); - TemporaryBasal temporaryBasal = new TemporaryBasal(); - temporaryBasal.date = datetime.getTime(); - temporaryBasal.source = Source.PUMP; - temporaryBasal.pumpId = datetime.getTime(); + TemporaryBasal temporaryBasal = new TemporaryBasal() + .date(datetime.getTime()) + .source(Source.PUMP) + .pumpId(datetime.getTime()); ExtendedBolus extendedBolus = new ExtendedBolus(); extendedBolus.date = datetime.getTime(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java index 2506e5321d..77994a5047 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/InsightPlugin.java @@ -592,12 +592,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte if (pumpEnactResult.success) { // create log entry - final TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = System.currentTimeMillis(); - tempBasal.isAbsolute = false; - tempBasal.percentRate = percent_amount; - tempBasal.durationInMinutes = durationInMinutes; - tempBasal.source = Source.USER; + final TemporaryBasal tempBasal = new TemporaryBasal() + .date(System.currentTimeMillis()) + .percent(percent_amount) + .duration(durationInMinutes) + .source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); } @@ -643,12 +642,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte if (pumpEnactResult.success) { // create log entry - final TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = System.currentTimeMillis(); - tempBasal.isAbsolute = false; - tempBasal.percentRate = percent; - tempBasal.durationInMinutes = durationInMinutes; - tempBasal.source = Source.USER; // TODO check this is correct + final TemporaryBasal tempBasal = new TemporaryBasal() + .date(System.currentTimeMillis()) + .percent(percent) + .duration(durationInMinutes) + .source(Source.USER); // TODO check this is correct MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); } @@ -683,13 +681,10 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte } // TODO isn't conditional on one apparently being in progress only the history change - boolean enacted = false; final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME); if (MainApp.getConfigBuilder().isTempBasalInProgress()) { - enacted = true; - TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); } lastDataTime = new Date(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java index 588074b0c4..6fc0152eb8 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpInsight/history/HistoryLogAdapter.java @@ -10,9 +10,8 @@ import info.nightscout.androidaps.db.TemporaryBasal; /** * Created by jamorham on 27/01/2018. - * + *

* Write to the History Log - * */ class HistoryLogAdapter { @@ -25,7 +24,7 @@ class HistoryLogAdapter { void createTBRrecord(Date eventDate, int percent, int duration, long record_id) { - TemporaryBasal temporaryBasal = new TemporaryBasal(eventDate.getTime()); + TemporaryBasal temporaryBasal = new TemporaryBasal().date(eventDate.getTime()); final TemporaryBasal temporaryBasalFromHistory = MainApp.getConfigBuilder().getTempBasalFromHistory(eventDate.getTime()); @@ -50,10 +49,10 @@ class HistoryLogAdapter { } } - temporaryBasal.source = Source.PUMP; - temporaryBasal.pumpId = record_id; - temporaryBasal.percentRate = percent; - temporaryBasal.durationInMinutes = duration; + temporaryBasal.source(Source.PUMP) + .pumpId(record_id) + .percent(percent) + .duration(duration); MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java index 00ff2fc7a4..dbf0a21235 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpVirtual/VirtualPumpPlugin.java @@ -98,7 +98,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { pumpDescription.basalStep = 0.01d; pumpDescription.basalMinimumRate = 0.01d; - pumpDescription.isRefillingCapable = false; + pumpDescription.isRefillingCapable = true; pumpDescription.storesCarbInfo = false; pumpDescription.is30minBasalRatesCapable = true; @@ -291,12 +291,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); - TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = System.currentTimeMillis(); - tempBasal.isAbsolute = true; - tempBasal.absoluteRate = absoluteRate; - tempBasal.durationInMinutes = durationInMinutes; - tempBasal.source = Source.USER; + TemporaryBasal tempBasal = new TemporaryBasal() + .date(System.currentTimeMillis()) + .absolute(absoluteRate) + .duration(durationInMinutes) + .source(Source.USER); PumpEnactResult result = new PumpEnactResult(); result.success = true; result.enacted = true; @@ -321,12 +320,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { if (!result.success) return result; } - TemporaryBasal tempBasal = new TemporaryBasal(); - tempBasal.date = System.currentTimeMillis(); - tempBasal.isAbsolute = false; - tempBasal.percentRate = percent; - tempBasal.durationInMinutes = durationInMinutes; - tempBasal.source = Source.USER; + TemporaryBasal tempBasal = new TemporaryBasal() + .date(System.currentTimeMillis()) + .percent(percent) + .duration(durationInMinutes) + .source(Source.USER); result.success = true; result.enacted = true; result.percent = percent; @@ -376,8 +374,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface { result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); if (treatmentsInterface.isTempBasalInProgress()) { result.enacted = true; - TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); - tempStop.source = Source.USER; + TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER); treatmentsInterface.addToHistoryTempBasal(tempStop); //tempBasal = null; if (Config.logPumpComm) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java index 8254293c4d..829ded4c46 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/TreatmentsPlugin.java @@ -57,7 +57,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { private IobTotal lastTreatmentCalculation; private IobTotal lastTempBasalsCalculation; - public static List treatments; + private final static ArrayList treatments = new ArrayList<>(); private final static Intervals tempBasals = new NonOverlappingIntervals<>(); private final static Intervals extendedBoluses = new NonOverlappingIntervals<>(); private final static Intervals tempTargets = new OverlappingIntervals<>(); @@ -146,8 +146,10 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) dia = MainApp.getConfigBuilder().getProfile().getDia(); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); - - treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false); + synchronized (treatments) { + treatments.clear(); + treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false)); + } } private static void initializeTempBasalData() { @@ -202,22 +204,24 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { double dia = profile.getDia(); - for (Integer pos = 0; pos < treatments.size(); pos++) { - Treatment t = treatments.get(pos); - if (!t.isValid) continue; - if (t.date > time) continue; - Iob tIOB = t.iobCalc(time, dia); - total.iob += tIOB.iobContrib; - total.activity += tIOB.activityContrib; - if (t.date > total.lastBolusTime) - total.lastBolusTime = t.date; - if (!t.isSMB) { - // instead of dividing the DIA that only worked on the bilinear curves, - // multiply the time the treatment is seen active. - long timeSinceTreatment = time - t.date; - long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0)); - Iob bIOB = t.iobCalc(snoozeTime, dia); - total.bolussnooze += bIOB.iobContrib; + synchronized (treatments) { + for (Integer pos = 0; pos < treatments.size(); pos++) { + Treatment t = treatments.get(pos); + if (!t.isValid) continue; + if (t.date > time) continue; + Iob tIOB = t.iobCalc(time, dia); + total.iob += tIOB.iobContrib; + total.activity += tIOB.activityContrib; + if (t.date > total.lastBolusTime) + total.lastBolusTime = t.date; + if (!t.isSMB) { + // instead of dividing the DIA that only worked on the bilinear curves, + // multiply the time the treatment is seen active. + long timeSinceTreatment = time - t.date; + long snoozeTime = t.date + (long) (timeSinceTreatment * SP.getDouble("openapsama_bolussnooze_dia_divisor", 2.0)); + Iob bIOB = t.iobCalc(snoozeTime, dia); + total.bolussnooze += bIOB.iobContrib; + } } } @@ -248,17 +252,19 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { long now = System.currentTimeMillis(); long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue(); - for (Treatment treatment : treatments) { - if (!treatment.isValid) - continue; - long t = treatment.date; - 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; + synchronized (treatments) { + for (Treatment treatment : treatments) { + if (!treatment.isValid) + continue; + long t = treatment.date; + 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; + } } } } @@ -275,29 +281,35 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public List getTreatmentsFromHistory() { - return treatments; + synchronized (treatments) { + return (List) treatments.clone(); + } } @Override public List getTreatments5MinBackFromHistory(long time) { List in5minback = new ArrayList<>(); - for (Integer pos = 0; pos < treatments.size(); pos++) { - Treatment t = treatments.get(pos); - if (!t.isValid) - continue; - if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0) - in5minback.add(t); + synchronized (treatments) { + for (Integer pos = 0; pos < treatments.size(); pos++) { + Treatment t = treatments.get(pos); + if (!t.isValid) + continue; + if (t.date <= time && t.date > time - 5 * 60 * 1000 && t.carbs > 0) + in5minback.add(t); + } + return in5minback; } - return in5minback; } @Override public long getLastBolusTime() { long now = System.currentTimeMillis(); long last = 0; - for (Treatment t : treatments) { - if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now) - last = t.date; + synchronized (treatments) { + for (Treatment t : treatments) { + if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now) + last = t.date; + } } log.debug("Last bolus time: " + new Date(last).toLocaleString()); return last; @@ -425,14 +437,14 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public Intervals getExtendedBolusesFromHistory() { synchronized (extendedBoluses) { - return extendedBoluses; + return new NonOverlappingIntervals<>(extendedBoluses); } } @Override public Intervals getTemporaryBasalsFromHistory() { synchronized (tempBasals) { - return tempBasals; + return new NonOverlappingIntervals<>(tempBasals); } } @@ -514,7 +526,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public Intervals getTempTargetsFromHistory() { synchronized (tempTargets) { - return tempTargets; + return new OverlappingIntervals<>(tempTargets); } } @@ -534,7 +546,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface { @Override public ProfileIntervals getProfileSwitchesFromHistory() { synchronized (profiles) { - return profiles; + return new ProfileIntervals<>(profiles); } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java index 61f4877ccc..99019e5fd7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/ProfileGraph.java @@ -11,6 +11,7 @@ import java.util.ArrayList; import java.util.List; import info.nightscout.androidaps.data.Profile; +import info.nightscout.utils.Round; /** * Created by Adrian on 15.04.2018. @@ -48,7 +49,7 @@ public class ProfileGraph extends GraphView { getViewport().setYAxisBoundsManual(true); getViewport().setMinY(0); - getViewport().setMaxY(profile.getMaxDailyBasal()*1.1); + getViewport().setMaxY(Round.ceilTo(profile.getMaxDailyBasal()*1.1, 0.5)); getGridLabelRenderer().setNumHorizontalLabels(13); getGridLabelRenderer().setVerticalLabelsColor(basalSeries.getColor()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java index baf1e43d55..6831ee33f9 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsBolusFragment.java @@ -76,7 +76,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. return; Treatment t = treatments.get(position); holder.date.setText(DateUtil.dateAndTimeString(t.date)); - holder.insulin.setText(DecimalFormatter.to2Decimal(t.insulin) + " U"); + holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(t.insulin) + " U"); holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g"); Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U"); @@ -176,7 +176,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. llm = new LinearLayoutManager(view.getContext()); recyclerView.setLayoutManager(llm); - RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.treatments); + RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()); recyclerView.setAdapter(adapter); iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal); @@ -232,7 +232,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View. activity.runOnUiThread(new Runnable() { @Override public void run() { - recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.treatments), false); + recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false); if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) { iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U"); activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java index 1cb6d04614..2bf7684c94 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsExtendedBolusesFragment.java @@ -80,7 +80,7 @@ public class TreatmentsExtendedBolusesFragment extends SubscriberFragment { holder.date.setText(DateUtil.dateAndTimeString(extendedBolus.date) + " - " + DateUtil.timeString(extendedBolus.end())); } holder.duration.setText(DecimalFormatter.to0Decimal(extendedBolus.durationInMinutes) + " min"); - holder.insulin.setText(DecimalFormatter.to2Decimal(extendedBolus.insulin) + " U"); + holder.insulin.setText(DecimalFormatter.toPumpSupportedBolus(extendedBolus.insulin) + " U"); holder.realDuration.setText(DecimalFormatter.to0Decimal(extendedBolus.getRealDuration()) + " min"); IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis()); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java index 8f838ee45a..9fb895c1c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Treatments/fragments/TreatmentsTemporaryBasalsFragment.java @@ -100,7 +100,11 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment { holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%"); } holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration()) + " min"); - IobTotal iob = tempBasal.iobCalc(System.currentTimeMillis()); + IobTotal iob = new IobTotal(System.currentTimeMillis()); + try { // in case app loaded and still no profile selected + iob = tempBasal.iobCalc(System.currentTimeMillis()); + } catch (Exception e) { + } holder.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob) + " U"); holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U"); holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h"); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java index 190df0a692..dcac1cec0f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/Wear/ActionStringHandler.java @@ -309,8 +309,8 @@ public class ActionStringHandler { } else { sendStatusmessage("TDD", generateTDDMessage(historyList, dummies)); } - } - }); + } + }); } } else { // if up to date: prepare, send (check if CPP is activated -> add CPP stats) @@ -604,17 +604,15 @@ public class ActionStringHandler { } private static void generateTempTarget(int duration, double low, double high) { - TempTarget tempTarget = new TempTarget(); - tempTarget.date = System.currentTimeMillis(); - tempTarget.durationInMinutes = duration; - tempTarget.reason = "WearPlugin"; - tempTarget.source = Source.USER; + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(duration) + .reason("WearPlugin") + .source(Source.USER); if (tempTarget.durationInMinutes != 0) { - tempTarget.low = low; - tempTarget.high = high; + tempTarget.low(low).high(high); } else { - tempTarget.low = 0; - tempTarget.high = 0; + tempTarget.low(0).high(0); } MainApp.getDbHelper().createOrUpdate(tempTarget); diff --git a/app/src/main/java/info/nightscout/utils/DateUtil.java b/app/src/main/java/info/nightscout/utils/DateUtil.java index 102720ef1b..8ec2310036 100644 --- a/app/src/main/java/info/nightscout/utils/DateUtil.java +++ b/app/src/main/java/info/nightscout/utils/DateUtil.java @@ -159,5 +159,8 @@ public class DateUtil { return timeFrameString(timestamp - System.currentTimeMillis()); } + public static long now() { + return System.currentTimeMillis(); + } } diff --git a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java index 1a70b43c30..d821f5ba37 100644 --- a/app/src/main/java/info/nightscout/utils/DecimalFormatter.java +++ b/app/src/main/java/info/nightscout/utils/DecimalFormatter.java @@ -2,6 +2,8 @@ package info.nightscout.utils; import java.text.DecimalFormat; +import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; + /** * Created by mike on 11.07.2016. */ @@ -26,4 +28,16 @@ public class DecimalFormatter { public static String to3Decimal(double value) { return format3dec.format(value); } + + public static String toPumpSupportedBolus(double value) { + return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01 + ? to2Decimal(value) + : to1Decimal(value); + } + + public static DecimalFormat pumpSupportedBolusFormat() { + return ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep <= 0.01 + ? new DecimalFormat("0.00") + : new DecimalFormat("0.0"); + } } diff --git a/app/src/main/java/info/nightscout/utils/NSUpload.java b/app/src/main/java/info/nightscout/utils/NSUpload.java index a75377aae1..96d24af4d4 100644 --- a/app/src/main/java/info/nightscout/utils/NSUpload.java +++ b/app/src/main/java/info/nightscout/utils/NSUpload.java @@ -140,7 +140,7 @@ public class NSUpload { data.put("splitNow", 0); data.put("splitExt", 100); data.put("enteredinsulin", extendedBolus.insulin); - data.put("relative", extendedBolus.insulin); + data.put("relative", extendedBolus.insulin / extendedBolus.durationInMinutes * 60); // U/h if (extendedBolus.pumpId != 0) data.put("pumpId", extendedBolus.pumpId); data.put("created_at", DateUtil.toISOString(extendedBolus.date)); @@ -475,6 +475,27 @@ public class NSUpload { } } + public static void uploadEvent(String careportalEvent, long time) { + Context context = MainApp.instance().getApplicationContext(); + Bundle bundle = new Bundle(); + bundle.putString("action", "dbAdd"); + bundle.putString("collection", "treatments"); + JSONObject data = new JSONObject(); + try { + data.put("eventType", careportalEvent); + data.put("created_at", DateUtil.toISOString(time)); + data.put("enteredBy", SP.getString("careportal_enteredby", MainApp.gs(R.string.app_name))); + } catch (JSONException e) { + log.error("Unhandled exception", e); + } + bundle.putString("data", data.toString()); + Intent intent = new Intent(Intents.ACTION_DATABASE); + intent.putExtras(bundle); + intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); + context.sendBroadcast(intent); + DbLogger.dbAdd(intent, data.toString()); + } + public static void removeFoodFromNS(String _id) { try { Context context = MainApp.instance().getApplicationContext(); diff --git a/app/src/main/java/info/nightscout/utils/OKDialog.java b/app/src/main/java/info/nightscout/utils/OKDialog.java index 6bd84cbe71..3212e6b1fd 100644 --- a/app/src/main/java/info/nightscout/utils/OKDialog.java +++ b/app/src/main/java/info/nightscout/utils/OKDialog.java @@ -61,4 +61,19 @@ public class OKDialog { log.debug("show_dialog exception: " + e); } } + + public static void showConfirmation(final Activity activity, String message, final Runnable runnable) { + AlertDialog alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme)) + .setMessage(message) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + dialog.dismiss(); + if (runnable != null) { + SystemClock.sleep(100); + activity.runOnUiThread(runnable); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + } diff --git a/app/src/main/java/info/nightscout/utils/T.java b/app/src/main/java/info/nightscout/utils/T.java new file mode 100644 index 0000000000..ce8541dd8c --- /dev/null +++ b/app/src/main/java/info/nightscout/utils/T.java @@ -0,0 +1,59 @@ +package info.nightscout.utils; + +/** + * Created by mike on 26.03.2018. + */ + +public class T { + private long time; // in msec + + public static T msecs(long msec) { + T t = new T(); + t.time = msec; + return t; + } + + public static T secs(long sec) { + T t = new T(); + t.time = sec * 1000L; + return t; + } + + public static T mins(long min) { + T t = new T(); + t.time = min * 60 * 1000L; + return t; + } + + public static T hours(long hour) { + T t = new T(); + t.time = hour * 60 * 60 * 1000L; + return t; + } + + public static T days(long day) { + T t = new T(); + t.time = day * 24 * 60 * 60 * 1000L; + return t; + } + + public long msecs() { + return time; + } + + public long secs() { + return time / 1000L; + } + + public long mins() { + return time / 60 / 1000L; + } + + public long hours() { + return time / 60 / 60 / 1000L; + } + + public long days() { + return time / 24 / 60 / 60 / 1000L; + } +} diff --git a/app/src/main/res/layout/actions_fill_dialog.xml b/app/src/main/res/layout/actions_fill_dialog.xml index 55e44f4bc7..18a5886246 100644 --- a/app/src/main/res/layout/actions_fill_dialog.xml +++ b/app/src/main/res/layout/actions_fill_dialog.xml @@ -1,110 +1,97 @@ - + - - - + android:orientation="vertical" + android:focusableInTouchMode="true" + android:padding="10dp"> - + - + - + - + -