fix conflict

This commit is contained in:
Milos Kozak 2018-03-28 10:25:58 +02:00
commit fc2da20743
74 changed files with 1788 additions and 666 deletions

View file

@ -24,6 +24,7 @@ ext {
repositories { repositories {
maven { url 'https://maven.fabric.io/public' } maven { url 'https://maven.fabric.io/public' }
jcenter { url "https://jcenter.bintray.com/" }
} }
def generateGitBuild = { -> def generateGitBuild = { ->
@ -62,7 +63,7 @@ android {
targetSdkVersion 23 targetSdkVersion 23
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "1.60a-dev" version "1.60b-dev"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", generateGitBuild() buildConfigField "String", "BUILDVERSION", generateGitBuild()
@ -210,6 +211,7 @@ dependencies {
compile "com.google.guava:guava:20.0" compile "com.google.guava:guava:20.0"
compile "net.danlew:android.joda:2.9.9.1" 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' compile 'org.mozilla:rhino:1.7.7.2'

View file

@ -24,7 +24,7 @@ public class Config {
public static final boolean SMSCOMMUNICATORENABLED = !BuildConfig.NSCLIENTOLNY && !BuildConfig.G5UPLOADER; 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 detailedLog = true;
public static final boolean logFunctionCalls = true; public static final boolean logFunctionCalls = true;

View file

@ -31,7 +31,6 @@ import info.nightscout.androidaps.interfaces.InsulinInterface;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.Actions.ActionsFragment; import info.nightscout.androidaps.plugins.Actions.ActionsFragment;
import info.nightscout.androidaps.plugins.Careportal.CareportalPlugin; 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.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin; import info.nightscout.androidaps.plugins.ConstraintsSafety.SafetyPlugin;
@ -188,7 +187,7 @@ public class MainApp extends Application {
pluginsList.add(new PersistentNotificationPlugin(this)); pluginsList.add(new PersistentNotificationPlugin(this));
pluginsList.add(NSClientPlugin.getPlugin()); pluginsList.add(NSClientPlugin.getPlugin());
pluginsList.add(sConfigBuilder = ConfigBuilderFragment.getPlugin()); pluginsList.add(sConfigBuilder = ConfigBuilderPlugin.getPlugin());
MainApp.getConfigBuilder().initialize(); MainApp.getConfigBuilder().initialize();
} }
@ -389,6 +388,8 @@ public class MainApp extends Application {
} }
public static boolean isEngineeringModeOrRelease() { public static boolean isEngineeringModeOrRelease() {
if (!BuildConfig.APS)
return true;
return engineeringMode || !devBranch; return engineeringMode || !devBranch;
} }

View file

@ -64,31 +64,31 @@ public class DataService extends IntentService {
if (Config.logFunctionCalls) if (Config.logFunctionCalls)
log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras())); log.debug("onHandleIntent " + BundleLogger.log(intent.getExtras()));
if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) { if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceXdripPlugin.class)) {
xDripEnabled = true; xDripEnabled = true;
nsClientEnabled = false; nsClientEnabled = false;
mm640gEnabled = false; mm640gEnabled = false;
glimpEnabled = false; glimpEnabled = false;
dexcomG5Enabled = false; dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) { } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceNSClientPlugin.class)) {
xDripEnabled = false; xDripEnabled = false;
nsClientEnabled = true; nsClientEnabled = true;
mm640gEnabled = false; mm640gEnabled = false;
glimpEnabled = false; glimpEnabled = false;
dexcomG5Enabled = false; dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) { } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceMM640gPlugin.class)) {
xDripEnabled = false; xDripEnabled = false;
nsClientEnabled = false; nsClientEnabled = false;
mm640gEnabled = true; mm640gEnabled = true;
glimpEnabled = false; glimpEnabled = false;
dexcomG5Enabled = false; dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) { } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceGlimpPlugin.class)) {
xDripEnabled = false; xDripEnabled = false;
nsClientEnabled = false; nsClientEnabled = false;
mm640gEnabled = false; mm640gEnabled = false;
glimpEnabled = true; glimpEnabled = true;
dexcomG5Enabled = false; dexcomG5Enabled = false;
} else if (ConfigBuilderPlugin.getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) { } else if (ConfigBuilderPlugin.getPlugin().getActiveBgSource().getClass().equals(SourceDexcomG5Plugin.class)) {
xDripEnabled = false; xDripEnabled = false;
nsClientEnabled = false; nsClientEnabled = false;
mm640gEnabled = false; mm640gEnabled = false;

View file

@ -4,9 +4,11 @@ import java.util.ArrayList;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
/** /**
* Created by mike on 19.03.2018. * Created by mike on 19.03.2018.
@ -41,6 +43,10 @@ public class ConstraintChecker implements ConstraintsInterface {
return isSMBModeEnabled(new Constraint<>(true)); return isSMBModeEnabled(new Constraint<>(true));
} }
public Constraint<Boolean> isAdvancedFilteringEnabled() {
return isAdvancedFilteringEnabled(new Constraint<>(true));
}
public Constraint<Double> getMaxBasalAllowed(Profile profile) { public Constraint<Double> getMaxBasalAllowed(Profile profile) {
return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile); return applyBasalConstraints(new Constraint<>(Constants.REALLYHIGHBASALRATE), profile);
} }
@ -121,6 +127,17 @@ public class ConstraintChecker implements ConstraintsInterface {
return value; return value;
} }
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
ArrayList<PluginBase> 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 @Override
public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) { public Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); ArrayList<PluginBase> constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class);

View file

@ -2,6 +2,8 @@ package info.nightscout.androidaps.data;
import android.content.Context; import android.content.Context;
import com.rits.cloning.Cloner;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.Date; 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 long deliverAt = 0; // SMB should be delivered within 1 min from this time
public DetailedBolusInfo copy() { public DetailedBolusInfo copy() {
DetailedBolusInfo copy = new DetailedBolusInfo(); DetailedBolusInfo n = new DetailedBolusInfo();
copy.date = this.date; n.date = date;
copy.eventType = this.eventType; n.eventType = eventType;
copy.insulin = this.insulin; n.insulin = insulin;
copy.carbs = this.carbs; n.carbs = carbs;
copy.source = this.source; n.source = source;
copy.isValid = this.isValid; n.isValid = isValid;
copy.glucose = this.glucose; n.glucose = glucose;
copy.glucoseType = this.glucoseType; n.glucoseType = glucoseType;
copy.carbTime = this.carbTime; n.carbTime = carbTime;
copy.boluscalc = this.boluscalc; n.boluscalc = boluscalc;
copy.context = this.context; n.context = context;
copy.pumpId = this.pumpId; n.pumpId = pumpId;
copy.isSMB = this.isSMB; n.isSMB = isSMB;
return copy; n.deliverAt = deliverAt;
return n;
} }
@Override @Override

View file

@ -21,6 +21,7 @@ import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.BgReading;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.Round; import info.nightscout.utils.Round;
@ -40,17 +41,10 @@ public class GlucoseStatus {
@Override @Override
public String toString() { public String toString() {
return MainApp.sResources.getString(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" + return MainApp.gs(R.string.glucose) + " " + DecimalFormatter.to0Decimal(glucose) + " mg/dl\n" +
MainApp.sResources.getString(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" + MainApp.gs(R.string.delta) + " " + DecimalFormatter.to0Decimal(delta) + " mg/dl\n" +
MainApp.sResources.getString(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" + MainApp.gs(R.string.short_avgdelta) + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl\n" +
MainApp.sResources.getString(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"; MainApp.gs(R.string.long_avgdelta) + " " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
}
public Spanned toSpanned() {
return Html.fromHtml("<b>" + MainApp.sResources.getString(R.string.glucose) + "</b>: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.delta) + "</b>: " + DecimalFormatter.to0Decimal(delta) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.short_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl<br>" +
"<b>" + MainApp.sResources.getString(R.string.long_avgdelta) + "</b>: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl");
} }
public GlucoseStatus() { public GlucoseStatus() {
@ -75,11 +69,15 @@ public class GlucoseStatus {
@Nullable @Nullable
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) { public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
// load 45min // load 45min
long fromtime = (long) (System.currentTimeMillis() - 60 * 1000L * 45); long fromtime = DateUtil.now() - 60 * 1000L * 45;
List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
int sizeRecords = data.size(); 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; return null;
} }
@ -87,13 +85,14 @@ public class GlucoseStatus {
long now_date = now.date; long now_date = now.date;
double change; double change;
if (sizeRecords < 2) { if (sizeRecords == 1) {
GlucoseStatus status = new GlucoseStatus(); GlucoseStatus status = new GlucoseStatus();
status.glucose = now.value; status.glucose = now.value;
status.short_avgdelta = 0d; status.short_avgdelta = 0d;
status.delta = 0d; status.delta = 0d;
status.long_avgdelta = 0d; status.long_avgdelta = 0d;
status.avgdelta = 0d; // for OpenAPS MA status.avgdelta = 0d; // for OpenAPS MA
status.date = now_date;
return status.round(); return status.round();
} }

View file

@ -16,7 +16,11 @@ import info.nightscout.androidaps.interfaces.Interval;
public abstract class Intervals<T extends Interval> { public abstract class Intervals<T extends Interval> {
LongSparseArray<T> rawData = new LongSparseArray<T>(); // oldest at index 0 LongSparseArray<T> rawData; // oldest at index 0
public Intervals() {
rawData = new LongSparseArray<T>();
}
public synchronized Intervals reset() { public synchronized Intervals reset() {
rawData = new LongSparseArray<T>(); rawData = new LongSparseArray<T>();
@ -27,8 +31,7 @@ public abstract class Intervals<T extends Interval> {
/** /**
* The List must be sorted by `T.start()` in ascending order * The List must be sorted by `T.start()` in ascending order
* */
* */
public synchronized void add(List<T> list) { public synchronized void add(List<T> list) {
for (T interval : list) { for (T interval : list) {
rawData.put(interval.start(), interval); rawData.put(interval.start(), interval);
@ -36,6 +39,10 @@ public abstract class Intervals<T extends Interval> {
merge(); merge();
} }
public synchronized void add(T interval) {
rawData.put(interval.start(), interval);
merge();
}
public synchronized List<T> getList() { public synchronized List<T> getList() {
@ -86,5 +93,4 @@ public abstract class Intervals<T extends Interval> {
} }
} }

View file

@ -7,6 +7,16 @@ public class Iob {
public double iobContrib = 0d; public double iobContrib = 0d;
public double activityContrib = 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) { public Iob plus(Iob iob) {
iobContrib += iob.iobContrib; iobContrib += iob.iobContrib;
activityContrib += iob.activityContrib; activityContrib += iob.activityContrib;

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.data; package info.nightscout.androidaps.data;
import com.rits.cloning.Cloner;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -35,20 +37,9 @@ public class IobTotal {
long time; long time;
public IobTotal clone() { public IobTotal copy() {
IobTotal copy = new IobTotal(time); Cloner cloner = new Cloner();
copy.iob = iob; return cloner.deepClone(this);
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(long time) { public IobTotal(long time) {
@ -82,6 +73,8 @@ public class IobTotal {
result.basaliob = bolusIOB.basaliob + basalIob.basaliob; result.basaliob = bolusIOB.basaliob + basalIob.basaliob;
result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin; result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin;
result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin; result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin;
result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin;
result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin;
result.lastBolusTime = bolusIOB.lastBolusTime; result.lastBolusTime = bolusIOB.lastBolusTime;
result.lastTempDate = basalIob.lastTempDate; result.lastTempDate = basalIob.lastTempDate;
result.lastTempRate = basalIob.lastTempRate; result.lastTempRate = basalIob.lastTempRate;
@ -97,6 +90,8 @@ public class IobTotal {
this.basaliob = Round.roundTo(this.basaliob, 0.001); this.basaliob = Round.roundTo(this.basaliob, 0.001);
this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001); this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001);
this.hightempinsulin = Round.roundTo(this.hightempinsulin, 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; return this;
} }

View file

@ -2,7 +2,9 @@ package info.nightscout.androidaps.data;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v4.util.LongSparseArray;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.interfaces.Interval; import info.nightscout.androidaps.interfaces.Interval;
/** /**
@ -11,6 +13,14 @@ import info.nightscout.androidaps.interfaces.Interval;
public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> { public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
public NonOverlappingIntervals() {
super();
}
public NonOverlappingIntervals (Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() { protected synchronized void merge() {
for (int index = 0; index < rawData.size() - 1; index++) { for (int index = 0; index < rawData.size() - 1; index++) {
Interval i = rawData.valueAt(index); Interval i = rawData.valueAt(index);
@ -27,4 +37,5 @@ public class NonOverlappingIntervals<T extends Interval> extends Intervals<T> {
if (index >= 0) return rawData.valueAt(index); if (index >= 0) return rawData.valueAt(index);
return null; return null;
} }
} }

View file

@ -11,6 +11,14 @@ import info.nightscout.androidaps.interfaces.Interval;
public class OverlappingIntervals<T extends Interval> extends Intervals<T> { public class OverlappingIntervals<T extends Interval> extends Intervals<T> {
public OverlappingIntervals() {
super();
}
public OverlappingIntervals(Intervals<T> other) {
rawData = other.rawData.clone();
}
protected synchronized void merge() { protected synchronized void merge() {
boolean needToCut = false; boolean needToCut = false;
long cutTime = 0; long cutTime = 0;

View file

@ -22,7 +22,15 @@ import info.nightscout.utils.DateUtil;
public class ProfileIntervals<T extends Interval> { public class ProfileIntervals<T extends Interval> {
private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class); private static Logger log = LoggerFactory.getLogger(ProfileIntervals.class);
private LongSparseArray<T> rawData = new LongSparseArray<>(); // oldest at index 0 private LongSparseArray<T> rawData; // oldest at index 0
public ProfileIntervals () {
rawData = new LongSparseArray<>();
}
public ProfileIntervals (ProfileIntervals<T> other) {
rawData = other.rawData.clone();
}
public synchronized ProfileIntervals reset() { public synchronized ProfileIntervals reset() {
rawData = new LongSparseArray<>(); rawData = new LongSparseArray<>();
@ -30,9 +38,11 @@ public class ProfileIntervals<T extends Interval> {
} }
public synchronized void add(T newInterval) { public synchronized void add(T newInterval) {
if (newInterval.isValid()) {
rawData.put(newInterval.start(), newInterval); rawData.put(newInterval.start(), newInterval);
merge(); merge();
} }
}
public synchronized void add(List<T> list) { public synchronized void add(List<T> list) {
for (T interval : list) { for (T interval : list) {
@ -56,10 +66,12 @@ public class ProfileIntervals<T extends Interval> {
public synchronized Interval getValueToTime(long time) { public synchronized Interval getValueToTime(long time) {
int index = binarySearch(time); int index = binarySearch(time);
if (index >= 0) return rawData.valueAt(index); if (index >= 0) return rawData.valueAt(index);
// if we request data older than first record, use oldest instead // if we request data older than first record, use oldest with zero duration instead
if (rawData.size() > 0) { for (index = 0; index < rawData.size(); index++) {
log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); if (rawData.valueAt(index).durationInMsec() == 0) {
return rawData.valueAt(0); //log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString());
return rawData.valueAt(index);
}
} }
return null; return null;
} }
@ -117,4 +129,9 @@ public class ProfileIntervals<T extends Interval> {
public synchronized T getReversed(int index) { public synchronized T getReversed(int index) {
return rawData.valueAt(size() - 1 - index); return rawData.valueAt(size() - 1 - index);
} }
@Override
public String toString() {
return rawData.toString();
}
} }

View file

@ -58,7 +58,7 @@ import info.nightscout.utils.PercentageSplitter;
/** /**
* This Helper contains all resource to provide a central DB management functionality. Only methods handling * 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). * data-structure (and not the DB content) should be contained in here (meaning DDL and not SQL).
* * <p>
* This class can safely be called from Services, but should not call Services to avoid circular dependencies. * 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 * 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. * 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) { public void createTemptargetFromJsonIfNotExists(JSONObject trJson) {
try { try {
String units = MainApp.getConfigBuilder().getProfileUnits(); String units = MainApp.getConfigBuilder().getProfileUnits();
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = trJson.getLong("mills"); .date(trJson.getLong("mills"))
tempTarget.durationInMinutes = trJson.getInt("duration"); .duration(trJson.getInt("duration"))
tempTarget.low = Profile.toMgdl(trJson.getDouble("targetBottom"), units); .low(Profile.toMgdl(trJson.getDouble("targetBottom"), units))
tempTarget.high = Profile.toMgdl(trJson.getDouble("targetTop"), units); .high(Profile.toMgdl(trJson.getDouble("targetTop"), units))
tempTarget.reason = trJson.getString("reason"); .reason(trJson.getString("reason"))
tempTarget._id = trJson.getString("_id"); ._id(trJson.getString("_id"))
tempTarget.source = Source.NIGHTSCOUT; .source(Source.NIGHTSCOUT);
createOrUpdate(tempTarget); createOrUpdate(tempTarget);
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);
@ -1169,10 +1169,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
} }
createOrUpdate(extendedBolus); createOrUpdate(extendedBolus);
} else { } else {
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = trJson.getLong("mills"); .date(trJson.getLong("mills"))
tempBasal.source = Source.NIGHTSCOUT; .source(Source.NIGHTSCOUT)
tempBasal.pumpId = trJson.has("pumpId") ? trJson.getLong("pumpId") : 0; .pumpId(trJson.has("pumpId") ? trJson.getLong("pumpId") : 0);
if (trJson.has("duration")) { if (trJson.has("duration")) {
tempBasal.durationInMinutes = trJson.getInt("duration"); tempBasal.durationInMinutes = trJson.getInt("duration");
} }

View file

@ -61,6 +61,31 @@ public class ProfileSwitch implements Interval, DataPointWithLabelInterface {
private Profile profile = null; 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 @Nullable
public Profile getProfileObject() { public Profile getProfileObject() {
if (profile == null) if (profile == null)

View file

@ -71,6 +71,41 @@ public class TempTarget implements Interval {
reason = t.reason; 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 --------- // -------- Interval interface ---------
Long cuttedEnd = null; Long cuttedEnd = null;

View file

@ -60,8 +60,36 @@ public class TemporaryBasal implements Interval {
public TemporaryBasal() { public TemporaryBasal() {
} }
public TemporaryBasal(long date) { public TemporaryBasal date(long date) {
this.date = 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) { public TemporaryBasal(ExtendedBolus extendedBolus) {

View file

@ -128,7 +128,7 @@ public class Treatment implements DataPointWithLabelInterface {
@Override @Override
public String getLabel() { public String getLabel() {
String label = ""; String label = "";
if (insulin > 0) label += DecimalFormatter.to2Decimal(insulin) + "U"; if (insulin > 0) label += DecimalFormatter.toPumpSupportedBolus(insulin) + "U";
if (carbs > 0) if (carbs > 0)
label += "~" + DecimalFormatter.to0Decimal(carbs) + "g"; label += "~" + DecimalFormatter.to0Decimal(carbs) + "g";
return label; return label;
@ -149,7 +149,7 @@ public class Treatment implements DataPointWithLabelInterface {
@Override @Override
public float getSize() { public float getSize() {
return 10; return 2;
} }
@Override @Override

View file

@ -27,6 +27,10 @@ public interface ConstraintsInterface {
return value; return value;
} }
default Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
return value;
}
default Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) { default Constraint<Double> applyBasalConstraints(Constraint<Double> absoluteRate, Profile profile) {
return absoluteRate; return absoluteRate;
} }

View file

@ -116,9 +116,14 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() == null) { if (MainApp.getConfigBuilder().getActiveProfileInterface().getProfile() != null) {
tempTarget.setVisibility(View.GONE); profileSwitch.setVisibility(View.VISIBLE);
} else {
profileSwitch.setVisibility(View.GONE); profileSwitch.setVisibility(View.GONE);
}
if (MainApp.getConfigBuilder().getProfile() == null) {
tempTarget.setVisibility(View.GONE);
extendedBolus.setVisibility(View.GONE); extendedBolus.setVisibility(View.GONE);
extendedBolusCancel.setVisibility(View.GONE); extendedBolusCancel.setVisibility(View.GONE);
tempBasal.setVisibility(View.GONE); tempBasal.setVisibility(View.GONE);
@ -126,6 +131,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
fill.setVisibility(View.GONE); fill.setVisibility(View.GONE);
return; return;
} }
final PumpInterface pump = ConfigBuilderPlugin.getActivePump(); final PumpInterface pump = ConfigBuilderPlugin.getActivePump();
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease() final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
&& pump.getPumpDescription().isSetBasalProfileCapable; && pump.getPumpDescription().isSetBasalProfileCapable;

View file

@ -1,11 +1,11 @@
package info.nightscout.androidaps.plugins.Actions.dialogs; package info.nightscout.androidaps.plugins.Actions.dialogs;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.DialogFragment; import android.support.v4.app.DialogFragment;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -13,17 +13,23 @@ import android.view.ViewGroup;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.Button; import android.widget.Button;
import android.widget.CheckBox;
import com.crashlytics.android.answers.CustomEvent; import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Constants;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.util.LinkedList;
import java.util.List;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; 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.androidaps.queue.Callback;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker; import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse; import info.nightscout.utils.SafeParse;
@ -38,13 +45,13 @@ import info.nightscout.utils.SafeParse;
public class FillDialog extends DialogFragment implements OnClickListener { public class FillDialog extends DialogFragment implements OnClickListener {
private static Logger log = LoggerFactory.getLogger(FillDialog.class); private static Logger log = LoggerFactory.getLogger(FillDialog.class);
Button deliverButton;
double amount1 = 0d; double amount1 = 0d;
double amount2 = 0d; double amount2 = 0d;
double amount3 = 0d; double amount3 = 0d;
NumberPicker editInsulin; NumberPicker editInsulin;
CheckBox pumpSiteChangeCheckbox;
CheckBox insulinCartridgeChangeCheckbox;
public FillDialog() { public FillDialog() {
} }
@ -54,22 +61,24 @@ public class FillDialog extends DialogFragment implements OnClickListener {
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fill_dialog, null, false); 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().requestFeature(Window.FEATURE_NO_TITLE);
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 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 maxInsulin = MainApp.getConstraintChecker().getMaxBolusAllowed().value();
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep;
editInsulin = (NumberPicker) view.findViewById(R.id.treatments_newtreatment_insulinamount); editInsulin = view.findViewById(R.id.treatments_newtreatment_insulinamount);
editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, new DecimalFormat("0.00"), false); editInsulin.setParams(0d, 0d, maxInsulin, bolusstep, DecimalFormatter.pumpSupportedBolusFormat(), false);
//setup preset buttons //setup preset buttons
Button button1 = (Button) view.findViewById(R.id.fill_preset_button1); Button button1 = (Button) view.findViewById(R.id.fill_preset_button1);
Button button2 = (Button) view.findViewById(R.id.fill_preset_button2); Button button2 = (Button) view.findViewById(R.id.fill_preset_button2);
Button button3 = (Button) view.findViewById(R.id.fill_preset_button3); 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); amount1 = SP.getDouble("fill_button1", 0.3);
amount2 = SP.getDouble("fill_button2", 0d); amount2 = SP.getDouble("fill_button2", 0d);
@ -77,81 +86,85 @@ public class FillDialog extends DialogFragment implements OnClickListener {
if (amount1 > 0) { if (amount1 > 0) {
button1.setVisibility(View.VISIBLE); button1.setVisibility(View.VISIBLE);
button1.setText(DecimalFormatter.to2Decimal(amount1) + "U"); button1.setText(DecimalFormatter.toPumpSupportedBolus(amount1)); // + "U");
button1.setOnClickListener(this); button1.setOnClickListener(this);
} else { } else {
button1.setVisibility(View.GONE); button1.setVisibility(View.GONE);
} }
if (amount2 > 0) { if (amount2 > 0) {
button2.setVisibility(View.VISIBLE); button2.setVisibility(View.VISIBLE);
button2.setText(DecimalFormatter.to2Decimal(amount2) + "U"); button2.setText(DecimalFormatter.toPumpSupportedBolus(amount2)); // + "U");
button2.setOnClickListener(this); button2.setOnClickListener(this);
} else { } else {
button2.setVisibility(View.GONE); button2.setVisibility(View.GONE);
} }
if (amount3 > 0) { if (amount3 > 0) {
button3.setVisibility(View.VISIBLE); button3.setVisibility(View.VISIBLE);
button3.setText(DecimalFormatter.to2Decimal(amount3) + "U"); button3.setText(DecimalFormatter.toPumpSupportedBolus(amount3)); // + "U");
button3.setOnClickListener(this); button3.setOnClickListener(this);
} else { } else {
button3.setVisibility(View.GONE); button3.setVisibility(View.GONE);
} }
if (button1.getVisibility() == View.GONE && button2.getVisibility() == View.GONE && button3.getVisibility() == View.GONE) {
divider.setVisibility(View.GONE);
}
setCancelable(true); setCancelable(true);
getDialog().setCanceledOnTouchOutside(false); getDialog().setCanceledOnTouchOutside(false);
return view; return view;
} }
@Override
public void onResume() {
super.onResume();
if (getDialog() != null)
getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
@Override @Override
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.treatments_newtreatment_deliverbutton: case R.id.ok:
Double insulin = SafeParse.stringToDouble(editInsulin.getText().toString()); confirmAndDeliver();
confirmAndDeliver(insulin); break;
case R.id.cancel:
dismiss();
break; break;
case R.id.fill_preset_button1: case R.id.fill_preset_button1:
confirmAndDeliver(amount1); editInsulin.setValue(amount1);
break; break;
case R.id.fill_preset_button2: case R.id.fill_preset_button2:
confirmAndDeliver(amount2); editInsulin.setValue(amount2);
break; break;
case R.id.fill_preset_button3: case R.id.fill_preset_button3:
confirmAndDeliver(amount3); editInsulin.setValue(amount3);
break; break;
} }
} }
private void confirmAndDeliver(Double insulin) { private void confirmAndDeliver() {
try { try {
Double insulin = SafeParse.stringToDouble(editInsulin.getText());
String confirmMessage = getString(R.string.fillwarning) + "\n"; List<String> confirmMessage = new LinkedList<>();
Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value(); Double insulinAfterConstraints = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(insulin)).value();
confirmMessage += getString(R.string.bolus) + ": " + insulinAfterConstraints + "U"; if (insulinAfterConstraints > 0) {
if (insulinAfterConstraints - insulin != 0) confirmMessage.add(MainApp.gs(R.string.fillwarning));
confirmMessage += "\n" + getString(R.string.constraintapllied); confirmMessage.add("");
confirmMessage.add(MainApp.gs(R.string.bolus) + ": " + "<font color='" + MainApp.gc(R.color.colorCarbsButton) + "'>" + insulinAfterConstraints + "U" + "</font>");
if (!insulinAfterConstraints.equals(insulin))
confirmMessage.add("<font color='" + MainApp.sResources.getColor(R.color.low) + "'>" + MainApp.gs(R.string.bolusconstraintapplied) + "</font>");
}
if (pumpSiteChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_pump_site_change) + "</font>");
if (insulinCartridgeChangeCheckbox.isChecked())
confirmMessage.add("" + "<font color='" + MainApp.sResources.getColor(R.color.high) + "'>" + getString(R.string.record_insulin_cartridge_change) + "</font>");
final Double finalInsulinAfterConstraints = insulinAfterConstraints; final Double finalInsulinAfterConstraints = insulinAfterConstraints;
final Context context = getContext(); final Context context = getContext();
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(this.getContext().getString(R.string.confirmation)); if (confirmMessage.isEmpty())
builder.setMessage(confirmMessage); confirmMessage.add(MainApp.gs(R.string.no_action_selected));
builder.setPositiveButton(getString(R.string.primefill), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) { builder.setTitle(MainApp.gs(R.string.confirmation));
builder.setMessage(Html.fromHtml(Joiner.on("<br/>").join(confirmMessage)));
builder.setPositiveButton(getString(R.string.primefill), (dialog, id) -> {
if (finalInsulinAfterConstraints > 0) { if (finalInsulinAfterConstraints > 0) {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo(); DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
detailedBolusInfo.insulin = finalInsulinAfterConstraints; detailedBolusInfo.insulin = finalInsulinAfterConstraints;
@ -173,7 +186,9 @@ public class FillDialog extends DialogFragment implements OnClickListener {
}); });
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.setNegativeButton(getString(R.string.cancel), null);
builder.show(); builder.show();

View file

@ -51,13 +51,13 @@ import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.events.EventNewBasalProfile; import info.nightscout.androidaps.events.EventNewBasalProfile;
import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow; import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.Overview.Dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.HardLimits;
import info.nightscout.utils.NSUpload; import info.nightscout.utils.NSUpload;
import info.nightscout.utils.NumberPicker; import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
@ -108,6 +108,8 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
Date eventTime; Date eventTime;
private static Integer seconds = null;
public void setOptions(OptionsToShow options, int event) { public void setOptions(OptionsToShow options, int event) {
this.options = options; this.options = options;
this.event = MainApp.sResources.getString(event); this.event = MainApp.sResources.getString(event);
@ -115,6 +117,10 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public NewNSTreatmentDialog() { public NewNSTreatmentDialog() {
super(); super();
if (seconds == null) {
seconds = new Double(Math.random() * 59).intValue();
}
} }
@Override @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 = (NumberPicker) view.findViewById(R.id.careportal_newnstreatment_absoluteinput);
editAbsolute.setParams(0d, 0d, maxAbsolute, 0.05d, new DecimalFormat("0.00"), true, absoluteTextWatcher); 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 = (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); 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) { if (ps != null && ps.isCPP) {
final int percentage = ps.percentage; final int percentage = ps.percentage;
final int timeshift = ps.timeshift; final int timeshift = ps.timeshift;
reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h"); reuseButton.setText(reuseButton.getText() + " " + percentage + "% " + timeshift + "h");
reuseButton.setOnClickListener(new View.OnClickListener() { reuseButton.setOnClickListener(v -> {
@Override
public void onClick(View v) {
editPercentage.setValue((double) percentage); editPercentage.setValue((double) percentage);
editTimeshift.setValue((double) timeshift); 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_eventtime_layout), options.date);
showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg); showOrHide((ViewGroup) view.findViewById(R.id.careportal_newnstreatment_bg_layout), options.bg);
@ -440,7 +448,7 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) { public void onTimeSet(RadialPickerLayout view, int hourOfDay, int minute, int second) {
eventTime.setHours(hourOfDay); eventTime.setHours(hourOfDay);
eventTime.setMinutes(minute); 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)); timeButton.setText(DateUtil.timeString(eventTime));
updateBGforDateTime(); updateBGforDateTime();
} }
@ -692,17 +700,16 @@ public class NewNSTreatmentDialog extends DialogFragment implements View.OnClick
} else if (options.executeTempTarget) { } else if (options.executeTempTarget) {
try { try {
if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) { if ((data.has("targetBottom") && data.has("targetTop")) || (data.has("duration") && data.getInt("duration") == 0)) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = eventTime.getTime(); .date(eventTime.getTime())
tempTarget.durationInMinutes = data.getInt("duration"); .duration(data.getInt("duration"))
tempTarget.reason = data.getString("reason"); .reason(data.getString("reason"))
tempTarget.source = Source.USER; .source(Source.USER);
if (tempTarget.durationInMinutes != 0) { if (tempTarget.durationInMinutes != 0) {
tempTarget.low = Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()); tempTarget.low(Profile.toMgdl(data.getDouble("targetBottom"), profile.getUnits()))
tempTarget.high = Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()); .high(Profile.toMgdl(data.getDouble("targetTop"), profile.getUnits()));
} else { } else {
tempTarget.low = 0; tempTarget.low(0).high(0);
tempTarget.high = 0;
} }
log.debug("Creating new TempTarget db record: " + tempTarget.toString()); log.debug("Creating new TempTarget db record: " + tempTarget.toString());
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.ConfigBuilder;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.annotation.NonNull;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -17,11 +17,13 @@ import android.widget.ListAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import com.crashlytics.android.answers.CustomEvent; import com.crashlytics.android.answers.CustomEvent;
import java.util.ArrayList; import java.util.ArrayList;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.PreferencesActivity; import info.nightscout.androidaps.PreferencesActivity;
import info.nightscout.androidaps.R; 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.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.SensitivityInterface; 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.Insulin.InsulinFastactingPlugin;
import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin; import info.nightscout.androidaps.plugins.ProfileNS.NSProfilePlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
@ -43,33 +46,46 @@ import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.PasswordProtection; import info.nightscout.utils.PasswordProtection;
public class ConfigBuilderFragment extends Fragment { public class ConfigBuilderFragment extends SubscriberFragment {
static ConfigBuilderPlugin configBuilderPlugin = new ConfigBuilderPlugin();
static public ConfigBuilderPlugin getPlugin() {
return configBuilderPlugin;
}
@BindView(R.id.configbuilder_insulinlistview)
ListView insulinListView; ListView insulinListView;
@BindView(R.id.configbuilder_sensitivitylistview)
ListView sensitivityListView; ListView sensitivityListView;
@BindView(R.id.configbuilder_bgsourcelistview)
ListView bgsourceListView; ListView bgsourceListView;
@BindView(R.id.configbuilder_bgsourcelabel)
TextView bgsourceLabel; TextView bgsourceLabel;
@BindView(R.id.configbuilder_pumplistview)
ListView pumpListView; ListView pumpListView;
@BindView(R.id.configbuilder_pumplabel)
TextView pumpLabel; TextView pumpLabel;
@BindView(R.id.configbuilder_looplistview)
ListView loopListView; ListView loopListView;
@BindView(R.id.configbuilder_looplabel)
TextView loopLabel; TextView loopLabel;
@BindView(R.id.configbuilder_treatmentslistview)
ListView treatmentsListView; ListView treatmentsListView;
@BindView(R.id.configbuilder_treatmentslabel)
TextView treatmentsLabel; TextView treatmentsLabel;
@BindView(R.id.configbuilder_profilelistview)
ListView profileListView; ListView profileListView;
@BindView(R.id.configbuilder_profilelabel)
TextView profileLabel; TextView profileLabel;
@BindView(R.id.configbuilder_apslistview)
ListView apsListView; ListView apsListView;
@BindView(R.id.configbuilder_apslabel)
TextView apsLabel; TextView apsLabel;
@BindView(R.id.configbuilder_constraintslistview)
ListView constraintsListView; ListView constraintsListView;
@BindView(R.id.configbuilder_constraintslabel)
TextView constraintsLabel; TextView constraintsLabel;
@BindView(R.id.configbuilder_generallistview)
ListView generalListView; ListView generalListView;
@BindView(R.id.configbuilder_mainlayout)
LinearLayout mainLayout; LinearLayout mainLayout;
@BindView(R.id.configbuilder_unlock)
Button unlock; Button unlock;
PluginCustomAdapter insulinDataAdapter = null; PluginCustomAdapter insulinDataAdapter = null;
@ -84,51 +100,17 @@ public class ConfigBuilderFragment extends Fragment {
PluginCustomAdapter generalDataAdapter = null; PluginCustomAdapter generalDataAdapter = null;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
try { try {
View view = inflater.inflate(R.layout.configbuilder_fragment, container, false); View view = inflater.inflate(R.layout.configbuilder_fragment, container, false);
insulinListView = (ListView) view.findViewById(R.id.configbuilder_insulinlistview); unbinder = ButterKnife.bind(this, view);
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);
mainLayout = (LinearLayout) view.findViewById(R.id.configbuilder_mainlayout); if (PasswordProtection.isLocked("settings_password"))
unlock = (Button) view.findViewById(R.id.configbuilder_unlock);
setViews();
if (PasswordProtection.isLocked("settings_password")) {
mainLayout.setVisibility(View.GONE); mainLayout.setVisibility(View.GONE);
unlock.setOnClickListener(new View.OnClickListener() { else
@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); unlock.setVisibility(View.GONE);
}
}, null);
}
});
} else {
unlock.setVisibility(View.GONE);
}
return view; return view;
} catch (Exception e) { } catch (Exception e) {
FabricPrivacy.logException(e); FabricPrivacy.logException(e);
@ -137,7 +119,18 @@ public class ConfigBuilderFragment extends Fragment {
return null; 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); insulinDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInListByInterface(InsulinInterface.class, PluginBase.INSULIN), PluginBase.INSULIN);
insulinListView.setAdapter(insulinDataAdapter); insulinListView.setAdapter(insulinDataAdapter);
setListViewHeightBasedOnChildren(insulinListView); 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); generalDataAdapter = new PluginCustomAdapter(getContext(), R.layout.configbuilder_simpleitem, MainApp.getSpecificPluginsVisibleInList(PluginBase.GENERAL), PluginBase.GENERAL);
generalListView.setAdapter(generalDataAdapter); generalListView.setAdapter(generalDataAdapter);
setListViewHeightBasedOnChildren(generalListView); setListViewHeightBasedOnChildren(generalListView);
} }
/* /*
@ -194,7 +186,7 @@ public class ConfigBuilderFragment extends Fragment {
private ArrayList<PluginBase> pluginList; private ArrayList<PluginBase> pluginList;
final private int type; final private int type;
public PluginCustomAdapter(Context context, int textViewResourceId, PluginCustomAdapter(Context context, int textViewResourceId,
ArrayList<PluginBase> pluginList, int type) { ArrayList<PluginBase> pluginList, int type) {
super(context, textViewResourceId, pluginList); super(context, textViewResourceId, pluginList);
this.pluginList = new ArrayList<>(); this.pluginList = new ArrayList<>();
@ -209,10 +201,11 @@ public class ConfigBuilderFragment extends Fragment {
ImageView settings; ImageView settings;
} }
@NonNull
@Override @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); PluginBase plugin = pluginList.get(position);
if (view == null) { if (view == null) {
@ -231,60 +224,45 @@ public class ConfigBuilderFragment extends Fragment {
view.setTag(holder); view.setTag(holder);
holder.checkboxEnabled.setOnClickListener(new View.OnClickListener() { holder.checkboxEnabled.setOnClickListener(v -> {
public void onClick(View v) {
CheckBox cb = (CheckBox) v; CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag(); PluginBase plugin1 = (PluginBase) cb.getTag();
plugin.setPluginEnabled(type, cb.isChecked()); plugin1.setPluginEnabled(type, cb.isChecked());
plugin.setFragmentVisible(type, cb.isChecked()); plugin1.setFragmentVisible(type, cb.isChecked());
onEnabledCategoryChanged(plugin, type); onEnabledCategoryChanged(plugin1, type);
configBuilderPlugin.storeSettings(); ConfigBuilderPlugin.getPlugin().storeSettings();
MainApp.bus().post(new EventRefreshGui()); MainApp.bus().post(new EventRefreshGui());
MainApp.bus().post(new EventConfigBuilderChange()); MainApp.bus().post(new EventConfigBuilderChange());
getPlugin().logPluginStatus(); ConfigBuilderPlugin.getPlugin().logPluginStatus();
FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange")); FabricPrivacy.getInstance().logCustom(new CustomEvent("ConfigurationChange"));
}
}); });
holder.checkboxVisible.setOnClickListener(new View.OnClickListener() { holder.checkboxVisible.setOnClickListener(v -> {
public void onClick(View v) {
CheckBox cb = (CheckBox) v; CheckBox cb = (CheckBox) v;
PluginBase plugin = (PluginBase) cb.getTag(); PluginBase plugin12 = (PluginBase) cb.getTag();
plugin.setFragmentVisible(type, cb.isChecked()); plugin12.setFragmentVisible(type, cb.isChecked());
configBuilderPlugin.storeSettings(); ConfigBuilderPlugin.getPlugin().storeSettings();
MainApp.bus().post(new EventRefreshGui()); MainApp.bus().post(new EventRefreshGui());
getPlugin().logPluginStatus(); ConfigBuilderPlugin.getPlugin().logPluginStatus();
}
}); });
holder.settings.setOnClickListener(new View.OnClickListener() { holder.settings.setOnClickListener(v -> {
public void onClick(View v) { final PluginBase plugin13 = (PluginBase) v.getTag();
final PluginBase plugin = (PluginBase) v.getTag(); PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", new Runnable() {
@Override
public void run() {
Intent i = new Intent(getContext(), PreferencesActivity.class); Intent i = new Intent(getContext(), PreferencesActivity.class);
i.putExtra("id", plugin.getPreferencesId()); i.putExtra("id", plugin13.getPreferencesId());
startActivity(i); startActivity(i);
}
}, null); }, null);
}
}); });
holder.name.setOnLongClickListener(new View.OnLongClickListener() { holder.name.setOnLongClickListener(v -> {
@Override final PluginBase plugin14 = (PluginBase) v.getTag();
public boolean onLongClick(View v) { PasswordProtection.QueryPassword(getContext(), R.string.settings_password, "settings_password", () -> {
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); Intent i = new Intent(getContext(), PreferencesActivity.class);
i.putExtra("id", plugin.getPreferencesId()); i.putExtra("id", plugin14.getPreferencesId());
startActivity(i); startActivity(i);
}
}, null); }, null);
return false; return false;
}
}); });
} else { } else {
@ -317,7 +295,7 @@ public class ConfigBuilderFragment extends Fragment {
if (pluginList.size() < 2) { if (pluginList.size() < 2) {
holder.checkboxEnabled.setEnabled(false); holder.checkboxEnabled.setEnabled(false);
plugin.setPluginEnabled(type, true); plugin.setPluginEnabled(type, true);
getPlugin().storeSettings(); ConfigBuilderPlugin.getPlugin().storeSettings();
} }
// Constraints cannot be disabled // Constraints cannot be disabled
@ -396,17 +374,17 @@ public class ConfigBuilderFragment extends Fragment {
} }
} else { // enable first plugin in list } else { // enable first plugin in list
if (type == PluginBase.PUMP) if (type == PluginBase.PUMP)
MainApp.getSpecificPlugin(VirtualPumpPlugin.class).setPluginEnabled(type, true); VirtualPumpPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.INSULIN) else if (type == PluginBase.INSULIN)
MainApp.getSpecificPlugin(InsulinFastactingPlugin.class).setPluginEnabled(type, true); InsulinFastactingPlugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.SENSITIVITY) else if (type == PluginBase.SENSITIVITY)
MainApp.getSpecificPlugin(SensitivityOref0Plugin.class).setPluginEnabled(type, true); SensitivityOref0Plugin.getPlugin().setPluginEnabled(type, true);
else if (type == PluginBase.PROFILE) else if (type == PluginBase.PROFILE)
MainApp.getSpecificPlugin(NSProfilePlugin.class).setPluginEnabled(type, true); NSProfilePlugin.getPlugin().setPluginEnabled(type, true);
else else
pluginsInCategory.get(0).setPluginEnabled(type, true); pluginsInCategory.get(0).setPluginEnabled(type, true);
} }
setViews(); updateGUI();
} }
} }

View file

@ -4,12 +4,15 @@ import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.crashlytics.android.answers.CustomEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
@ -20,6 +23,7 @@ import info.nightscout.androidaps.data.IobTotal;
import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.MealData;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileIntervals; import info.nightscout.androidaps.data.ProfileIntervals;
import info.nightscout.androidaps.data.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.CareportalEvent; import info.nightscout.androidaps.db.CareportalEvent;
import info.nightscout.androidaps.db.ExtendedBolus; 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.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NSUpload; import info.nightscout.utils.NSUpload;
import info.nightscout.utils.ToastUtils; import info.nightscout.utils.ToastUtils;
@ -54,7 +59,15 @@ import info.nightscout.utils.ToastUtils;
public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface { public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
private static Logger log = LoggerFactory.getLogger(ConfigBuilderPlugin.class); 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 PumpInterface activePump;
private static ProfileInterface activeProfile; private static ProfileInterface activeProfile;
private static TreatmentsInterface activeTreatments; private static TreatmentsInterface activeTreatments;
@ -193,7 +206,7 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
return commandQueue; return commandQueue;
} }
public static BgSourceInterface getActiveBgSource() { public BgSourceInterface getActiveBgSource() {
return activeBgSource; return activeBgSource;
} }
@ -653,11 +666,14 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
if (profileSwitch.profileJson != null) { if (profileSwitch.profileJson != null) {
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
} else { } else {
Profile profile = activeProfile.getProfile().getSpecificProfile(profileSwitch.profileName); ProfileStore profileStore = activeProfile.getProfile();
if (profileStore != null) {
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
if (profile != null) if (profile != null)
return profileSwitch.profileName; return profileSwitch.profileName;
} }
} }
}
return MainApp.gs(R.string.noprofileselected); return MainApp.gs(R.string.noprofileselected);
} }
@ -692,6 +708,14 @@ public class ConfigBuilderPlugin implements PluginBase, TreatmentsInterface {
return profile; 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"); log.debug("getProfile at the end: returning null");
return null; return null;
} }

View file

@ -5,7 +5,9 @@ import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.interfaces.BgSourceInterface;
import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.Constraint;
import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.ConstraintsInterface;
import info.nightscout.androidaps.interfaces.PluginBase; 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); boolean enabled = SP.getBoolean(R.string.key_use_smb, false);
if (!enabled) if (!enabled)
value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this); value.set(false, MainApp.gs(R.string.smbdisabledinpreferences), this);
ConstraintChecker constraintChecker = MainApp.getConstraintChecker();
Constraint<Boolean> closedLoop = constraintChecker.isClosedLoopAllowed();
if (!closedLoop.value())
value.set(false, MainApp.gs(R.string.smbnotallowedinopenloopmode), this);
return value;
}
@Override
public Constraint<Boolean> isAdvancedFilteringEnabled(Constraint<Boolean> value) {
BgSourceInterface bgSource = MainApp.getConfigBuilder().getActiveBgSource();
if (bgSource != null) {
if (!bgSource.advancedFilteringSupported())
value.set(false, MainApp.gs(R.string.smbalwaysdisabled), this);
}
return value; return value;
} }

View file

@ -64,7 +64,8 @@ public class AutosensData {
public double slopeFromMaxDeviation = 0; public double slopeFromMaxDeviation = 0;
public double slopeFromMinDeviation = 999; 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 ; 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 ;
} }

View file

@ -351,12 +351,11 @@ public class IobCobCalculatorPlugin implements PluginBase {
IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round(); IobTotal basalIob = MainApp.getConfigBuilder().getCalculationToTimeTempBasals(time).round();
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) { if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginBase.APS)) {
// Add expected zere temp basal for next 240 mins // Add expected zere temp basal for next 240 mins
IobTotal basalIobWithZeroTemp = basalIob.clone(); IobTotal basalIobWithZeroTemp = basalIob.copy();
TemporaryBasal t = new TemporaryBasal(); TemporaryBasal t = new TemporaryBasal()
t.date = now + 60 * 1000L; .date(now + 60 * 1000L)
t.durationInMinutes = 240; .duration(240)
t.isAbsolute = true; .absolute(0);
t.absoluteRate = 0;
if (t.date < time) { if (t.date < time) {
IobTotal calc = t.iobCalc(time); IobTotal calc = t.iobCalc(time);
basalIobWithZeroTemp.plus(calc); basalIobWithZeroTemp.plus(calc);

View file

@ -4,6 +4,9 @@ import android.content.Context;
import android.os.PowerManager; import android.os.PowerManager;
import android.support.v4.util.LongSparseArray; import android.support.v4.util.LongSparseArray;
import com.crashlytics.android.Crashlytics;
import com.crashlytics.android.answers.CustomEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -11,6 +14,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.BuildConfig;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
@ -22,6 +26,7 @@ import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.queue.QueueThread; import info.nightscout.androidaps.queue.QueueThread;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.FabricPrivacy;
/** /**
* Created by mike on 23.01.2018. * Created by mike on 23.01.2018.
@ -151,8 +156,10 @@ public class IobCobThread extends Thread {
AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago); AutosensData hourAgoData = iobCobCalculatorPlugin.getAutosensData(hourago);
if (hourAgoData != null) { if (hourAgoData != null) {
int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time); int initialIndex = autosensDataTable.indexOfKey(hourAgoData.time);
log.debug(">>>>> bucketed_data.size()=" + bucketed_data.size() + " i=" + i + "hourAgoData=" + hourAgoData.toString());
for (int past = 1; past < 12; past++) { int past = 1;
try {
for (; past < 12; past++) {
AutosensData ad = autosensDataTable.valueAt(initialIndex + past); AutosensData ad = autosensDataTable.valueAt(initialIndex + past);
double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5; double deviationSlope = (ad.avgDeviation - avgDeviation) / (ad.time - bgTime) * 1000 * 60 * 5;
if (ad.avgDeviation > maxDeviation) { if (ad.avgDeviation > maxDeviation) {
@ -167,6 +174,17 @@ public class IobCobThread extends Thread {
//if (Config.logAutosensData) //if (Config.logAutosensData)
// log.debug("Deviations: " + new Date(bgTime) + new Date(ad.time) + " avgDeviation=" + avgDeviation + " deviationSlope=" + deviationSlope + " slopeFromMaxDeviation=" + slopeFromMaxDeviation + " slopeFromMinDeviation=" + slopeFromMinDeviation); // 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)); log.debug("Running detectSensitivity from: " + DateUtil.dateAndTimeString(oldestTimeWithData) + " to: " + DateUtil.dateAndTimeString(bgTime));
autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio; autosensData.autosensRatio = iobCobCalculatorPlugin.detectSensitivity(oldestTimeWithData, bgTime).ratio;
if (Config.logAutosensData) if (Config.logAutosensData)
log.debug(autosensData.log(bgTime)); log.debug(autosensData.toString());
} }
} }
MainApp.bus().post(new EventAutosensCalculationFinished(cause)); MainApp.bus().post(new EventAutosensCalculationFinished(cause));

View file

@ -62,7 +62,7 @@ public class APSResult {
// smb // smb
if (smb != 0) if (smb != 0)
ret += ("SMB: " + DecimalFormatter.to2Decimal(smb) + " U\n"); ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U\n");
// reason // reason
ret += MainApp.sResources.getString(R.string.reason) + ": " + reason; ret += MainApp.sResources.getString(R.string.reason) + ": " + reason;
@ -87,7 +87,7 @@ public class APSResult {
// smb // smb
if (smb != 0) if (smb != 0)
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.to2Decimal(smb) + " U<br>"); ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb) + " U<br>");
// reason // reason
ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;"); ret += "<b>" + MainApp.sResources.getString(R.string.reason) + "</b>: " + reason.replace("<", "&lt;").replace(">", "&gt;");

View file

@ -46,6 +46,7 @@ public class DetermineBasalAdapterSMBJS {
private JSONObject mCurrentTemp; private JSONObject mCurrentTemp;
private JSONObject mAutosensData = null; private JSONObject mAutosensData = null;
private boolean mMicrobolusAllowed; private boolean mMicrobolusAllowed;
private boolean mSMBAlwaysAllowed;
private String storedCurrentTemp = null; private String storedCurrentTemp = null;
private String storedIobData = null; private String storedIobData = null;
@ -55,6 +56,7 @@ public class DetermineBasalAdapterSMBJS {
private String storedMeal_data = null; private String storedMeal_data = null;
private String storedAutosens_data = null; private String storedAutosens_data = null;
private String storedMicroBolusAllowed = null; private String storedMicroBolusAllowed = null;
private String storedSMBAlwaysAllowed = null;
private String scriptDebug = ""; private String scriptDebug = "";
@ -82,6 +84,7 @@ public class DetermineBasalAdapterSMBJS {
log.debug("Autosens data: " + (storedAutosens_data = "undefined")); log.debug("Autosens data: " + (storedAutosens_data = "undefined"));
log.debug("Reservoir data: " + "undefined"); log.debug("Reservoir data: " + "undefined");
log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed)); log.debug("MicroBolusAllowed: " + (storedMicroBolusAllowed = "" + mMicrobolusAllowed));
log.debug("SMBAlwaysAllowed: " + (storedSMBAlwaysAllowed = "" + mSMBAlwaysAllowed));
DetermineBasalResultSMB determineBasalResultSMB = null; DetermineBasalResultSMB determineBasalResultSMB = null;
@ -210,7 +213,8 @@ public class DetermineBasalAdapterSMBJS {
MealData mealData, MealData mealData,
double autosensDataRatio, double autosensDataRatio,
boolean tempTargetSet, boolean tempTargetSet,
boolean microBolusAllowed boolean microBolusAllowed,
boolean smbAlwaysAllowed
) throws JSONException { ) throws JSONException {
String units = profile.getUnits(); String units = profile.getUnits();
@ -244,12 +248,11 @@ public class DetermineBasalAdapterSMBJS {
mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap); mProfile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap);
mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false)); mProfile.put("enableUAM", SP.getBoolean(R.string.key_use_uam, false));
mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable); mProfile.put("A52_risk_enable", SMBDefaults.A52_risk_enable);
boolean SMBEnabled = MainApp.getConstraintChecker().isSMBModeEnabled().value() && MainApp.getConstraintChecker().isClosedLoopAllowed().value(); mProfile.put("enableSMB_with_COB", SP.getBoolean(R.string.key_enableSMB_with_COB, false));
mProfile.put("enableSMB_with_COB", SMBEnabled && 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("enableSMB_with_temptarget", SMBEnabled && 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("allowSMB_with_high_temptarget", SMBEnabled && 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_always", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_always, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported()); mProfile.put("enableSMB_after_carbs", SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && smbAlwaysAllowed);
mProfile.put("enableSMB_after_carbs", SMBEnabled && SP.getBoolean(R.string.key_enableSMB_after_carbs, false) && ConfigBuilderPlugin.getActiveBgSource().advancedFilteringSupported());
mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes)); mProfile.put("maxSMBBasalMinutes", SP.getInt("key_smbmaxminutes", SMBDefaults.maxSMBBasalMinutes));
mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold); mProfile.put("carbsReqThreshold", SMBDefaults.carbsReqThreshold);
@ -308,6 +311,7 @@ public class DetermineBasalAdapterSMBJS {
mAutosensData.put("ratio", 1.0); mAutosensData.put("ratio", 1.0);
} }
mMicrobolusAllowed = microBolusAllowed; mMicrobolusAllowed = microBolusAllowed;
mSMBAlwaysAllowed = smbAlwaysAllowed;
} }

View file

@ -95,26 +95,26 @@ public class OpenAPSSMBFragment extends SubscriberFragment {
} }
DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS; DetermineBasalAdapterSMBJS determineBasalAdapterSMBJS = plugin.lastDetermineBasalAdapterSMBJS;
if (determineBasalAdapterSMBJS != null) { if (determineBasalAdapterSMBJS != null) {
glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam())); glucoseStatusView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getGlucoseStatusParam()).toString().trim());
currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam())); currentTempView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getCurrentTempParam()).toString().trim());
try { try {
JSONArray iobArray = new JSONArray(determineBasalAdapterSMBJS.getIobDataParam()); 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) { } catch (JSONException e) {
e.printStackTrace(); log.error("Unhandled exception", e);
iobDataView.setText("JSONException"); iobDataView.setText("JSONException see log for details");
} }
profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam())); profileView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getProfileParam()).toString().trim());
mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam())); mealDataView.setText(JSONFormatter.format(determineBasalAdapterSMBJS.getMealDataParam()).toString().trim());
scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug()); scriptdebugView.setText(determineBasalAdapterSMBJS.getScriptDebug().trim());
if (lastAPSResult != null && lastAPSResult.inputConstraints != null) if (lastAPSResult != null && lastAPSResult.inputConstraints != null)
constraintsView.setText(lastAPSResult.inputConstraints.getReasons()); constraintsView.setText(lastAPSResult.inputConstraints.getReasons().trim());
} }
if (plugin.lastAPSRun != null) { if (plugin.lastAPSRun != null) {
lastRunView.setText(plugin.lastAPSRun.toLocaleString()); lastRunView.setText(plugin.lastAPSRun.toLocaleString().trim());
} }
if (plugin.lastAutosensResult != null) { if (plugin.lastAutosensResult != null) {
autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json())); autosensDataView.setText(JSONFormatter.format(plugin.lastAutosensResult.json()).toString().trim());
} }
} }
}); });

View file

@ -231,6 +231,15 @@ public class OpenAPSSMBPlugin implements PluginBase, APSInterface {
} else { } else {
lastAutosensResult = new AutosensResult(); lastAutosensResult = new AutosensResult();
} }
Constraint<Boolean> smbAllowed = new Constraint<>(true);
MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed);
inputConstraints.copyReasons(smbAllowed);
Constraint<Boolean> smbAlwaysEnabled = new Constraint<>(true);
MainApp.getConstraintChecker().isAdvancedFilteringEnabled(smbAlwaysEnabled);
inputConstraints.copyReasons(smbAlwaysEnabled);
Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart); Profiler.log(log, "detectSensitivityandCarbAbsorption()", startPart);
Profiler.log(log, "SMB data gathering", start); 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, determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg, ConfigBuilderPlugin.getActivePump().getBaseBasalRate(), iobArray, glucoseStatus, mealData,
lastAutosensResult.ratio, //autosensDataRatio lastAutosensResult.ratio, //autosensDataRatio
isTempTarget, isTempTarget,
true //microBolusAllowed smbAllowed.value(),
smbAlwaysEnabled.value()
); );
} catch (JSONException e) { } catch (JSONException e) {
log.error(e.getMessage()); log.error(e.getMessage());

View file

@ -380,31 +380,31 @@ public class NewCarbsDialog extends DialogFragment implements OnClickListener, D
accepted = true; accepted = true;
if (startActivityTTCheckbox.isChecked()) { if (startActivityTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalActivityTTDuration; .duration(finalActivityTTDuration)
tempTarget.reason = MainApp.gs(R.string.activity); .reason(MainApp.gs(R.string.activity))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalActivityTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalActivityTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startEatingSoonTTCheckbox.isChecked()) { } else if (startEatingSoonTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalEatingSoonTTDuration; .duration(finalEatingSoonTTDuration)
tempTarget.reason = MainApp.gs(R.string.eatingsoon); .reason(MainApp.gs(R.string.eatingsoon))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalEatigSoonTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} else if (startHypoTTCheckbox.isChecked()) { } else if (startHypoTTCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = finalHypoTTDuration; .duration(finalHypoTTDuration)
tempTarget.reason = MainApp.gs(R.string.hypo); .reason(MainApp.gs(R.string.hypo))
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); .low(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()))
tempTarget.high = Profile.toMgdl(finalHypoTT, currentProfile.getUnits()); .high(Profile.toMgdl(finalHypoTT, currentProfile.getUnits()));
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);
} }

View file

@ -20,7 +20,6 @@ import android.widget.Button;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.TextView; import android.widget.TextView;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent; import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; 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.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.NumberPicker; import info.nightscout.utils.NumberPicker;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import info.nightscout.utils.SafeParse; 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 = (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); dateButton = (TextView) view.findViewById(R.id.newinsulin_eventdate);
timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime); timeButton = (TextView) view.findViewById(R.id.newinsulin_eventtime);
@ -160,7 +161,8 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
} }
private String toSignedString(double value) { private String toSignedString(double value) {
return value > 0 ? "+" + value : String.valueOf(value); String formatted = DecimalFormatter.toPumpSupportedBolus(value);
return value > 0 ? "+" + formatted : formatted;
} }
@Override @Override
@ -279,13 +281,13 @@ public class NewInsulinDialog extends DialogFragment implements OnClickListener,
accepted = true; accepted = true;
if (startESMCheckbox.isChecked()) { if (startESMCheckbox.isChecked()) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = (int) ttDuration; .duration((int) ttDuration)
tempTarget.reason = "Eating soon"; .reason("Eating soon")
tempTarget.source = Source.USER; .source(Source.USER)
tempTarget.low = (int) finalTT; .low((int) finalTT)
tempTarget.high = (int) finalTT; .high((int) finalTT);
MainApp.getDbHelper().createOrUpdate(tempTarget); 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"));
} }
} }
}); });

View file

@ -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); 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); editCarbs.setParams(0d, 0d, (double) maxCarbs, 1d, new DecimalFormat("0"), false, textWatcher);
double bolusstep = ConfigBuilderPlugin.getActivePump().getPumpDescription().bolusStep; 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); editCarbTime.setParams(0d, -60d, 60d, 5d, new DecimalFormat("0"), false);
initDialog(); initDialog();
@ -260,19 +260,13 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
} }
private void saveCheckedStates() { 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_cob), cobCheckbox.isChecked());
SP.putBoolean(getString(R.string.key_wizard_include_trend_bg), bgtrendCheckbox.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() { 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)); 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)); 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 @Override
@ -461,7 +455,9 @@ public class WizardDialog extends DialogFragment implements OnClickListener, Com
Double c_bg = SafeParse.stringToDouble(editBg.getText()); Double c_bg = SafeParse.stringToDouble(editBg.getText());
Integer c_carbs = SafeParse.stringToInt(editCarbs.getText()); Integer c_carbs = SafeParse.stringToInt(editCarbs.getText());
Double c_correction = SafeParse.stringToDouble(editCorr.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 if (c_correction - corrAfterConstraint != 0) { // c_correction != corrAfterConstraint doesn't work
editCorr.setValue(0d); editCorr.setValue(0d);
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), getString(R.string.bolusconstraintapplied)); 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) { 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") : ""; String carbsText = calculatedCarbs > 0d ? (DecimalFormatter.to0Decimal(calculatedCarbs) + "g") : "";
total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText); total.setText(MainApp.gs(R.string.result) + ": " + insulinText + " " + carbsText);
okButton.setVisibility(View.VISIBLE); okButton.setVisibility(View.VISIBLE);

View file

@ -288,13 +288,28 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
llm = new LinearLayoutManager(view.getContext()); llm = new LinearLayoutManager(view.getContext());
notificationsView.setLayoutManager(llm); 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().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
bgGraph.getGridLabelRenderer().reloadStyles(); bgGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid)); iobGraph.getGridLabelRenderer().setGridColor(MainApp.sResources.getColor(R.color.graphgrid));
iobGraph.getGridLabelRenderer().reloadStyles(); iobGraph.getGridLabelRenderer().reloadStyles();
iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false); iobGraph.getGridLabelRenderer().setHorizontalLabelsVisible(false);
bgGraph.getGridLabelRenderer().setLabelVerticalWidth(50); bgGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
iobGraph.getGridLabelRenderer().setLabelVerticalWidth(50); iobGraph.getGridLabelRenderer().setLabelVerticalWidth(axisWidth);
iobGraph.getGridLabelRenderer().setNumVerticalLabels(5); iobGraph.getGridLabelRenderer().setNumVerticalLabels(5);
rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6); rangeToDisplay = SP.getInt(R.string.key_rangetodisplay, 6);
@ -1166,7 +1181,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
extendedBolusView.setText(extendedBolusText); extendedBolusView.setText(extendedBolusText);
} }
if (extendedBolusText.equals("")) if (extendedBolusText.equals(""))
extendedBolusView.setVisibility(View.GONE); extendedBolusView.setVisibility(View.INVISIBLE);
else else
extendedBolusView.setVisibility(View.VISIBLE); extendedBolusView.setVisibility(View.VISIBLE);
} }
@ -1194,7 +1209,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
quickWizardButton.setVisibility(View.VISIBLE); quickWizardButton.setVisibility(View.VISIBLE);
String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g"; String text = quickWizardEntry.buttonText() + "\n" + DecimalFormatter.to0Decimal(quickWizardEntry.carbs()) + "g";
BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false); BolusWizard wizard = quickWizardEntry.doCalc(profile, tempTarget, lastBG, false);
text += " " + DecimalFormatter.to2Decimal(wizard.calculatedTotalInsulin) + "U"; text += " " + DecimalFormatter.toPumpSupportedBolus(wizard.calculatedTotalInsulin) + "U";
quickWizardButton.setText(text); quickWizardButton.setText(text);
if (wizard.calculatedTotalInsulin <= 0) if (wizard.calculatedTotalInsulin <= 0)
quickWizardButton.setVisibility(View.GONE); quickWizardButton.setVisibility(View.GONE);

View file

@ -48,11 +48,11 @@ import java.util.Iterator;
*/ */
public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> extends BaseSeries<E> { public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> extends BaseSeries<E> {
// Default spSize // Default spSize
int spSize = 12; int spSize = 14;
// Convert the sp to pixels // Convert the sp to pixels
Context context = MainApp.instance().getApplicationContext(); Context context = MainApp.instance().getApplicationContext();
float scaledTextSize = spSize * context.getResources().getDisplayMetrics().scaledDensity; 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 * choose a predefined shape to render for
@ -233,9 +233,10 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
} else if (value.getShape() == Shape.SMB) { } else if (value.getShape() == Shape.SMB) {
mPaint.setStrokeWidth(2); mPaint.setStrokeWidth(2);
Point[] points = new Point[3]; Point[] points = new Point[3];
points[0] = new Point((int)endX, (int)(endY-value.getSize())); float size = value.getSize() * scaledPxSize;
points[1] = new Point((int)(endX+value.getSize()), (int)(endY+value.getSize()*0.67)); points[0] = new Point((int)endX, (int)(endY-size));
points[2] = new Point((int)(endX-value.getSize()), (int)(endY+value.getSize()*0.67)); points[1] = new Point((int)(endX+size), (int)(endY+size*0.67));
points[2] = new Point((int)(endX-size), (int)(endY+size*0.67));
mPaint.setStyle(Paint.Style.FILL_AND_STROKE); mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
drawArrows(points, canvas, mPaint); drawArrows(points, canvas, mPaint);
} else if (value.getShape() == Shape.EXTENDEDBOLUS) { } else if (value.getShape() == Shape.EXTENDEDBOLUS) {

View file

@ -7,6 +7,7 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
@ -16,16 +17,19 @@ import java.util.ArrayList;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemSelected; import butterknife.OnItemSelected;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.data.ProfileStore; 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.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI; import info.nightscout.androidaps.plugins.ProfileNS.events.EventNSProfileUpdateGUI;
import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph; import info.nightscout.androidaps.plugins.Treatments.fragments.ProfileGraph;
import info.nightscout.utils.DecimalFormatter; import info.nightscout.utils.DecimalFormatter;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.OKDialog;
import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED; import static butterknife.OnItemSelected.Callback.NOTHING_SELECTED;
@ -53,6 +57,8 @@ public class NSProfileFragment extends SubscriberFragment {
TextView target; TextView target;
@BindView(R.id.basal_graph) @BindView(R.id.basal_graph)
ProfileGraph basalGraph; ProfileGraph basalGraph;
@BindView(R.id.nsprofile_profileswitch)
Button activateButton;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
@ -79,13 +85,6 @@ public class NSProfileFragment extends SubscriberFragment {
@Override @Override
protected void updateGUI() { protected void updateGUI() {
if (MainApp.getConfigBuilder().getProfile() == null) {
noProfile.setVisibility(View.VISIBLE);
return;
} else {
noProfile.setVisibility(View.GONE);
}
ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile(); ProfileStore profileStore = NSProfilePlugin.getPlugin().getProfile();
if (profileStore != null) { if (profileStore != null) {
ArrayList<CharSequence> profileList = profileStore.getProfileList(); ArrayList<CharSequence> profileList = profileStore.getProfileList();
@ -97,6 +96,9 @@ public class NSProfileFragment extends SubscriberFragment {
if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName())) if (profileList.get(p).equals(MainApp.getConfigBuilder().getProfileName()))
profileSpinner.setSelection(p); 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()); target.setText(profile.getTargetList());
basalGraph.show(profile); basalGraph.show(profile);
} }
if (profile.isValid("NSProfileFragment")) if (profile.isValid("NSProfileFragment")) {
invalidProfile.setVisibility(View.GONE); invalidProfile.setVisibility(View.GONE);
else activateButton.setVisibility(View.VISIBLE);
} else {
invalidProfile.setVisibility(View.VISIBLE); invalidProfile.setVisibility(View.VISIBLE);
activateButton.setVisibility(View.GONE);
}
} else {
activateButton.setVisibility(View.GONE);
} }
} }
@ -135,5 +142,20 @@ public class NSProfileFragment extends SubscriberFragment {
isf.setText(""); isf.setText("");
basal.setText(""); basal.setText("");
target.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)
);
}
}
} }
} }

View file

@ -109,10 +109,14 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
@NonNull @NonNull
private static final ComboPump pump = new ComboPump(); 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; 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; private volatile boolean cancelBolus;
/** /**
@ -131,10 +135,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
*/ */
private volatile boolean pumpHistoryChanged = false; 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 * 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)} * 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<Bolus> recentBoluses = new ArrayList<>(0); private volatile List<Bolus> recentBoluses = new ArrayList<>(0);
public static ComboPlugin getPlugin() { public static ComboPlugin getPlugin() {
@ -373,7 +379,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return new Date(pump.lastSuccessfulCmdTime); 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 @Override
public synchronized void getPumpStatus() { public synchronized void getPumpStatus() {
log.debug("getPumpStatus called"); log.debug("getPumpStatus called");
@ -445,7 +453,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
MainApp.bus().post(new EventComboPumpUpdateGUI()); 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) { private void updateLocalData(CommandResult result) {
if (result.reservoirLevel != PumpState.UNKNOWN) { if (result.reservoirLevel != PumpState.UNKNOWN) {
pump.reservoirLevel = result.reservoirLevel; pump.reservoirLevel = result.reservoirLevel;
@ -737,7 +747,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
cancelBolus = true; 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 - * @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 * 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; PumpState state = commandResult.state;
if (state.tbrActive && state.tbrPercent == adjustedPercent if (state.tbrActive && state.tbrPercent == adjustedPercent
&& (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) { && (state.tbrRemainingDuration == durationInMinutes || state.tbrRemainingDuration == durationInMinutes - 1)) {
TemporaryBasal tempStart = new TemporaryBasal(); TemporaryBasal tempStart = new TemporaryBasal()
tempStart.date = state.timestamp; .date(state.timestamp)
tempStart.durationInMinutes = state.tbrRemainingDuration; .duration(state.tbrRemainingDuration)
tempStart.percentRate = state.tbrPercent; .percent(state.tbrPercent)
tempStart.isAbsolute = false; .source(Source.USER);
tempStart.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStart);
MainApp.bus().post(new EventComboPumpUpdateGUI()); MainApp.bus().post(new EventComboPumpUpdateGUI());
@ -825,7 +835,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return OPERATION_NOT_SUPPORTED; 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, * alert. This relies on TemporaryBasal objects to properly reflect the pumps state,
* which is ensured by {@link #checkAndResolveTbrMismatch(PumpState)}, which runs on each * 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 * 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); return new PumpEnactResult().success(false).enacted(false);
} }
if (!cancelResult.state.tbrActive) { if (!cancelResult.state.tbrActive) {
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = cancelResult.state.timestamp; .date(cancelResult.state.timestamp)
tempBasal.durationInMinutes = 0; .duration(0)
tempBasal.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
return new PumpEnactResult().isTempCancel(true).success(true).enacted(true); return new PumpEnactResult().isTempCancel(true).success(true).enacted(true);
} else { } else {
@ -995,12 +1006,11 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now); TemporaryBasal aapsTbr = MainApp.getConfigBuilder().getTempBasalFromHistory(now);
if (aapsTbr == null || aapsTbr.percentRate != 0) { if (aapsTbr == null || aapsTbr.percentRate != 0) {
log.debug("Creating 15m zero temp since pump is suspended"); log.debug("Creating 15m zero temp since pump is suspended");
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = 0; .percent(0)
newTempBasal.isAbsolute = false; .duration(15)
newTempBasal.durationInMinutes = 15; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); 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) { private void checkPumpTime(PumpState state) {
if (state.pumpTime == 0) { if (state.pumpTime == 0) {
// time couldn't be read (e.g. a warning is displayed on the menu , hiding the time field) // 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("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "new TBR on pump")); .putCustomAttribute("type", "new TBR on pump"));
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = state.tbrPercent; .percent(state.tbrPercent)
newTempBasal.isAbsolute = false; .duration(state.tbrRemainingDuration)
newTempBasal.durationInMinutes = state.tbrRemainingDuration; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal);
} else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) { } else if (aapsTbr != null && aapsTbr.getPlannedRemainingMinutes() > 2 && !state.tbrActive) {
log.debug("Ending AAPS-TBR since pump has no TBR active"); 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("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR cancelled on pump")); .putCustomAttribute("type", "TBR cancelled on pump"));
TemporaryBasal tempStop = new TemporaryBasal(); TemporaryBasal tempStop = new TemporaryBasal()
tempStop.date = now; .date(now)
tempStop.durationInMinutes = 0; .duration(0)
tempStop.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
} else if (aapsTbr != null && state.tbrActive } else if (aapsTbr != null && state.tbrActive
&& (aapsTbr.percentRate != state.tbrPercent || && (aapsTbr.percentRate != state.tbrPercent ||
@ -1150,23 +1161,24 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
.putCustomAttribute("buildversion", BuildConfig.BUILDVERSION) .putCustomAttribute("buildversion", BuildConfig.BUILDVERSION)
.putCustomAttribute("version", BuildConfig.VERSION) .putCustomAttribute("version", BuildConfig.VERSION)
.putCustomAttribute("type", "TBR on pump differs from AAPS TBR")); .putCustomAttribute("type", "TBR on pump differs from AAPS TBR"));
TemporaryBasal tempStop = new TemporaryBasal(); TemporaryBasal tempStop = new TemporaryBasal()
tempStop.date = now - 1000; .date(now - 1000)
tempStop.durationInMinutes = 0; .duration(0)
tempStop.source = Source.USER; .source(Source.USER);
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = now; .date(now)
newTempBasal.percentRate = state.tbrPercent; .percent(state.tbrPercent)
newTempBasal.isAbsolute = false; .duration(state.tbrRemainingDuration)
newTempBasal.durationInMinutes = state.tbrRemainingDuration; .source(Source.USER);
newTempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(newTempBasal); 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) { private boolean readHistory(@Nullable PumpHistoryRequest request) {
CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request)); CommandResult historyResult = runCommand(MainApp.gs(R.string.combo_activity_reading_pump_history), 3, () -> ruffyScripter.readHistory(request));
if (!historyResult.success) { if (!historyResult.success) {
@ -1203,7 +1215,8 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf
return updated; 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 * 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. * 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 * Should be good enough, even with command mode, it's a challenge to create that situation

View file

@ -10,7 +10,6 @@ import android.os.SystemClock;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import com.crashlytics.android.answers.Answers;
import com.crashlytics.android.answers.CustomEvent; import com.crashlytics.android.answers.CustomEvent;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;

View file

@ -68,33 +68,29 @@ public class MsgStatusTempBasal extends MessageBase {
if (danaRPump.isTempBasalInProgress) { if (danaRPump.isTempBasalInProgress) {
if (tempBasal.percentRate != danaRPump.tempBasalPercent) { if (tempBasal.percentRate != danaRPump.tempBasalPercent) {
// Close current temp basal // Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(danaRPump.tempBasalStart.getTime() - 1000); TemporaryBasal tempStop = new TemporaryBasal().date(danaRPump.tempBasalStart.getTime() - 1000).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
// Create new // Create new
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = danaRPump.tempBasalStart.getTime(); .date(danaRPump.tempBasalStart.getTime())
newTempBasal.percentRate = danaRPump.tempBasalPercent; .percent(danaRPump.tempBasalPercent)
newTempBasal.isAbsolute = false; .duration(danaRPump.tempBasalTotalSec / 60)
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; .source(Source.USER);
newTempBasal.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(newTempBasal); treatmentsInterface.addToHistoryTempBasal(newTempBasal);
} }
} else { } else {
// Close current temp basal // Close current temp basal
TemporaryBasal tempStop = new TemporaryBasal(now); TemporaryBasal tempStop = new TemporaryBasal().date(now).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
} }
} else { } else {
if (danaRPump.isTempBasalInProgress) { if (danaRPump.isTempBasalInProgress) {
// Create new // Create new
TemporaryBasal newTempBasal = new TemporaryBasal(); TemporaryBasal newTempBasal = new TemporaryBasal()
newTempBasal.date = danaRPump.tempBasalStart.getTime(); .date(danaRPump.tempBasalStart.getTime())
newTempBasal.percentRate = danaRPump.tempBasalPercent; .percent(danaRPump.tempBasalPercent)
newTempBasal.isAbsolute = false; .duration(danaRPump.tempBasalTotalSec / 60)
newTempBasal.durationInMinutes = danaRPump.tempBasalTotalSec / 60; .source(Source.USER);
newTempBasal.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(newTempBasal); treatmentsInterface.addToHistoryTempBasal(newTempBasal);
} }
} }

View file

@ -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 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); int param2 = ((intFromBuff(data, 9, 1) << 8) & 0xFF00) + (intFromBuff(data, 10, 1) & 0xFF);
TemporaryBasal temporaryBasal = new TemporaryBasal(); TemporaryBasal temporaryBasal = new TemporaryBasal().date(datetime.getTime()).source(Source.PUMP).pumpId(datetime.getTime());
temporaryBasal.date = datetime.getTime();
temporaryBasal.source = Source.PUMP;
temporaryBasal.pumpId = datetime.getTime();
ExtendedBolus extendedBolus = new ExtendedBolus(); ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime(); extendedBolus.date = datetime.getTime();

View file

@ -56,10 +56,10 @@ public class MsgHistoryEvents_v2 extends MessageBase {
int param1 = intFromBuff(bytes, 7, 2); int param1 = intFromBuff(bytes, 7, 2);
int param2 = intFromBuff(bytes, 9, 2); int param2 = intFromBuff(bytes, 9, 2);
TemporaryBasal temporaryBasal = new TemporaryBasal(); TemporaryBasal temporaryBasal = new TemporaryBasal()
temporaryBasal.date = datetime.getTime(); .date(datetime.getTime())
temporaryBasal.source = Source.PUMP; .source(Source.PUMP)
temporaryBasal.pumpId = datetime.getTime(); .pumpId(datetime.getTime());
ExtendedBolus extendedBolus = new ExtendedBolus(); ExtendedBolus extendedBolus = new ExtendedBolus();
extendedBolus.date = datetime.getTime(); extendedBolus.date = datetime.getTime();

View file

@ -592,12 +592,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) { if (pumpEnactResult.success) {
// create log entry // create log entry
final TemporaryBasal tempBasal = new TemporaryBasal(); final TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent_amount)
tempBasal.percentRate = percent_amount; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal);
} }
@ -643,12 +642,11 @@ public class InsightPlugin implements PluginBase, PumpInterface, ConstraintsInte
if (pumpEnactResult.success) { if (pumpEnactResult.success) {
// create log entry // create log entry
final TemporaryBasal tempBasal = new TemporaryBasal(); final TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent)
tempBasal.percentRate = percent; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER); // TODO check this is correct
tempBasal.source = Source.USER; // TODO check this is correct
MainApp.getConfigBuilder().addToHistoryTempBasal(tempBasal); 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 // 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); final Mstatus ms = async.busyWaitForCommandResult(cmd, BUSY_WAIT_TIME);
if (MainApp.getConfigBuilder().isTempBasalInProgress()) { if (MainApp.getConfigBuilder().isTempBasalInProgress()) {
enacted = true; TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis());
tempStop.source = Source.USER;
MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop); MainApp.getConfigBuilder().addToHistoryTempBasal(tempStop);
} }
lastDataTime = new Date(); lastDataTime = new Date();

View file

@ -10,9 +10,8 @@ import info.nightscout.androidaps.db.TemporaryBasal;
/** /**
* Created by jamorham on 27/01/2018. * Created by jamorham on 27/01/2018.
* * <p>
* Write to the History Log * Write to the History Log
*
*/ */
class HistoryLogAdapter { class HistoryLogAdapter {
@ -25,7 +24,7 @@ class HistoryLogAdapter {
void createTBRrecord(Date eventDate, int percent, int duration, long record_id) { 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()); final TemporaryBasal temporaryBasalFromHistory = MainApp.getConfigBuilder().getTempBasalFromHistory(eventDate.getTime());
@ -50,10 +49,10 @@ class HistoryLogAdapter {
} }
} }
temporaryBasal.source = Source.PUMP; temporaryBasal.source(Source.PUMP)
temporaryBasal.pumpId = record_id; .pumpId(record_id)
temporaryBasal.percentRate = percent; .percent(percent)
temporaryBasal.durationInMinutes = duration; .duration(duration);
MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal); MainApp.getConfigBuilder().addToHistoryTempBasal(temporaryBasal);
} }

View file

@ -98,7 +98,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
pumpDescription.basalStep = 0.01d; pumpDescription.basalStep = 0.01d;
pumpDescription.basalMinimumRate = 0.01d; pumpDescription.basalMinimumRate = 0.01d;
pumpDescription.isRefillingCapable = false; pumpDescription.isRefillingCapable = true;
pumpDescription.storesCarbInfo = false; pumpDescription.storesCarbInfo = false;
pumpDescription.is30minBasalRatesCapable = true; pumpDescription.is30minBasalRatesCapable = true;
@ -291,12 +291,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
@Override @Override
public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) { public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, Profile profile, boolean enforceNew) {
TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder(); TreatmentsInterface treatmentsInterface = MainApp.getConfigBuilder();
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = true; .absolute(absoluteRate)
tempBasal.absoluteRate = absoluteRate; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
PumpEnactResult result = new PumpEnactResult(); PumpEnactResult result = new PumpEnactResult();
result.success = true; result.success = true;
result.enacted = true; result.enacted = true;
@ -321,12 +320,11 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
if (!result.success) if (!result.success)
return result; return result;
} }
TemporaryBasal tempBasal = new TemporaryBasal(); TemporaryBasal tempBasal = new TemporaryBasal()
tempBasal.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempBasal.isAbsolute = false; .percent(percent)
tempBasal.percentRate = percent; .duration(durationInMinutes)
tempBasal.durationInMinutes = durationInMinutes; .source(Source.USER);
tempBasal.source = Source.USER;
result.success = true; result.success = true;
result.enacted = true; result.enacted = true;
result.percent = percent; result.percent = percent;
@ -376,8 +374,7 @@ public class VirtualPumpPlugin implements PluginBase, PumpInterface {
result.comment = MainApp.instance().getString(R.string.virtualpump_resultok); result.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
if (treatmentsInterface.isTempBasalInProgress()) { if (treatmentsInterface.isTempBasalInProgress()) {
result.enacted = true; result.enacted = true;
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis()); TemporaryBasal tempStop = new TemporaryBasal().date(System.currentTimeMillis()).source(Source.USER);
tempStop.source = Source.USER;
treatmentsInterface.addToHistoryTempBasal(tempStop); treatmentsInterface.addToHistoryTempBasal(tempStop);
//tempBasal = null; //tempBasal = null;
if (Config.logPumpComm) if (Config.logPumpComm)

View file

@ -57,7 +57,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
private IobTotal lastTreatmentCalculation; private IobTotal lastTreatmentCalculation;
private IobTotal lastTempBasalsCalculation; private IobTotal lastTempBasalsCalculation;
public static List<Treatment> treatments; private final static ArrayList<Treatment> treatments = new ArrayList<>();
private final static Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>(); private final static Intervals<TemporaryBasal> tempBasals = new NonOverlappingIntervals<>();
private final static Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>(); private final static Intervals<ExtendedBolus> extendedBoluses = new NonOverlappingIntervals<>();
private final static Intervals<TempTarget> tempTargets = new OverlappingIntervals<>(); private final static Intervals<TempTarget> tempTargets = new OverlappingIntervals<>();
@ -146,8 +146,10 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null) if (MainApp.getConfigBuilder() != null && MainApp.getConfigBuilder().getProfile() != null)
dia = MainApp.getConfigBuilder().getProfile().getDia(); dia = MainApp.getConfigBuilder().getProfile().getDia();
long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia)); long fromMills = (long) (System.currentTimeMillis() - 60 * 60 * 1000L * (24 + dia));
synchronized (treatments) {
treatments = MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false); treatments.clear();
treatments.addAll(MainApp.getDbHelper().getTreatmentDataFromTime(fromMills, false));
}
} }
private static void initializeTempBasalData() { private static void initializeTempBasalData() {
@ -202,6 +204,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
double dia = profile.getDia(); double dia = profile.getDia();
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) { for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos); Treatment t = treatments.get(pos);
if (!t.isValid) continue; if (!t.isValid) continue;
@ -220,6 +223,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
total.bolussnooze += bIOB.iobContrib; total.bolussnooze += bIOB.iobContrib;
} }
} }
}
if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses()) if (!ConfigBuilderPlugin.getActivePump().isFakingTempsByExtendedBoluses())
synchronized (extendedBoluses) { synchronized (extendedBoluses) {
@ -248,6 +252,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue(); long dia_ago = now - (Double.valueOf(1.5d * profile.getDia() * 60 * 60 * 1000l)).longValue();
synchronized (treatments) {
for (Treatment treatment : treatments) { for (Treatment treatment : treatments) {
if (!treatment.isValid) if (!treatment.isValid)
continue; continue;
@ -262,6 +267,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
} }
} }
} }
}
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("getMealData()"); AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("getMealData()");
if (autosensData != null) { if (autosensData != null) {
@ -275,12 +281,15 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public List<Treatment> getTreatmentsFromHistory() { public List<Treatment> getTreatmentsFromHistory() {
return treatments; synchronized (treatments) {
return (List<Treatment>) treatments.clone();
}
} }
@Override @Override
public List<Treatment> getTreatments5MinBackFromHistory(long time) { public List<Treatment> getTreatments5MinBackFromHistory(long time) {
List<Treatment> in5minback = new ArrayList<>(); List<Treatment> in5minback = new ArrayList<>();
synchronized (treatments) {
for (Integer pos = 0; pos < treatments.size(); pos++) { for (Integer pos = 0; pos < treatments.size(); pos++) {
Treatment t = treatments.get(pos); Treatment t = treatments.get(pos);
if (!t.isValid) if (!t.isValid)
@ -290,15 +299,18 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
} }
return in5minback; return in5minback;
} }
}
@Override @Override
public long getLastBolusTime() { public long getLastBolusTime() {
long now = System.currentTimeMillis(); long now = System.currentTimeMillis();
long last = 0; long last = 0;
synchronized (treatments) {
for (Treatment t : treatments) { for (Treatment t : treatments) {
if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now) if (t.date > last && t.insulin > 0 && t.isValid && t.date <= now)
last = t.date; last = t.date;
} }
}
log.debug("Last bolus time: " + new Date(last).toLocaleString()); log.debug("Last bolus time: " + new Date(last).toLocaleString());
return last; return last;
} }
@ -425,14 +437,14 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public Intervals<ExtendedBolus> getExtendedBolusesFromHistory() { public Intervals<ExtendedBolus> getExtendedBolusesFromHistory() {
synchronized (extendedBoluses) { synchronized (extendedBoluses) {
return extendedBoluses; return new NonOverlappingIntervals<>(extendedBoluses);
} }
} }
@Override @Override
public Intervals<TemporaryBasal> getTemporaryBasalsFromHistory() { public Intervals<TemporaryBasal> getTemporaryBasalsFromHistory() {
synchronized (tempBasals) { synchronized (tempBasals) {
return tempBasals; return new NonOverlappingIntervals<>(tempBasals);
} }
} }
@ -514,7 +526,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public Intervals<TempTarget> getTempTargetsFromHistory() { public Intervals<TempTarget> getTempTargetsFromHistory() {
synchronized (tempTargets) { synchronized (tempTargets) {
return tempTargets; return new OverlappingIntervals<>(tempTargets);
} }
} }
@ -534,7 +546,7 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
@Override @Override
public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() { public ProfileIntervals<ProfileSwitch> getProfileSwitchesFromHistory() {
synchronized (profiles) { synchronized (profiles) {
return profiles; return new ProfileIntervals<>(profiles);
} }
} }

View file

@ -11,6 +11,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.utils.Round;
/** /**
* Created by Adrian on 15.04.2018. * Created by Adrian on 15.04.2018.
@ -48,7 +49,7 @@ public class ProfileGraph extends GraphView {
getViewport().setYAxisBoundsManual(true); getViewport().setYAxisBoundsManual(true);
getViewport().setMinY(0); getViewport().setMinY(0);
getViewport().setMaxY(profile.getMaxDailyBasal()*1.1); getViewport().setMaxY(Round.ceilTo(profile.getMaxDailyBasal()*1.1, 0.5));
getGridLabelRenderer().setNumHorizontalLabels(13); getGridLabelRenderer().setNumHorizontalLabels(13);
getGridLabelRenderer().setVerticalLabelsColor(basalSeries.getColor()); getGridLabelRenderer().setVerticalLabelsColor(basalSeries.getColor());

View file

@ -76,7 +76,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
return; return;
Treatment t = treatments.get(position); Treatment t = treatments.get(position);
holder.date.setText(DateUtil.dateAndTimeString(t.date)); 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"); holder.carbs.setText(DecimalFormatter.to0Decimal(t.carbs) + " g");
Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia()); Iob iob = t.iobCalc(System.currentTimeMillis(), profile.getDia());
holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U"); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iobContrib) + " U");
@ -176,7 +176,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
llm = new LinearLayoutManager(view.getContext()); llm = new LinearLayoutManager(view.getContext());
recyclerView.setLayoutManager(llm); recyclerView.setLayoutManager(llm);
RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.treatments); RecyclerViewAdapter adapter = new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory());
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal); iobTotal = (TextView) view.findViewById(R.id.treatments_iobtotal);
@ -232,7 +232,7 @@ public class TreatmentsBolusFragment extends SubscriberFragment implements View.
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {
recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.treatments), false); recyclerView.swapAdapter(new RecyclerViewAdapter(TreatmentsPlugin.getPlugin().getTreatmentsFromHistory()), false);
if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) { if (TreatmentsPlugin.getPlugin().getLastCalculationTreatments() != null) {
iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U"); iobTotal.setText(DecimalFormatter.to2Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().iob) + " U");
activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U"); activityTotal.setText(DecimalFormatter.to3Decimal(TreatmentsPlugin.getPlugin().getLastCalculationTreatments().activity) + " U");

View file

@ -80,7 +80,7 @@ public class TreatmentsExtendedBolusesFragment extends SubscriberFragment {
holder.date.setText(DateUtil.dateAndTimeString(extendedBolus.date) + " - " + DateUtil.timeString(extendedBolus.end())); holder.date.setText(DateUtil.dateAndTimeString(extendedBolus.date) + " - " + DateUtil.timeString(extendedBolus.end()));
} }
holder.duration.setText(DecimalFormatter.to0Decimal(extendedBolus.durationInMinutes) + " min"); 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"); holder.realDuration.setText(DecimalFormatter.to0Decimal(extendedBolus.getRealDuration()) + " min");
IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis()); IobTotal iob = extendedBolus.iobCalc(System.currentTimeMillis());
holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U"); holder.iob.setText(DecimalFormatter.to2Decimal(iob.iob) + " U");

View file

@ -100,7 +100,11 @@ public class TreatmentsTemporaryBasalsFragment extends SubscriberFragment {
holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%"); holder.percent.setText(DecimalFormatter.to0Decimal(tempBasal.percentRate) + "%");
} }
holder.realDuration.setText(DecimalFormatter.to0Decimal(tempBasal.getRealDuration()) + " min"); 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.iob.setText(DecimalFormatter.to2Decimal(iob.basaliob) + " U");
holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U"); holder.netInsulin.setText(DecimalFormatter.to2Decimal(iob.netInsulin) + " U");
holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h"); holder.netRatio.setText(DecimalFormatter.to2Decimal(iob.netRatio) + " U/h");

View file

@ -604,17 +604,15 @@ public class ActionStringHandler {
} }
private static void generateTempTarget(int duration, double low, double high) { private static void generateTempTarget(int duration, double low, double high) {
TempTarget tempTarget = new TempTarget(); TempTarget tempTarget = new TempTarget()
tempTarget.date = System.currentTimeMillis(); .date(System.currentTimeMillis())
tempTarget.durationInMinutes = duration; .duration(duration)
tempTarget.reason = "WearPlugin"; .reason("WearPlugin")
tempTarget.source = Source.USER; .source(Source.USER);
if (tempTarget.durationInMinutes != 0) { if (tempTarget.durationInMinutes != 0) {
tempTarget.low = low; tempTarget.low(low).high(high);
tempTarget.high = high;
} else { } else {
tempTarget.low = 0; tempTarget.low(0).high(0);
tempTarget.high = 0;
} }
MainApp.getDbHelper().createOrUpdate(tempTarget); MainApp.getDbHelper().createOrUpdate(tempTarget);

View file

@ -159,5 +159,8 @@ public class DateUtil {
return timeFrameString(timestamp - System.currentTimeMillis()); return timeFrameString(timestamp - System.currentTimeMillis());
} }
public static long now() {
return System.currentTimeMillis();
}
} }

View file

@ -2,6 +2,8 @@ package info.nightscout.utils;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
/** /**
* Created by mike on 11.07.2016. * Created by mike on 11.07.2016.
*/ */
@ -26,4 +28,16 @@ public class DecimalFormatter {
public static String to3Decimal(double value) { public static String to3Decimal(double value) {
return format3dec.format(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");
}
} }

View file

@ -140,7 +140,7 @@ public class NSUpload {
data.put("splitNow", 0); data.put("splitNow", 0);
data.put("splitExt", 100); data.put("splitExt", 100);
data.put("enteredinsulin", extendedBolus.insulin); data.put("enteredinsulin", extendedBolus.insulin);
data.put("relative", extendedBolus.insulin); data.put("relative", extendedBolus.insulin / extendedBolus.durationInMinutes * 60); // U/h
if (extendedBolus.pumpId != 0) if (extendedBolus.pumpId != 0)
data.put("pumpId", extendedBolus.pumpId); data.put("pumpId", extendedBolus.pumpId);
data.put("created_at", DateUtil.toISOString(extendedBolus.date)); 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) { public static void removeFoodFromNS(String _id) {
try { try {
Context context = MainApp.instance().getApplicationContext(); Context context = MainApp.instance().getApplicationContext();

View file

@ -61,4 +61,19 @@ public class OKDialog {
log.debug("show_dialog exception: " + e); 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();
}
} }

View file

@ -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;
}
}

View file

@ -1,110 +1,97 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:focusableInTouchMode="true" xmlns:android="http://schemas.android.com/apk/res/android">
android:orientation="vertical"
android:padding="10dp">
<LinearLayout <LinearLayout
android:id="@+id/careportal_newnstreatment_insulin_layout" android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="vertical"
android:focusableInTouchMode="true"
android:padding="10dp">
<TextView <TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:width="120dp" android:padding="5dp"
android:padding="10dp" android:text="@string/primefill"
android:text="@string/treatments_newtreatment_insulinamount_label" android:textAppearance="?android:attr/textAppearanceLarge"
android:textAppearance="@android:style/TextAppearance.Material.Small" android:textColor="@color/colorInsulinButton" />
android:textStyle="bold" />
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:padding="5dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/icon_cp_pump_canula" />
<LinearLayout
android:id="@+id/careportal_newnstreatment_insulin_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical">
<CheckBox
android:id="@+id/catheter_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:text="Pump site change" />
<CheckBox
android:id="@+id/cartridge_change"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="5dp"
android:text="Insulin cartridge change" />
<info.nightscout.utils.NumberPicker <info.nightscout.utils.NumberPicker
android:id="@+id/treatments_newtreatment_insulinamount" android:id="@+id/treatments_newtreatment_insulinamount"
android:layout_width="130dp" android:layout_width="130dp"
android:layout_height="40dp" /> android:layout_height="40dp"
android:layout_gravity="end"
<TextView android:layout_marginBottom="10dp"
android:layout_width="wrap_content" android:layout_marginLeft="30dp"
android:layout_height="wrap_content" android:layout_marginRight="30dp"
android:layout_gravity="center_vertical" android:layout_marginTop="10dp" />
android:gravity="left"
android:minWidth="45dp"
android:paddingLeft="5dp"
android:text="U"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginLeft="20dp" android:layout_marginTop="5dp">
android:layout_marginRight="20dp"
android:orientation="horizontal"
android:padding="10dp">
<Button
android:id="@+id/treatments_newtreatment_deliverbutton"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="10dp"
android:text="@string/primefill"
android:textSize="20sp" />
</LinearLayout>
<View
android:id="@+id/fill_preset_divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:orientation="horizontal"
android:padding="10dp"
android:gravity="center_horizontal"
android:layout_gravity="center_horizontal">
<Button <Button
android:id="@+id/fill_preset_button1" android:id="@+id/fill_preset_button1"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="0.3" android:layout_weight="1"
android:padding="10dp" android:text="0.3U" />
android:text="0.3U"
android:textSize="20sp" />
<Button <Button
android:id="@+id/fill_preset_button2" android:id="@+id/fill_preset_button2"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="0.3" android:layout_weight="1"
android:padding="10dp" android:text="0.7U" />
android:text="0.7U"
android:textSize="20sp" />
<Button <Button
android:id="@+id/fill_preset_button3" android:id="@+id/fill_preset_button3"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="0.3" android:layout_weight="1"
android:padding="10dp" android:text="1.2U" />
android:text="1.2U"
android:textSize="20sp" />
</LinearLayout>
<include layout="@layout/mdtp_done_button" />
</LinearLayout> </LinearLayout>
</LinearLayout> </ScrollView>

View file

@ -101,7 +101,7 @@
android:layout_marginRight="10dp" android:layout_marginRight="10dp"
android:layout_marginTop="3dp" android:layout_marginTop="3dp"
android:layout_weight="0.5" android:layout_weight="0.5"
android:drawableTop="@drawable/icon_actions_refill" android:drawableTop="@drawable/icon_cp_pump_canula"
android:text="@string/primefill" /> android:text="@string/primefill" />
</LinearLayout> </LinearLayout>

View file

@ -14,4 +14,14 @@
layout="@layout/profileviewer_fragment" layout="@layout/profileviewer_fragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Button
android:id="@+id/nsprofile_profileswitch"
style="?android:attr/buttonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/activate_profile"
android:textColor="@color/colorProfileSwitchButton" />
</LinearLayout> </LinearLayout>

View file

@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -11,7 +9,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusableInTouchMode="true" android:focusableInTouchMode="true"

View file

@ -990,5 +990,9 @@
<string name="unsafeusage">unsafe usage</string> <string name="unsafeusage">unsafe usage</string>
<string name="key_openapsama_useautosens" translatable="false">openapsama_useautosens</string> <string name="key_openapsama_useautosens" translatable="false">openapsama_useautosens</string>
<string name="readstatusfailed">Read status failed</string> <string name="readstatusfailed">Read status failed</string>
<string name="record_pump_site_change">Record pump site change</string>
<string name="record_insulin_cartridge_change">Record insulin cartridge change</string>
<string name="smbalwaysdisabled">SMB always and after carbs disabled because active BG source doesn\'t support advanced filtering</string>
<string name="smbnotallowedinopenloopmode">SMB not allowed in open loop mode</string>
</resources> </resources>

View file

@ -13,7 +13,9 @@ import java.util.Locale;
import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.ConstraintChecker;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
@ -56,6 +58,14 @@ public class AAPSMocker {
when(MainApp.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable"); when(MainApp.gs(R.string.pumpisnottempbasalcapable)).thenReturn("Pump is not temp basal capable");
when(MainApp.gs(R.string.loop)).thenReturn("Loop"); when(MainApp.gs(R.string.loop)).thenReturn("Loop");
when(MainApp.gs(R.string.loop_shortname)).thenReturn("LOOP"); when(MainApp.gs(R.string.loop_shortname)).thenReturn("LOOP");
when(MainApp.gs(R.string.smbalwaysdisabled)).thenReturn("SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering");
when(MainApp.gs(R.string.smbnotallowedinopenloopmode)).thenReturn("SMB not allowed in open loop mode");
when(MainApp.gs(R.string.Glimp)).thenReturn("Glimp");
when(MainApp.gs(R.string.glucose)).thenReturn("Glucose");
when(MainApp.gs(R.string.delta)).thenReturn("Delta");
when(MainApp.gs(R.string.short_avgdelta)).thenReturn("Short avg. delta");
when(MainApp.gs(R.string.long_avgdelta)).thenReturn("Long avg. delta");
when(MainApp.gs(R.string.zerovalueinprofile)).thenReturn("Invalid profile: %s");
} }
public static MainApp mockMainApp() { public static MainApp mockMainApp() {
@ -71,6 +81,11 @@ public class AAPSMocker {
when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin); when(MainApp.getConfigBuilder()).thenReturn(configBuilderPlugin);
} }
public static void mockConstraintsChecker() {
ConstraintChecker constraintChecker = mock(ConstraintChecker.class);
when(MainApp.getConstraintChecker()).thenReturn(constraintChecker);
}
public static void mockBus() { public static void mockBus() {
Bus bus = PowerMockito.mock(Bus.class); Bus bus = PowerMockito.mock(Bus.class);
when(MainApp.bus()).thenReturn(bus); when(MainApp.bus()).thenReturn(bus);
@ -88,9 +103,16 @@ public class AAPSMocker {
when(MainApp.instance().getApplicationContext()).thenReturn(context); when(MainApp.instance().getApplicationContext()).thenReturn(context);
} }
public static Profile getValidProfile() throws JSONException { public static void mockDatabaseHelper() {
DatabaseHelper databaseHelper = mock(DatabaseHelper.class);
when(MainApp.getDbHelper()).thenReturn(databaseHelper);
}
public static Profile getValidProfile() {
try {
if (profile == null) if (profile == null)
profile = new Profile(new JSONObject(validProfile), Constants.MGDL); profile = new Profile(new JSONObject(validProfile), Constants.MGDL);
} catch (JSONException e) {}
return profile; return profile;
} }
} }

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.data;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class DetailedBolusInfoTest {
@Test
public void toStringShouldBeOverloaded() {
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
Assert.assertEquals(true, detailedBolusInfo.toString().contains("insulin"));
}
@Test
public void copyShouldCopyAllProperties() {
DetailedBolusInfo d1 = new DetailedBolusInfo();
d1.deliverAt = 123;
DetailedBolusInfo d2 = d1.copy();
Assert.assertEquals(true, EqualsBuilder.reflectionEquals(d2, d1));
}
}

View file

@ -0,0 +1,184 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.BgReading;
import info.nightscout.androidaps.db.DatabaseHelper;
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.powermock.api.mockito.PowerMockito.when;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, DatabaseHelper.class, DateUtil.class})
public class GlucoseStatusTest {
@Test
public void toStringShouldBeOverloaded() {
GlucoseStatus glucoseStatus = new GlucoseStatus();
Assert.assertEquals(true, glucoseStatus.toString().contains("Delta"));
}
@Test
public void roundtest() {
GlucoseStatus glucoseStatus = new GlucoseStatus();
glucoseStatus.glucose = 100.11111;
Assert.assertEquals(100.1, glucoseStatus.round().glucose, 0.0001);
}
@Test
public void calculateValidGlucoseStatus() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateValidBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(214d, glucoseStatus.glucose, 0.001d);
Assert.assertEquals(-2d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(-2.5d, glucoseStatus.short_avgdelta, 0.001d); // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(-2.5d, glucoseStatus.avgdelta, 0.001d); // the same as short_avgdelta
Assert.assertEquals(-2d, glucoseStatus.long_avgdelta, 0.001d); // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date); // latest date
}
@Test
public void calculateMostRecentGlucoseStatus() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateMostRecentBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(215d, glucoseStatus.glucose, 0.001d); // (214+216) / 2
Assert.assertEquals(-1.25d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(-1.25d, glucoseStatus.short_avgdelta, 0.001d);
Assert.assertEquals(-1.25d, glucoseStatus.avgdelta, 0.001d);
Assert.assertEquals(0d, glucoseStatus.long_avgdelta, 0.001d);
Assert.assertEquals(1514766850000L, glucoseStatus.date); // date is average too
}
@Test
public void oneRecordShouldProduceZeroDeltas() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOneCurrentRecordBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(214d, glucoseStatus.glucose, 0.001d);
Assert.assertEquals(0d, glucoseStatus.delta, 0.001d);
Assert.assertEquals(0d, glucoseStatus.short_avgdelta, 0.001d); // -2 -2.5 -3 deltas are relative to current value
Assert.assertEquals(0d, glucoseStatus.avgdelta, 0.001d); // the same as short_avgdelta
Assert.assertEquals(0d, glucoseStatus.long_avgdelta, 0.001d); // -2 -2 -2 -2
Assert.assertEquals(1514766900000L, glucoseStatus.date); // latest date
}
@Test
public void insuffientDataShouldReturnNull() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateInsufficientBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(null, glucoseStatus);
}
@Test
public void oldDataShouldReturnNull() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOldBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
Assert.assertEquals(null, glucoseStatus);
}
@Test
public void returnOldDataIfAllowed() {
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOldBgData());
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(true);
Assert.assertNotEquals(null, glucoseStatus);
}
@Test
public void averageShouldNotFailOnEmptyArray() {
Assert.assertEquals(0d, GlucoseStatus.average(new ArrayList<>()), 0.001d);
}
@Before
public void initMocking() {
AAPSMocker.mockMainApp();
AAPSMocker.mockStrings();
AAPSMocker.mockDatabaseHelper();
PowerMockito.mockStatic(DateUtil.class);
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
}
// [{"mgdl":214,"mills":1521895773113,"device":"xDrip-DexcomG5","direction":"Flat","filtered":191040,"unfiltered":205024,"noise":1,"rssi":100},{"mgdl":219,"mills":1521896073352,"device":"xDrip-DexcomG5","direction":"Flat","filtered":200160,"unfiltered":209760,"noise":1,"rssi":100},{"mgdl":222,"mills":1521896372890,"device":"xDrip-DexcomG5","direction":"Flat","filtered":207360,"unfiltered":212512,"noise":1,"rssi":100},{"mgdl":220,"mills":1521896673062,"device":"xDrip-DexcomG5","direction":"Flat","filtered":211488,"unfiltered":210688,"noise":1,"rssi":100},{"mgdl":193,"mills":1521896972933,"device":"xDrip-DexcomG5","direction":"Flat","filtered":212384,"unfiltered":208960,"noise":1,"rssi":100},{"mgdl":181,"mills":1521897273336,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":210592,"unfiltered":204320,"noise":1,"rssi":100},{"mgdl":176,"mills":1521897572875,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":206720,"unfiltered":197440,"noise":1,"rssi":100},{"mgdl":168,"mills":1521897872929,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":201024,"unfiltered":187904,"noise":1,"rssi":100},{"mgdl":161,"mills":1521898172814,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":193376,"unfiltered":178144,"noise":1,"rssi":100},{"mgdl":148,"mills":1521898472879,"device":"xDrip-DexcomG5","direction":"SingleDown","filtered":183264,"unfiltered":161216,"noise":1,"rssi":100},{"mgdl":139,"mills":1521898772862,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":170784,"unfiltered":148928,"noise":1,"rssi":100},{"mgdl":132,"mills":1521899072896,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":157248,"unfiltered":139552,"noise":1,"rssi":100},{"mgdl":125,"mills":1521899372834,"device":"xDrip-DexcomG5","direction":"FortyFiveDown","filtered":144416,"unfiltered":129616.00000000001,"noise":1,"rssi":100},{"mgdl":128,"mills":1521899973456,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130240.00000000001,"unfiltered":133536,"noise":1,"rssi":100},{"mgdl":132,"mills":1521900573287,"device":"xDrip-DexcomG5","direction":"Flat","filtered":133504,"unfiltered":138720,"noise":1,"rssi":100},{"mgdl":127,"mills":1521900873711,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136480,"unfiltered":132992,"noise":1,"rssi":100},{"mgdl":127,"mills":1521901180151,"device":"xDrip-DexcomG5","direction":"Flat","filtered":136896,"unfiltered":132128,"noise":1,"rssi":100},{"mgdl":125,"mills":1521901473582,"device":"xDrip-DexcomG5","direction":"Flat","filtered":134624,"unfiltered":129696,"noise":1,"rssi":100},{"mgdl":120,"mills":1521901773597,"device":"xDrip-DexcomG5","direction":"Flat","filtered":130704.00000000001,"unfiltered":123376,"noise":1,"rssi":100},{"mgdl":116,"mills":1521902075855,"device":"xDrip-DexcomG5","direction":"Flat","filtered":126272,"unfiltered":118448,"noise":1,"rssi":100}]
List<BgReading> generateValidBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}")))); // +2
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":219,\"mills\":1514766300000,\"direction\":\"Flat\"}")))); // +3
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":223,\"mills\":1514766000000,\"direction\":\"Flat\"}")))); // +4
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":222,\"mills\":1514765700000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":224,\"mills\":1514765400000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateMostRecentBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766800000,\"direction\":\"Flat\"}")))); // +2
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateInsufficientBgData() {
List<BgReading> list = new ArrayList<>();
return list;
}
List<BgReading> generateOldBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
List<BgReading> generateOneCurrentRecordBgData() {
List<BgReading> list = new ArrayList<>();
try {
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
} catch (JSONException e) {
e.printStackTrace();
}
return list;
}
}

View file

@ -0,0 +1,41 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 27.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class IobTest {
@Test
public void plusTest() {
Iob a = new Iob().iobContrib(1).activityContrib(2);
Iob b = new Iob().iobContrib(3).activityContrib(4);
a.plus(b);
Assert.assertEquals(4d, a.iobContrib, 0.01d);
Assert.assertEquals(6d, a.activityContrib, 0.01d);
}
@Test
public void equalTest() {
Iob a1 = new Iob().iobContrib(1).activityContrib(2);
Iob a2 = new Iob().iobContrib(1).activityContrib(2);
Iob b = new Iob().iobContrib(3).activityContrib(4);
Assert.assertEquals(true, a1.equals(a1));
Assert.assertEquals(true, a1.equals(a2));
Assert.assertEquals(false, a1.equals(b));
Assert.assertEquals(false, a1.equals(null));
Assert.assertEquals(false, a1.equals(new Object()));
}
@Test
public void hashCodeTest() {
Iob a = new Iob().iobContrib(1).activityContrib(2);
Assert.assertNotEquals(0, a.hashCode());
}
}

View file

@ -0,0 +1,144 @@
package info.nightscout.androidaps.data;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.utils.DateUtil;
/**
* Created by mike on 27.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class IobTotalTest {
long now = DateUtil.now();
@Test
public void copytest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
IobTotal b = a.copy();
Assert.assertEquals(a.iob, b.iob, 0.01d);
}
@Test
public void plusTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 10;
a.bolussnooze = 10;
a.basaliob = 10;
a.netbasalinsulin = 10;
a.hightempinsulin = 10;
a.netInsulin = 10;
a.extendedBolusInsulin = 10;
a.plus(a.copy());
Assert.assertEquals(20, a.iob, 0.01d);
Assert.assertEquals(20, a.activity, 0.01d);
Assert.assertEquals(20, a.bolussnooze, 0.01d);
Assert.assertEquals(20, a.basaliob, 0.01d);
Assert.assertEquals(20, a.netbasalinsulin, 0.01d);
Assert.assertEquals(20, a.hightempinsulin, 0.01d);
Assert.assertEquals(20, a.netInsulin, 0.01d);
Assert.assertEquals(20, a.extendedBolusInsulin, 0.01d);
}
@Test
public void combineTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
IobTotal b = a.copy();
IobTotal c = IobTotal.combine(a, b);
Assert.assertEquals(a.time, c.time, 0.01d);
Assert.assertEquals(23, c.iob, 0.01d);
Assert.assertEquals(22, c.activity, 0.01d);
Assert.assertEquals(12, c.bolussnooze, 0.01d);
Assert.assertEquals(26, c.basaliob, 0.01d);
Assert.assertEquals(28, c.netbasalinsulin, 0.01d);
Assert.assertEquals(30, c.hightempinsulin, 0.01d);
Assert.assertEquals(32, c.netInsulin, 0.01d);
Assert.assertEquals(34, c.extendedBolusInsulin, 0.01d);
}
@Test
public void roundTest() {
IobTotal a = new IobTotal(now);
a.iob = 1.1111111111111;
a.activity = 1.1111111111111;
a.bolussnooze = 1.1111111111111;
a.basaliob = 1.1111111111111;
a.netbasalinsulin = 1.1111111111111;
a.hightempinsulin = 1.1111111111111;
a.netInsulin = 1.1111111111111;
a.extendedBolusInsulin = 1.1111111111111;
a.round();
Assert.assertEquals(1.111d, a.iob, 0.00001d);
Assert.assertEquals(1.1111d, a.activity, 0.00001d);
Assert.assertEquals(1.1111d, a.bolussnooze, 0.00001d);
Assert.assertEquals(1.111d, a.basaliob, 0.00001d);
Assert.assertEquals(1.111d, a.netbasalinsulin, 0.00001d);
Assert.assertEquals(1.111d, a.hightempinsulin, 0.00001d);
Assert.assertEquals(1.111d, a.netInsulin, 0.00001d);
Assert.assertEquals(1.111d, a.extendedBolusInsulin, 0.00001d);
}
@Test
public void jsonTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
try {
JSONObject j = a.json();
Assert.assertEquals(a.iob, j.getDouble("iob"), 0.0000001d);
Assert.assertEquals(a.basaliob, j.getDouble("basaliob"), 0.0000001d);
Assert.assertEquals(a.activity, j.getDouble("activity"), 0.0000001d);
Assert.assertEquals(now, DateUtil.fromISODateString(j.getString("time")).getTime(), 1000);
} catch (Exception e) {
Assert.fail("Exception: " + e.getMessage());
}
}
@Test
public void determineBasalJsonTest() {
IobTotal a = new IobTotal(now);
a.iob = 10;
a.activity = 11;
a.bolussnooze = 12;
a.basaliob = 13;
a.netbasalinsulin = 14;
a.hightempinsulin = 15;
a.netInsulin = 16;
a.extendedBolusInsulin = 17;
a.iobWithZeroTemp = new IobTotal(now);
try {
JSONObject j = a.determineBasalJson();
Assert.assertEquals(a.iob, j.getDouble("iob"), 0.0000001d);
Assert.assertEquals(a.basaliob, j.getDouble("basaliob"), 0.0000001d);
Assert.assertEquals(a.bolussnooze, j.getDouble("bolussnooze"), 0.0000001d);
Assert.assertEquals(a.activity, j.getDouble("activity"), 0.0000001d);
Assert.assertEquals(0, j.getLong("lastBolusTime"));
Assert.assertEquals(now, DateUtil.fromISODateString(j.getString("time")).getTime(), 1000);
Assert.assertNotNull(j.getJSONObject("iobWithZeroTemp"));
} catch (Exception e) {
Assert.fail("Exception: " + e.getMessage());
}
}
}

View file

@ -0,0 +1,18 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class MealDataTest {
@Test
public void canCreateObject() {
MealData md = new MealData();
Assert.assertEquals(0d, md.boluses, 0.01d);
}
}

View file

@ -0,0 +1,58 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class NonOverapingIntervalsTest {
private final long startDate = DateUtil.now();
NonOverlappingIntervals<TemporaryBasal> list = new NonOverlappingIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new TemporaryBasal().date(startDate).duration((int) T.hours(10).mins()).absolute(1));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// stop temp after 5h
list.add(new TemporaryBasal().date(startDate + T.hours(5).msecs()).duration(0));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(1d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// insert 1h interval inside
list.add(new TemporaryBasal().date(startDate + T.hours(3).msecs()).duration((int) T.hours(1).mins()).absolute(2));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(1d, list.getValueByInterval(startDate).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() - 1));
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(3).msecs()).absoluteRate, 0.01d);
Assert.assertEquals(2d, list.getValueByInterval(startDate + T.hours(4).msecs() - 1).absoluteRate, 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(4).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new TemporaryBasal().date(startDate).duration((int) T.hours(10).mins()).absolute(1));
NonOverlappingIntervals<TemporaryBasal> list2 = new NonOverlappingIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
}

View file

@ -0,0 +1,72 @@
package info.nightscout.androidaps.data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class OverapingIntervalsTest {
private final long startDate = DateUtil.now();
OverlappingIntervals<TempTarget> list = new OverlappingIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new TempTarget().date(startDate).duration((int) T.hours(10).mins()).low(100).high(100));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// stop temp target after 5h
list.add(new TempTarget().date(startDate + T.hours(5).msecs()).duration(0));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
// insert 1h interval inside
list.add(new TempTarget().date(startDate + T.hours(3).msecs()).duration((int) T.hours(1).mins()).low(200).high(200));
Assert.assertEquals(null, list.getValueByInterval(startDate - T.secs(1).msecs()));
Assert.assertEquals(100d, list.getValueByInterval(startDate).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(5).msecs() - 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(5).msecs() + 1));
Assert.assertEquals(200d, list.getValueByInterval(startDate + T.hours(3).msecs()).target(), 0.01d);
Assert.assertEquals(100d, list.getValueByInterval(startDate + T.hours(4).msecs() + 1).target(), 0.01d);
Assert.assertEquals(null, list.getValueByInterval(startDate + T.hours(10).msecs() + 1));
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new TempTarget().date(startDate).duration((int) T.hours(10).mins()).low(100).high(100));
OverlappingIntervals<TempTarget> list2 = new OverlappingIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
@Test
public void testReversingArrays() {
List<TempTarget> someList = new ArrayList<>();
someList.add(new TempTarget().date(startDate).duration((int) T.hours(3).mins()).low(200).high(200));
someList.add(new TempTarget().date(startDate + T.hours(1).msecs()).duration((int) T.hours(1).mins()).low(100).high(100));
list.reset();
list.add(someList);
Assert.assertEquals(startDate, list.get(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversedList().get(0).date);
}
}

View file

@ -0,0 +1,93 @@
package info.nightscout.androidaps.data;
import com.squareup.otto.Bus;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.util.ArrayList;
import java.util.List;
import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.db.ProfileSwitch;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.T;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, Bus.class})
public class ProfileIntervalsTest {
private final long startDate = DateUtil.now();
ProfileIntervals<ProfileSwitch> list = new ProfileIntervals<>();
@Test
public void doTests() {
// create one 10h interval and test value in and out
list.add(new ProfileSwitch().date(startDate).duration((int) T.hours(10).mins()).profileName("1").profile(AAPSMocker.getValidProfile()));
// for older date first record should be returned only if has zero duration
Assert.assertEquals(null, list.getValueToTime(startDate - T.secs(1).msecs()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate)).profileName);
Assert.assertEquals(null, list.getValueToTime(startDate + T.hours(10).msecs() + 1));
list.reset();
list.add(new ProfileSwitch().date(startDate).profileName("1").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate - T.secs(1).msecs())).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate)).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(10).msecs() + 1)).profileName);
// switch to different profile after 5h
list.add(new ProfileSwitch().date(startDate + T.hours(5).msecs()).duration(0).profileName("2").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate - T.secs(1).msecs())).profileName);
Assert.assertEquals("1", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(5).msecs() - 1)).profileName);
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(5).msecs() + 1)).profileName);
// insert 1h interval inside
list.add(new ProfileSwitch().date(startDate + T.hours(6).msecs()).duration((int) T.hours(1).mins()).profileName("3").profile(AAPSMocker.getValidProfile()));
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(6).msecs() - 1)).profileName);
Assert.assertEquals("3", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(6).msecs() + 1)).profileName);
Assert.assertEquals("2", ((ProfileSwitch) list.getValueToTime(startDate + T.hours(7).msecs() + 1)).profileName);
}
@Test
public void testCopyConstructor() {
list.reset();
list.add(new ProfileSwitch().date(startDate).duration((int) T.hours(10).mins()).profileName("4").profile(AAPSMocker.getValidProfile()));
ProfileIntervals<ProfileSwitch> list2 = new ProfileIntervals<>(list);
Assert.assertEquals(1, list2.getList().size());
}
@Test
public void invalidProfilesShouldNotBeReturned() {
list.reset();
list.add(new ProfileSwitch().date(startDate + T.hours(1).msecs()).profileName("6"));
Assert.assertEquals(null, list.get(0));
}
@Test
public void testReversingArrays() {
List<ProfileSwitch> someList = new ArrayList<>();
someList.add(new ProfileSwitch().date(startDate).duration((int) T.hours(3).mins()).profileName("5").profile(AAPSMocker.getValidProfile()));
someList.add(new ProfileSwitch().date(startDate + T.hours(1).msecs()).duration((int) T.hours(1).mins()).profileName("6").profile(AAPSMocker.getValidProfile()));
list.reset();
list.add(someList);
Assert.assertEquals(startDate, list.get(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date);
Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversedList().get(0).date);
}
@Before
public void prepareMock() {
AAPSMocker.mockMainApp();
AAPSMocker.mockStrings();
AAPSMocker.mockBus();
}
}

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.PumpDanaRS.DanaRSPlugin;
import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin; import info.nightscout.androidaps.plugins.PumpInsight.InsightPlugin;
import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner; import info.nightscout.androidaps.plugins.PumpInsight.connector.StatusTaskRunner;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
import info.nightscout.utils.FabricPrivacy; import info.nightscout.utils.FabricPrivacy;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
@ -110,10 +111,21 @@ public class ConstraintsCheckerTest {
Assert.assertEquals(Boolean.FALSE, c.value()); Assert.assertEquals(Boolean.FALSE, c.value());
} }
@Test
public void isAdvancedFilteringEnabledTest() throws Exception {
when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin());
Constraint<Boolean> c = constraintChecker.isAdvancedFilteringEnabled();
Assert.assertEquals(true, c.getReasonList().size() == 1); // Safety
Assert.assertEquals(true, c.getMostLimitedReasonList().size() == 1); // Safety
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test @Test
public void isSMBModeEnabledTest() throws Exception { public void isSMBModeEnabledTest() throws Exception {
objectivesPlugin.objectives.get(7).setStarted(new Date(0)); objectivesPlugin.objectives.get(7).setStarted(new Date(0));
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false); when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true));
Constraint<Boolean> c = constraintChecker.isSMBModeEnabled(); Constraint<Boolean> c = constraintChecker.isSMBModeEnabled();
Assert.assertEquals(true, c.getReasonList().size() == 2); // Safety & Objectives Assert.assertEquals(true, c.getReasonList().size() == 2); // Safety & Objectives
@ -240,6 +252,7 @@ public class ConstraintsCheckerTest {
MainApp mainApp = AAPSMocker.mockMainApp(); MainApp mainApp = AAPSMocker.mockMainApp();
AAPSMocker.mockConfigBuilder(); AAPSMocker.mockConfigBuilder();
AAPSMocker.mockConstraintsChecker();
AAPSMocker.mockApplicationContext(); AAPSMocker.mockApplicationContext();
AAPSMocker.mockBus(); AAPSMocker.mockBus();
AAPSMocker.mockStrings(); AAPSMocker.mockStrings();

View file

@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.OpenAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.OpenAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.OpenAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.PumpVirtual.VirtualPumpPlugin;
import info.nightscout.androidaps.plugins.SourceGlimp.SourceGlimpPlugin;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -70,6 +71,7 @@ public class SafetyPluginTest {
@Test @Test
public void notEnabledSMBInPreferencesDisablesSMB() throws Exception { public void notEnabledSMBInPreferencesDisablesSMB() throws Exception {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false); when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(false);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(true));
Constraint<Boolean> c = new Constraint<>(true); Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c); c = safetyPlugin.isSMBModeEnabled(c);
@ -77,6 +79,27 @@ public class SafetyPluginTest {
Assert.assertEquals(Boolean.FALSE, c.value()); Assert.assertEquals(Boolean.FALSE, c.value());
} }
@Test
public void openLoopPreventsSMB() throws Exception {
when(SP.getBoolean(R.string.key_use_smb, false)).thenReturn(true);
when(MainApp.getConstraintChecker().isClosedLoopAllowed()).thenReturn(new Constraint<>(false));
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isSMBModeEnabled(c);
Assert.assertEquals(true, c.getReasons().contains("SMB not allowed in open loop mode"));
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test
public void bgsourceShouldPreventSMBAlways() throws Exception {
when(MainApp.getConfigBuilder().getActiveBgSource()).thenReturn(SourceGlimpPlugin.getPlugin());
Constraint<Boolean> c = new Constraint<>(true);
c = safetyPlugin.isAdvancedFilteringEnabled(c);
Assert.assertEquals("Safety: SMB always and after carbs disabled because active BG source doesn\\'t support advanced filtering", c.getReasons());
Assert.assertEquals(Boolean.FALSE, c.value());
}
@Test @Test
public void basalRateShouldBeLimited() throws Exception { public void basalRateShouldBeLimited() throws Exception {
when(SP.getDouble(R.string.key_openapsma_max_basal, 1d)).thenReturn(1d); when(SP.getDouble(R.string.key_openapsma_max_basal, 1d)).thenReturn(1d);
@ -204,9 +227,12 @@ public class SafetyPluginTest {
public void prepareMock() { public void prepareMock() {
AAPSMocker.mockMainApp(); AAPSMocker.mockMainApp();
AAPSMocker.mockConfigBuilder(); AAPSMocker.mockConfigBuilder();
AAPSMocker.mockConstraintsChecker();
AAPSMocker.mockSP(); AAPSMocker.mockSP();
AAPSMocker.mockStrings(); AAPSMocker.mockStrings();
when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump); when(MainApp.getConfigBuilder().getActivePump()).thenReturn(pump);
safetyPlugin = SafetyPlugin.getPlugin(); safetyPlugin = SafetyPlugin.getPlugin();

View file

@ -0,0 +1,24 @@
package info.nightscout.utils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;
/**
* Created by mike on 26.03.2018.
*/
@RunWith(PowerMockRunner.class)
public class TTest {
@Test
public void doTests() {
Assert.assertEquals(1, T.msecs(1000).secs());
Assert.assertEquals(1, T.secs(60).mins());
Assert.assertEquals(1, T.mins(60).hours());
Assert.assertEquals(1, T.hours(24).days());
Assert.assertEquals(24, T.days(1).hours());
Assert.assertEquals(60000, T.mins(1).msecs());
}
}