commit
f1acf6449a
BIN
app/jacoco.exec
BIN
app/jacoco.exec
Binary file not shown.
|
@ -18,6 +18,9 @@ import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.android.AndroidInjector;
|
import dagger.android.AndroidInjector;
|
||||||
import dagger.android.DaggerApplication;
|
import dagger.android.DaggerApplication;
|
||||||
|
import info.nightscout.androidaps.database.AppRepository;
|
||||||
|
import info.nightscout.androidaps.database.transactions.VersionChangeTransaction;
|
||||||
|
import info.nightscout.androidaps.db.CompatDBHelper;
|
||||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
import info.nightscout.androidaps.db.StaticInjector;
|
import info.nightscout.androidaps.db.StaticInjector;
|
||||||
import info.nightscout.androidaps.dependencyInjection.DaggerAppComponent;
|
import info.nightscout.androidaps.dependencyInjection.DaggerAppComponent;
|
||||||
|
@ -38,11 +41,14 @@ import info.nightscout.androidaps.services.Intents;
|
||||||
import info.nightscout.androidaps.utils.ActivityMonitor;
|
import info.nightscout.androidaps.utils.ActivityMonitor;
|
||||||
import info.nightscout.androidaps.utils.locale.LocaleHelper;
|
import info.nightscout.androidaps.utils.locale.LocaleHelper;
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
|
||||||
public class MainApp extends DaggerApplication {
|
public class MainApp extends DaggerApplication {
|
||||||
|
|
||||||
static DatabaseHelper sDatabaseHelper = null;
|
static DatabaseHelper sDatabaseHelper = null;
|
||||||
|
|
||||||
|
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||||
|
|
||||||
@Inject PluginStore pluginStore;
|
@Inject PluginStore pluginStore;
|
||||||
@Inject AAPSLogger aapsLogger;
|
@Inject AAPSLogger aapsLogger;
|
||||||
@Inject ActivityMonitor activityMonitor;
|
@Inject ActivityMonitor activityMonitor;
|
||||||
|
@ -54,6 +60,8 @@ public class MainApp extends DaggerApplication {
|
||||||
@Inject ConfigBuilderPlugin configBuilderPlugin;
|
@Inject ConfigBuilderPlugin configBuilderPlugin;
|
||||||
@Inject KeepAliveReceiver.KeepAliveManager keepAliveManager;
|
@Inject KeepAliveReceiver.KeepAliveManager keepAliveManager;
|
||||||
@Inject List<PluginBase> plugins;
|
@Inject List<PluginBase> plugins;
|
||||||
|
@Inject CompatDBHelper compatDBHelper;
|
||||||
|
@Inject AppRepository repository;
|
||||||
|
|
||||||
@Inject StaticInjector staticInjector; // TODO avoid , here fake only to initialize
|
@Inject StaticInjector staticInjector; // TODO avoid , here fake only to initialize
|
||||||
|
|
||||||
|
@ -73,6 +81,15 @@ public class MainApp extends DaggerApplication {
|
||||||
aapsLogger.error("Uncaught exception crashing app", ex);
|
aapsLogger.error("Uncaught exception crashing app", ex);
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
String gitRemote = BuildConfig.REMOTE;
|
||||||
|
String commitHash = BuildConfig.HEAD;
|
||||||
|
if (gitRemote.contains("NoGitSystemAvailable")) {
|
||||||
|
gitRemote = null;
|
||||||
|
commitHash = null;
|
||||||
|
}
|
||||||
|
disposable.add(repository.runTransaction(new VersionChangeTransaction(BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE, gitRemote, commitHash)).subscribe());
|
||||||
|
disposable.add(compatDBHelper.dbChangeDisposable());
|
||||||
|
|
||||||
registerActivityLifecycleCallbacks(activityMonitor);
|
registerActivityLifecycleCallbacks(activityMonitor);
|
||||||
|
|
||||||
JodaTimeAndroid.init(this);
|
JodaTimeAndroid.init(this);
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
package info.nightscout.androidaps.db
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.entities.TemporaryTarget
|
||||||
|
import info.nightscout.androidaps.database.interfaces.TraceableDBEntry
|
||||||
|
import info.nightscout.androidaps.events.EventNewBG
|
||||||
|
import info.nightscout.androidaps.events.EventTempTargetChange
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData
|
||||||
|
import io.reactivex.disposables.Disposable
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
class CompatDBHelper @Inject constructor(
|
||||||
|
val aapsLogger: AAPSLogger,
|
||||||
|
val repository: AppRepository,
|
||||||
|
val rxBus: RxBusWrapper
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun dbChangeDisposable(): Disposable = repository
|
||||||
|
.changeObservable()
|
||||||
|
.doOnSubscribe {
|
||||||
|
rxBus.send(EventNewBG(null))
|
||||||
|
}
|
||||||
|
.subscribe {
|
||||||
|
it.filterIsInstance<GlucoseValue>().firstOrNull()?.let {
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Firing EventNewHistoryData")
|
||||||
|
rxBus.send(EventNewHistoryData(it.timestamp))
|
||||||
|
}
|
||||||
|
it.filterIsInstance<GlucoseValue>().lastOrNull()?.let {
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg")
|
||||||
|
rxBus.send(EventNewBG(it))
|
||||||
|
}
|
||||||
|
it.filterIsInstance<TemporaryTarget>().firstOrNull()?.let {
|
||||||
|
aapsLogger.debug(LTag.DATABASE, "Firing EventTempTargetChange")
|
||||||
|
rxBus.send(EventTempTargetChange())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -33,13 +33,11 @@ import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.dana.comm.RecordTypes;
|
import info.nightscout.androidaps.dana.comm.RecordTypes;
|
||||||
import info.nightscout.androidaps.data.NonOverlappingIntervals;
|
import info.nightscout.androidaps.data.NonOverlappingIntervals;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
import info.nightscout.androidaps.events.EventCareportalEventChange;
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
import info.nightscout.androidaps.events.EventExtendedBolusChange;
|
||||||
import info.nightscout.androidaps.events.EventNewBG;
|
|
||||||
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
|
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
|
||||||
import info.nightscout.androidaps.events.EventRefreshOverview;
|
import info.nightscout.androidaps.events.EventRefreshOverview;
|
||||||
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
|
import info.nightscout.androidaps.events.EventReloadProfileSwitchData;
|
||||||
|
@ -54,9 +52,7 @@ import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData;
|
|
||||||
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
|
import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryData;
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID;
|
import info.nightscout.androidaps.plugins.pump.insight.database.InsightBolusID;
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.database.InsightHistoryOffset;
|
import info.nightscout.androidaps.plugins.pump.insight.database.InsightHistoryOffset;
|
||||||
|
@ -64,7 +60,6 @@ import info.nightscout.androidaps.plugins.pump.insight.database.InsightPumpID;
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
|
||||||
import info.nightscout.androidaps.utils.JsonHelper;
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
import info.nightscout.androidaps.utils.PercentageSplitter;
|
import info.nightscout.androidaps.utils.PercentageSplitter;
|
||||||
import info.nightscout.androidaps.utils.T;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
|
@ -81,7 +76,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
@Inject OpenHumansUploader openHumansUploader;
|
@Inject OpenHumansUploader openHumansUploader;
|
||||||
|
|
||||||
public static final String DATABASE_NAME = "AndroidAPSDb";
|
public static final String DATABASE_NAME = "AndroidAPSDb";
|
||||||
public static final String DATABASE_BGREADINGS = "BgReadings";
|
|
||||||
public static final String DATABASE_TEMPORARYBASALS = "TemporaryBasals";
|
public static final String DATABASE_TEMPORARYBASALS = "TemporaryBasals";
|
||||||
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
|
public static final String DATABASE_EXTENDEDBOLUSES = "ExtendedBoluses";
|
||||||
public static final String DATABASE_TEMPTARGETS = "TempTargets";
|
public static final String DATABASE_TEMPTARGETS = "TempTargets";
|
||||||
|
@ -101,10 +95,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
private static final ScheduledExecutorService bgWorker = Executors.newSingleThreadScheduledExecutor();
|
private static final ScheduledExecutorService bgWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
private static ScheduledFuture<?> scheduledBgPost = null;
|
private static ScheduledFuture<?> scheduledBgPost = null;
|
||||||
|
|
||||||
private static final ScheduledExecutorService bgHistoryWorker = Executors.newSingleThreadScheduledExecutor();
|
|
||||||
private static ScheduledFuture<?> scheduledBgHistoryPost = null;
|
|
||||||
private static long oldestBgHistoryChange = 0;
|
|
||||||
|
|
||||||
private static final ScheduledExecutorService tempBasalsWorker = Executors.newSingleThreadScheduledExecutor();
|
private static final ScheduledExecutorService tempBasalsWorker = Executors.newSingleThreadScheduledExecutor();
|
||||||
private static ScheduledFuture<?> scheduledTemBasalsPost = null;
|
private static ScheduledFuture<?> scheduledTemBasalsPost = null;
|
||||||
|
|
||||||
|
@ -135,7 +125,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
try {
|
try {
|
||||||
aapsLogger.info(LTag.DATABASE, "onCreate");
|
aapsLogger.info(LTag.DATABASE, "onCreate");
|
||||||
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
//TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
||||||
|
@ -167,7 +157,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
if (oldVersion < 7) {
|
if (oldVersion < 7) {
|
||||||
aapsLogger.info(LTag.DATABASE, "onUpgrade");
|
aapsLogger.info(LTag.DATABASE, "onUpgrade");
|
||||||
TableUtils.dropTable(connectionSource, TempTarget.class, true);
|
TableUtils.dropTable(connectionSource, TempTarget.class, true);
|
||||||
TableUtils.dropTable(connectionSource, BgReading.class, true);
|
//TableUtils.dropTable(connectionSource, BgReading.class, true);
|
||||||
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
||||||
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
||||||
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
||||||
|
@ -217,7 +207,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
public void resetDatabases() {
|
public void resetDatabases() {
|
||||||
try {
|
try {
|
||||||
TableUtils.dropTable(connectionSource, TempTarget.class, true);
|
TableUtils.dropTable(connectionSource, TempTarget.class, true);
|
||||||
TableUtils.dropTable(connectionSource, BgReading.class, true);
|
//TableUtils.dropTable(connectionSource, BgReading.class, true);
|
||||||
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
TableUtils.dropTable(connectionSource, DanaRHistoryRecord.class, true);
|
||||||
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
TableUtils.dropTable(connectionSource, DbRequest.class, true);
|
||||||
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
TableUtils.dropTable(connectionSource, TemporaryBasal.class, true);
|
||||||
|
@ -227,7 +217,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
TableUtils.dropTable(connectionSource, TDD.class, true);
|
TableUtils.dropTable(connectionSource, TDD.class, true);
|
||||||
TableUtils.dropTable(connectionSource, OmnipodHistoryRecord.class, true);
|
TableUtils.dropTable(connectionSource, OmnipodHistoryRecord.class, true);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
TableUtils.createTableIfNotExists(connectionSource, TempTarget.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
//TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
TableUtils.createTableIfNotExists(connectionSource, DanaRHistoryRecord.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
TableUtils.createTableIfNotExists(connectionSource, DbRequest.class);
|
||||||
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
TableUtils.createTableIfNotExists(connectionSource, TemporaryBasal.class);
|
||||||
|
@ -241,7 +231,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
aapsLogger.error("Unhandled exception", e);
|
aapsLogger.error("Unhandled exception", e);
|
||||||
}
|
}
|
||||||
virtualPumpPlugin.setFakingStatus(true);
|
virtualPumpPlugin.setFakingStatus(true);
|
||||||
scheduleBgChange(null); // trigger refresh
|
|
||||||
scheduleTemporaryBasalChange();
|
scheduleTemporaryBasalChange();
|
||||||
scheduleExtendedBolusChange();
|
scheduleExtendedBolusChange();
|
||||||
scheduleTemporaryTargetChange();
|
scheduleTemporaryTargetChange();
|
||||||
|
@ -326,10 +315,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return getDao(TempTarget.class);
|
return getDao(TempTarget.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dao<BgReading, Long> getDaoBgReadings() throws SQLException {
|
|
||||||
return getDao(BgReading.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Dao<DanaRHistoryRecord, String> getDaoDanaRHistory() throws SQLException {
|
private Dao<DanaRHistoryRecord, String> getDaoDanaRHistory() throws SQLException {
|
||||||
return getDao(DanaRHistoryRecord.class);
|
return getDao(DanaRHistoryRecord.class);
|
||||||
}
|
}
|
||||||
|
@ -384,144 +369,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
aapsLogger.debug(LTag.DATABASE, "Rounding " + date + " to " + rounded);
|
aapsLogger.debug(LTag.DATABASE, "Rounding " + date + " to " + rounded);
|
||||||
return rounded;
|
return rounded;
|
||||||
}
|
}
|
||||||
// ------------------- BgReading handling -----------------------
|
|
||||||
|
|
||||||
public boolean createIfNotExists(BgReading bgReading, String from) {
|
|
||||||
try {
|
|
||||||
bgReading.date = roundDateToSec(bgReading.date);
|
|
||||||
BgReading old = getDaoBgReadings().queryForId(bgReading.date);
|
|
||||||
if (old == null) {
|
|
||||||
getDaoBgReadings().create(bgReading);
|
|
||||||
openHumansUploader.enqueueBGReading(bgReading);
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "BG: New record from: " + from + " " + bgReading.toString());
|
|
||||||
scheduleBgChange(bgReading);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!old.isEqual(bgReading)) {
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "BG: Similiar found: " + old.toString());
|
|
||||||
old.copyFrom(bgReading);
|
|
||||||
getDaoBgReadings().update(old);
|
|
||||||
openHumansUploader.enqueueBGReading(old);
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "BG: Updating record from: " + from + " New data: " + old.toString());
|
|
||||||
scheduleBgHistoryChange(old.date); // trigger cache invalidation
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(BgReading bgReading) {
|
|
||||||
bgReading.date = roundDateToSec(bgReading.date);
|
|
||||||
try {
|
|
||||||
getDaoBgReadings().update(bgReading);
|
|
||||||
openHumansUploader.enqueueBGReading(bgReading);
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "BG: Updating record from: "+ bgReading.toString());
|
|
||||||
scheduleBgHistoryChange(bgReading.date); // trigger cache invalidation
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleBgChange(@Nullable final BgReading bgReading) {
|
|
||||||
class PostRunnable implements Runnable {
|
|
||||||
public void run() {
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg");
|
|
||||||
rxBus.send(new EventNewBG(bgReading));
|
|
||||||
scheduledBgPost = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// prepare task for execution in 1 sec
|
|
||||||
// cancel waiting task to prevent sending multiple posts
|
|
||||||
if (scheduledBgPost != null)
|
|
||||||
scheduledBgPost.cancel(false);
|
|
||||||
Runnable task = new PostRunnable();
|
|
||||||
final int sec = 1;
|
|
||||||
scheduledBgPost = bgWorker.schedule(task, sec, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void scheduleBgHistoryChange(@Nullable final long timestamp) {
|
|
||||||
class PostRunnable implements Runnable {
|
|
||||||
public void run() {
|
|
||||||
aapsLogger.debug(LTag.DATABASE, "Firing EventNewBg");
|
|
||||||
rxBus.send(new EventNewHistoryBgData(oldestBgHistoryChange));
|
|
||||||
scheduledBgHistoryPost = null;
|
|
||||||
oldestBgHistoryChange = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// prepare task for execution in 1 sec
|
|
||||||
// cancel waiting task to prevent sending multiple posts
|
|
||||||
if (scheduledBgHistoryPost != null)
|
|
||||||
scheduledBgHistoryPost.cancel(false);
|
|
||||||
Runnable task = new PostRunnable();
|
|
||||||
final int sec = 3;
|
|
||||||
if (oldestBgHistoryChange == 0 || oldestBgHistoryChange > timestamp)
|
|
||||||
oldestBgHistoryChange = timestamp;
|
|
||||||
scheduledBgHistoryPost = bgHistoryWorker.schedule(task, sec, TimeUnit.SECONDS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BgReading> getBgreadingsDataFromTime(long mills, boolean ascending) {
|
|
||||||
try {
|
|
||||||
Dao<BgReading, Long> daoBgreadings = getDaoBgReadings();
|
|
||||||
List<BgReading> bgReadings;
|
|
||||||
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
|
|
||||||
queryBuilder.orderBy("date", ascending);
|
|
||||||
Where where = queryBuilder.where();
|
|
||||||
where.ge("date", mills).and().ge("value", 39).and().eq("isValid", true);
|
|
||||||
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
|
|
||||||
bgReadings = daoBgreadings.query(preparedQuery);
|
|
||||||
return bgReadings;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BgReading> getBgreadingsDataFromTime(long start, long end, boolean ascending) {
|
|
||||||
try {
|
|
||||||
Dao<BgReading, Long> daoBgreadings = getDaoBgReadings();
|
|
||||||
List<BgReading> bgReadings;
|
|
||||||
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
|
|
||||||
queryBuilder.orderBy("date", ascending);
|
|
||||||
Where where = queryBuilder.where();
|
|
||||||
where.between("date", start, end).and().ge("value", 39).and().eq("isValid", true);
|
|
||||||
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
|
|
||||||
bgReadings = daoBgreadings.query(preparedQuery);
|
|
||||||
return bgReadings;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BgReading> getAllBgreadingsDataFromTime(long mills, boolean ascending) {
|
|
||||||
try {
|
|
||||||
Dao<BgReading, Long> daoBgreadings = getDaoBgReadings();
|
|
||||||
List<BgReading> bgReadings;
|
|
||||||
QueryBuilder<BgReading, Long> queryBuilder = daoBgreadings.queryBuilder();
|
|
||||||
queryBuilder.orderBy("date", ascending);
|
|
||||||
Where where = queryBuilder.where();
|
|
||||||
where.ge("date", mills);
|
|
||||||
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
|
|
||||||
bgReadings = daoBgreadings.query(preparedQuery);
|
|
||||||
return bgReadings;
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return new ArrayList<BgReading>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BgReading> getAllBgReadings() {
|
|
||||||
try {
|
|
||||||
return getDaoBgReadings().queryForAll();
|
|
||||||
} catch (SQLException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------- TDD handling -----------------------
|
// ------------------- TDD handling -----------------------
|
||||||
public void createOrUpdateTDD(TDD tdd) {
|
public void createOrUpdateTDD(TDD tdd) {
|
||||||
|
@ -1672,6 +1519,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
|
private ProfileSwitch getLastProfileSwitchWithoutDuration() {
|
||||||
try {
|
try {
|
||||||
|
@ -2010,7 +1858,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copied from xDrip+
|
/*
|
||||||
|
TODO implement again for database branch // Copied from xDrip+
|
||||||
String calculateDirection(BgReading bgReading) {
|
String calculateDirection(BgReading bgReading) {
|
||||||
// Rework to get bgreaings from internal DB and calculate on that base
|
// Rework to get bgreaings from internal DB and calculate on that base
|
||||||
|
|
||||||
|
@ -2056,7 +1905,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
// aapsLogger.error(LTag.GLUCOSE, "Direction set to: " + arrow);
|
// aapsLogger.error(LTag.GLUCOSE, "Direction set to: " + arrow);
|
||||||
return arrow;
|
return arrow;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// ---------------- Open Humans Queue handling ---------------
|
// ---------------- Open Humans Queue handling ---------------
|
||||||
|
|
||||||
public void clearOpenHumansQueue() {
|
public void clearOpenHumansQueue() {
|
||||||
|
@ -2109,8 +1958,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
|
||||||
public long getCountOfAllRows() {
|
public long getCountOfAllRows() {
|
||||||
try {
|
try {
|
||||||
return getDaoBgReadings().countOf()
|
return getDaoCareportalEvents().countOf()
|
||||||
+ getDaoCareportalEvents().countOf()
|
|
||||||
+ getDaoExtendedBolus().countOf()
|
+ getDaoExtendedBolus().countOf()
|
||||||
+ getDaoCareportalEvents().countOf()
|
+ getDaoCareportalEvents().countOf()
|
||||||
+ getDaoProfileSwitch().countOf()
|
+ getDaoProfileSwitch().countOf()
|
||||||
|
|
|
@ -20,10 +20,6 @@ public class DatabaseHelperProvider implements DatabaseHelperInterface {
|
||||||
@Inject DatabaseHelperProvider() {
|
@Inject DatabaseHelperProvider() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull @Override public List<BgReading> getAllBgreadingsDataFromTime(long mills, boolean ascending) {
|
|
||||||
return MainApp.getDbHelper().getAllBgreadingsDataFromTime(mills, ascending);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void createOrUpdate(@NotNull CareportalEvent careportalEvent) {
|
@Override public void createOrUpdate(@NotNull CareportalEvent careportalEvent) {
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
MainApp.getDbHelper().createOrUpdate(careportalEvent);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.androidaps.core.di.CoreModule
|
||||||
import info.nightscout.androidaps.dana.di.DanaModule
|
import info.nightscout.androidaps.dana.di.DanaModule
|
||||||
import info.nightscout.androidaps.danar.di.DanaRModule
|
import info.nightscout.androidaps.danar.di.DanaRModule
|
||||||
import info.nightscout.androidaps.danars.di.DanaRSModule
|
import info.nightscout.androidaps.danars.di.DanaRSModule
|
||||||
|
import info.nightscout.androidaps.database.DatabaseModule
|
||||||
import info.nightscout.androidaps.plugins.pump.common.dagger.RileyLinkModule
|
import info.nightscout.androidaps.plugins.pump.common.dagger.RileyLinkModule
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dagger.OmnipodModule
|
import info.nightscout.androidaps.plugins.pump.omnipod.dagger.OmnipodModule
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -17,6 +18,7 @@ import javax.inject.Singleton
|
||||||
@Component(
|
@Component(
|
||||||
modules = [
|
modules = [
|
||||||
AndroidInjectionModule::class,
|
AndroidInjectionModule::class,
|
||||||
|
DatabaseModule::class,
|
||||||
PluginsModule::class,
|
PluginsModule::class,
|
||||||
SkinsModule::class,
|
SkinsModule::class,
|
||||||
ActivitiesModule::class,
|
ActivitiesModule::class,
|
||||||
|
|
|
@ -2,11 +2,9 @@ package info.nightscout.androidaps.dependencyInjection
|
||||||
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.db.DatabaseHelper
|
||||||
import info.nightscout.androidaps.db.*
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileStore
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
|
||||||
import info.nightscout.androidaps.plugins.general.food.FoodService
|
import info.nightscout.androidaps.plugins.general.food.FoodService
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentService
|
import info.nightscout.androidaps.plugins.treatments.TreatmentService
|
||||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||||
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
|
import info.nightscout.androidaps.utils.wizard.QuickWizardEntry
|
||||||
|
|
|
@ -13,13 +13,13 @@ import android.widget.AdapterView.OnItemSelectedListener
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import androidx.fragment.app.FragmentManager
|
import androidx.fragment.app.FragmentManager
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
import dagger.android.support.DaggerDialogFragment
|
import dagger.android.support.DaggerDialogFragment
|
||||||
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.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.databinding.DialogWizardBinding
|
import info.nightscout.androidaps.databinding.DialogWizardBinding
|
||||||
import info.nightscout.androidaps.db.BgReading
|
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.Constraint
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
@ -38,6 +38,7 @@ import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import info.nightscout.androidaps.utils.valueToUnits
|
||||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
@ -47,6 +48,7 @@ import kotlin.math.abs
|
||||||
|
|
||||||
class WizardDialog : DaggerDialogFragment() {
|
class WizardDialog : DaggerDialogFragment() {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||||
|
@ -233,6 +235,10 @@ class WizardDialog : DaggerDialogFragment() {
|
||||||
binding.cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
|
binding.cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun valueToUnitsToString(value: Double, units: String): String =
|
||||||
|
if (units == Constants.MGDL) DecimalFormatter.to0Decimal(value)
|
||||||
|
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
|
||||||
|
|
||||||
private fun initDialog() {
|
private fun initDialog() {
|
||||||
val profile = profileFunction.getProfile()
|
val profile = profileFunction.getProfile()
|
||||||
val profileStore = activePlugin.activeProfileInterface.profile
|
val profileStore = activePlugin.activeProfileInterface.profile
|
||||||
|
@ -243,8 +249,7 @@ class WizardDialog : DaggerDialogFragment() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val profileList: ArrayList<CharSequence>
|
val profileList: ArrayList<CharSequence> = profileStore.getProfileList()
|
||||||
profileList = profileStore.getProfileList()
|
|
||||||
profileList.add(0, resourceHelper.gs(R.string.active))
|
profileList.add(0, resourceHelper.gs(R.string.active))
|
||||||
context?.let { context ->
|
context?.let { context ->
|
||||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||||
|
@ -332,7 +337,7 @@ class WizardDialog : DaggerDialogFragment() {
|
||||||
binding.notes.text.toString(), carbTime)
|
binding.notes.text.toString(), carbTime)
|
||||||
|
|
||||||
wizard?.let { wizard ->
|
wizard?.let { wizard ->
|
||||||
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, profileFunction.getUnits())).valueToUnitsToString(profileFunction.getUnits()), wizard.sens)
|
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), valueToUnitsToString(Profile.toMgdl(bg, profileFunction.getUnits()), profileFunction.getUnits()), wizard.sens)
|
||||||
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
||||||
|
|
||||||
binding.carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
binding.carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
package info.nightscout.androidaps.events
|
package info.nightscout.androidaps.events
|
||||||
|
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
|
||||||
class EventNewBG(val bgReading: BgReading?) : EventLoop()
|
class EventNewBG(val glucoseValue: GlucoseValue?) : EventLoop()
|
|
@ -1,6 +1,7 @@
|
||||||
package info.nightscout.androidaps.historyBrowser
|
package info.nightscout.androidaps.historyBrowser
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
@ -32,9 +33,10 @@ class IobCobCalculatorPluginHistory @Inject constructor(
|
||||||
sensitivityAAPSPlugin: SensitivityAAPSPlugin,
|
sensitivityAAPSPlugin: SensitivityAAPSPlugin,
|
||||||
sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin,
|
sensitivityWeightedAveragePlugin: SensitivityWeightedAveragePlugin,
|
||||||
fabricPrivacy: FabricPrivacy,
|
fabricPrivacy: FabricPrivacy,
|
||||||
dateUtil: DateUtil
|
dateUtil: DateUtil,
|
||||||
|
repository: AppRepository
|
||||||
) : IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction,
|
) : IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction,
|
||||||
activePlugin, treatmentsPluginHistory, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil) {
|
activePlugin, treatmentsPluginHistory, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository) {
|
||||||
|
|
||||||
override fun onStart() { // do not attach to rxbus
|
override fun onStart() { // do not attach to rxbus
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ import info.nightscout.androidaps.activities.ErrorHelperActivity;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult;
|
import info.nightscout.androidaps.data.PumpEnactResult;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.database.entities.GlucoseValue;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.Source;
|
import info.nightscout.androidaps.db.Source;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
|
@ -201,14 +201,14 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
// Autosens calculation not triggered by a new BG
|
// Autosens calculation not triggered by a new BG
|
||||||
if (!(event.getCause() instanceof EventNewBG)) return;
|
if (!(event.getCause() instanceof EventNewBG)) return;
|
||||||
|
|
||||||
BgReading bgReading = iobCobCalculatorPlugin.actualBg();
|
GlucoseValue glucoseValue = iobCobCalculatorPlugin.actualBg();
|
||||||
// BG outdated
|
// BG outdated
|
||||||
if (bgReading == null) return;
|
if (glucoseValue == null) return;
|
||||||
// already looped with that value
|
// already looped with that value
|
||||||
if (bgReading.date <= lastBgTriggeredRun) return;
|
if (glucoseValue.getTimestamp() <= lastBgTriggeredRun) return;
|
||||||
|
|
||||||
lastBgTriggeredRun = bgReading.date;
|
lastBgTriggeredRun = glucoseValue.getTimestamp();
|
||||||
invoke("AutosenseCalculation for " + bgReading, true);
|
invoke("AutosenseCalculation for " + glucoseValue, true);
|
||||||
}, fabricPrivacy::logException)
|
}, fabricPrivacy::logException)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -392,30 +392,30 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
|
|
||||||
// Prepare for pumps using % basals
|
// Prepare for pumps using % basals
|
||||||
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT && allowPercentage()) {
|
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT && allowPercentage()) {
|
||||||
result.usePercent = true;
|
result.setUsePercent(true);
|
||||||
}
|
}
|
||||||
result.percent = (int) (result.rate / profile.getBasal() * 100);
|
result.setPercent((int) (result.getRate() / profile.getBasal() * 100));
|
||||||
|
|
||||||
// check rate for constraints
|
// check rate for constraints
|
||||||
final APSResult resultAfterConstraints = result.newAndClone(injector);
|
final APSResult resultAfterConstraints = result.newAndClone(injector);
|
||||||
resultAfterConstraints.rateConstraint = new Constraint<>(resultAfterConstraints.rate);
|
resultAfterConstraints.setRateConstraint(new Constraint<>(resultAfterConstraints.getRate()));
|
||||||
resultAfterConstraints.rate = constraintChecker.applyBasalConstraints(resultAfterConstraints.rateConstraint, profile).value();
|
resultAfterConstraints.setRate(constraintChecker.applyBasalConstraints(resultAfterConstraints.getRateConstraint(), profile).value());
|
||||||
|
|
||||||
resultAfterConstraints.percentConstraint = new Constraint<>(resultAfterConstraints.percent);
|
resultAfterConstraints.setPercentConstraint(new Constraint<>(resultAfterConstraints.getPercent()));
|
||||||
resultAfterConstraints.percent = constraintChecker.applyBasalPercentConstraints(resultAfterConstraints.percentConstraint, profile).value();
|
resultAfterConstraints.setPercent(constraintChecker.applyBasalPercentConstraints(resultAfterConstraints.getPercentConstraint(), profile).value());
|
||||||
|
|
||||||
resultAfterConstraints.smbConstraint = new Constraint<>(resultAfterConstraints.smb);
|
resultAfterConstraints.setSmbConstraint(new Constraint<>(resultAfterConstraints.getSmb()));
|
||||||
resultAfterConstraints.smb = constraintChecker.applyBolusConstraints(resultAfterConstraints.smbConstraint).value();
|
resultAfterConstraints.setSmb(constraintChecker.applyBolusConstraints(resultAfterConstraints.getSmbConstraint()).value());
|
||||||
|
|
||||||
// safety check for multiple SMBs
|
// safety check for multiple SMBs
|
||||||
long lastBolusTime = treatmentsPlugin.getLastBolusTime();
|
long lastBolusTime = treatmentsPlugin.getLastBolusTime();
|
||||||
if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) {
|
if (lastBolusTime != 0 && lastBolusTime + T.mins(3).msecs() > System.currentTimeMillis()) {
|
||||||
getAapsLogger().debug(LTag.APS, "SMB requested but still in 3 min interval");
|
getAapsLogger().debug(LTag.APS, "SMB requested but still in 3 min interval");
|
||||||
resultAfterConstraints.smb = 0;
|
resultAfterConstraints.setSmb(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastRun != null && lastRun.getConstraintsProcessed() != null) {
|
if (lastRun != null && lastRun.getConstraintsProcessed() != null) {
|
||||||
prevCarbsreq = lastRun.getConstraintsProcessed().carbsReq;
|
prevCarbsreq = lastRun.getConstraintsProcessed().getCarbsReq();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastRun == null) lastRun = new LastRun();
|
if (lastRun == null) lastRun = new LastRun();
|
||||||
|
@ -449,7 +449,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
if (closedLoopEnabled.value()) {
|
if (closedLoopEnabled.value()) {
|
||||||
if (allowNotification) {
|
if (allowNotification) {
|
||||||
if (resultAfterConstraints.isCarbsRequired()
|
if (resultAfterConstraints.isCarbsRequired()
|
||||||
&& resultAfterConstraints.carbsReq >= sp.getInt(R.string.key_smb_enable_carbs_suggestions_threshold, 0)
|
&& resultAfterConstraints.getCarbsReq() >= sp.getInt(R.string.key_smb_enable_carbs_suggestions_threshold, 0)
|
||||||
&& carbsSuggestionsSuspendedUntil < System.currentTimeMillis() && !treatmentTimethreshold(-15)) {
|
&& carbsSuggestionsSuspendedUntil < System.currentTimeMillis() && !treatmentTimethreshold(-15)) {
|
||||||
|
|
||||||
if (sp.getBoolean(R.string.key_enable_carbs_required_alert_local, true) && !sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true)) {
|
if (sp.getBoolean(R.string.key_enable_carbs_required_alert_local, true) && !sp.getBoolean(R.string.key_raise_notifications_as_android_notifications, true)) {
|
||||||
|
@ -519,9 +519,9 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
&& !commandQueue.isRunning(Command.CommandType.BOLUS)) {
|
&& !commandQueue.isRunning(Command.CommandType.BOLUS)) {
|
||||||
final PumpEnactResult waiting = new PumpEnactResult(getInjector());
|
final PumpEnactResult waiting = new PumpEnactResult(getInjector());
|
||||||
waiting.queued = true;
|
waiting.queued = true;
|
||||||
if (resultAfterConstraints.tempBasalRequested)
|
if (resultAfterConstraints.getTempBasalRequested())
|
||||||
lastRun.setTbrSetByPump(waiting);
|
lastRun.setTbrSetByPump(waiting);
|
||||||
if (resultAfterConstraints.bolusRequested)
|
if (resultAfterConstraints.getBolusRequested())
|
||||||
lastRun.setSmbSetByPump(waiting);
|
lastRun.setSmbSetByPump(waiting);
|
||||||
rxBus.send(new EventLoopUpdateGui());
|
rxBus.send(new EventLoopUpdateGui());
|
||||||
fabricPrivacy.logCustom("APSRequest");
|
fabricPrivacy.logCustom("APSRequest");
|
||||||
|
@ -653,7 +653,7 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
|
|
||||||
private void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
|
private void applyTBRRequest(APSResult request, Profile profile, Callback callback) {
|
||||||
|
|
||||||
if (!request.tempBasalRequested) {
|
if (!request.getTempBasalRequested()) {
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.result(new PumpEnactResult(getInjector()).enacted(false).success(true).comment(resourceHelper.gs(R.string.nochangerequested))).run();
|
callback.result(new PumpEnactResult(getInjector()).enacted(false).success(true).comment(resourceHelper.gs(R.string.nochangerequested))).run();
|
||||||
}
|
}
|
||||||
|
@ -682,48 +682,48 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
TemporaryBasal activeTemp = treatmentsPlugin.getTempBasalFromHistory(now);
|
TemporaryBasal activeTemp = treatmentsPlugin.getTempBasalFromHistory(now);
|
||||||
if (request.usePercent && allowPercentage()) {
|
if (request.getUsePercent() && allowPercentage()) {
|
||||||
if (request.percent == 100 && request.duration == 0) {
|
if (request.getPercent() == 100 && request.getDuration() == 0) {
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
|
||||||
commandQueue.cancelTempBasal(false, callback);
|
commandQueue.cancelTempBasal(false, callback);
|
||||||
} else {
|
} else {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Basal set correctly");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Basal set correctly");
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.result(new PumpEnactResult(getInjector()).percent(request.percent).duration(0)
|
callback.result(new PumpEnactResult(getInjector()).percent(request.getPercent()).duration(0)
|
||||||
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
|
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (activeTemp != null
|
} else if (activeTemp != null
|
||||||
&& activeTemp.getPlannedRemainingMinutes() > 5
|
&& activeTemp.getPlannedRemainingMinutes() > 5
|
||||||
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
|
&& request.getDuration() - activeTemp.getPlannedRemainingMinutes() < 30
|
||||||
&& request.percent == activeTemp.percentRate) {
|
&& request.getPercent() == activeTemp.percentRate) {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.result(new PumpEnactResult(getInjector()).percent(request.percent)
|
callback.result(new PumpEnactResult(getInjector()).percent(request.getPercent())
|
||||||
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
|
.enacted(false).success(true).duration(activeTemp.getPlannedRemainingMinutes())
|
||||||
.comment(resourceHelper.gs(R.string.let_temp_basal_run))).run();
|
.comment(resourceHelper.gs(R.string.let_temp_basal_run))).run();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: tempBasalPercent()");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: tempBasalPercent()");
|
||||||
commandQueue.tempBasalPercent(request.percent, request.duration, false, profile, callback);
|
commandQueue.tempBasalPercent(request.getPercent(), request.getDuration(), false, profile, callback);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((request.rate == 0 && request.duration == 0) || Math.abs(request.rate - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
if ((request.getRate() == 0 && request.getDuration() == 0) || Math.abs(request.getRate() - pump.getBaseBasalRate()) < pump.getPumpDescription().basalStep) {
|
||||||
if (activeTemp != null) {
|
if (activeTemp != null) {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: cancelTempBasal()");
|
||||||
commandQueue.cancelTempBasal(false, callback);
|
commandQueue.cancelTempBasal(false, callback);
|
||||||
} else {
|
} else {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Basal set correctly");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Basal set correctly");
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.result(new PumpEnactResult(getInjector()).absolute(request.rate).duration(0)
|
callback.result(new PumpEnactResult(getInjector()).absolute(request.getRate()).duration(0)
|
||||||
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
|
.enacted(false).success(true).comment(resourceHelper.gs(R.string.basal_set_correctly))).run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (activeTemp != null
|
} else if (activeTemp != null
|
||||||
&& activeTemp.getPlannedRemainingMinutes() > 5
|
&& activeTemp.getPlannedRemainingMinutes() > 5
|
||||||
&& request.duration - activeTemp.getPlannedRemainingMinutes() < 30
|
&& request.getDuration() - activeTemp.getPlannedRemainingMinutes() < 30
|
||||||
&& Math.abs(request.rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
|
&& Math.abs(request.getRate() - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: Temp basal set correctly");
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
callback.result(new PumpEnactResult(getInjector()).absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
|
callback.result(new PumpEnactResult(getInjector()).absolute(activeTemp.tempBasalConvertedToAbsolute(now, profile))
|
||||||
|
@ -732,13 +732,13 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: setTempBasalAbsolute()");
|
||||||
commandQueue.tempBasalAbsolute(request.rate, request.duration, false, profile, callback);
|
commandQueue.tempBasalAbsolute(request.getRate(), request.getDuration(), false, profile, callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applySMBRequest(APSResult request, Callback callback) {
|
private void applySMBRequest(APSResult request, Callback callback) {
|
||||||
if (!request.bolusRequested) {
|
if (!request.getBolusRequested()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -777,10 +777,10 @@ public class LoopPlugin extends PluginBase implements LoopInterface {
|
||||||
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
DetailedBolusInfo detailedBolusInfo = new DetailedBolusInfo();
|
||||||
detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.getLastBolusTime();
|
detailedBolusInfo.lastKnownBolusTime = treatmentsPlugin.getLastBolusTime();
|
||||||
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
detailedBolusInfo.eventType = CareportalEvent.CORRECTIONBOLUS;
|
||||||
detailedBolusInfo.insulin = request.smb;
|
detailedBolusInfo.insulin = request.getSmb();
|
||||||
detailedBolusInfo.isSMB = true;
|
detailedBolusInfo.isSMB = true;
|
||||||
detailedBolusInfo.source = Source.USER;
|
detailedBolusInfo.source = Source.USER;
|
||||||
detailedBolusInfo.deliverAt = request.deliverAt;
|
detailedBolusInfo.deliverAt = request.getDeliverAt();
|
||||||
getAapsLogger().debug(LTag.APS, "applyAPSRequest: bolus()");
|
getAapsLogger().debug(LTag.APS, "applyAPSRequest: bolus()");
|
||||||
commandQueue.bolus(detailedBolusInfo, callback);
|
commandQueue.bolus(detailedBolusInfo, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.openAPSAMA;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.mozilla.javascript.NativeObject;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
|
|
||||||
public class DetermineBasalResultAMA extends APSResult {
|
|
||||||
private AAPSLogger aapsLogger;
|
|
||||||
|
|
||||||
private double eventualBG;
|
|
||||||
private double snoozeBG;
|
|
||||||
|
|
||||||
DetermineBasalResultAMA(HasAndroidInjector injector, NativeObject result, JSONObject j) {
|
|
||||||
this(injector);
|
|
||||||
date = DateUtil.now();
|
|
||||||
json = j;
|
|
||||||
if (result.containsKey("error")) {
|
|
||||||
reason = result.get("error").toString();
|
|
||||||
tempBasalRequested = false;
|
|
||||||
rate = -1;
|
|
||||||
duration = -1;
|
|
||||||
} else {
|
|
||||||
reason = result.get("reason").toString();
|
|
||||||
if (result.containsKey("eventualBG")) eventualBG = (Double) result.get("eventualBG");
|
|
||||||
if (result.containsKey("snoozeBG")) snoozeBG = (Double) result.get("snoozeBG");
|
|
||||||
if (result.containsKey("rate")) {
|
|
||||||
rate = (Double) result.get("rate");
|
|
||||||
if (rate < 0d) rate = 0d;
|
|
||||||
tempBasalRequested = true;
|
|
||||||
} else {
|
|
||||||
rate = -1;
|
|
||||||
tempBasalRequested = false;
|
|
||||||
}
|
|
||||||
if (result.containsKey("duration")) {
|
|
||||||
duration = ((Double) result.get("duration")).intValue();
|
|
||||||
//changeRequested as above
|
|
||||||
} else {
|
|
||||||
duration = -1;
|
|
||||||
tempBasalRequested = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bolusRequested = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DetermineBasalResultAMA(HasAndroidInjector injector) {
|
|
||||||
super(injector);
|
|
||||||
hasPredictions = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DetermineBasalResultAMA newAndClone(HasAndroidInjector injector) {
|
|
||||||
DetermineBasalResultAMA newResult = new DetermineBasalResultAMA(injector);
|
|
||||||
doClone(newResult);
|
|
||||||
|
|
||||||
newResult.eventualBG = eventualBG;
|
|
||||||
newResult.snoozeBG = snoozeBG;
|
|
||||||
return newResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONObject json() {
|
|
||||||
try {
|
|
||||||
JSONObject ret = new JSONObject(this.json.toString());
|
|
||||||
return ret;
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error(LTag.APS, "Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package info.nightscout.androidaps.plugins.aps.openAPSAMA
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import org.mozilla.javascript.NativeObject
|
||||||
|
|
||||||
|
class DetermineBasalResultAMA private constructor(injector: HasAndroidInjector) : APSResult(injector) {
|
||||||
|
|
||||||
|
private var eventualBG = 0.0
|
||||||
|
private var snoozeBG = 0.0
|
||||||
|
|
||||||
|
internal constructor(injector: HasAndroidInjector, result: NativeObject, j: JSONObject) : this(injector) {
|
||||||
|
date = DateUtil.now()
|
||||||
|
json = j
|
||||||
|
if (result.containsKey("error")) {
|
||||||
|
reason = result["error"].toString()
|
||||||
|
tempBasalRequested = false
|
||||||
|
rate = (-1).toDouble()
|
||||||
|
duration = -1
|
||||||
|
} else {
|
||||||
|
reason = result["reason"].toString()
|
||||||
|
if (result.containsKey("eventualBG")) eventualBG = result["eventualBG"] as Double
|
||||||
|
if (result.containsKey("snoozeBG")) snoozeBG = result["snoozeBG"] as Double
|
||||||
|
if (result.containsKey("rate")) {
|
||||||
|
rate = result["rate"] as Double
|
||||||
|
if (rate < 0.0) rate = 0.0
|
||||||
|
tempBasalRequested = true
|
||||||
|
} else {
|
||||||
|
rate = (-1).toDouble()
|
||||||
|
tempBasalRequested = false
|
||||||
|
}
|
||||||
|
if (result.containsKey("duration")) {
|
||||||
|
duration = (result["duration"] as Double).toInt()
|
||||||
|
//changeRequested as above
|
||||||
|
} else {
|
||||||
|
duration = -1
|
||||||
|
tempBasalRequested = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bolusRequested = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newAndClone(injector: HasAndroidInjector): DetermineBasalResultAMA {
|
||||||
|
val newResult = DetermineBasalResultAMA(injector)
|
||||||
|
doClone(newResult)
|
||||||
|
newResult.eventualBG = eventualBG
|
||||||
|
newResult.snoozeBG = snoozeBG
|
||||||
|
return newResult
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun json(): JSONObject? {
|
||||||
|
try {
|
||||||
|
return JSONObject(json.toString())
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error(LTag.APS, "Unhandled exception", e)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
hasPredictions = true
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,20 +18,20 @@ import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui;
|
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui;
|
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui;
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
|
@ -238,15 +238,15 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
|
||||||
lastAPSResult = null;
|
lastAPSResult = null;
|
||||||
lastAPSRun = 0;
|
lastAPSRun = 0;
|
||||||
} else {
|
} else {
|
||||||
if (determineBasalResultAMA.rate == 0d && determineBasalResultAMA.duration == 0 && !treatmentsPlugin.isTempBasalInProgress())
|
if (determineBasalResultAMA.getRate() == 0d && determineBasalResultAMA.getDuration() == 0 && !treatmentsPlugin.isTempBasalInProgress())
|
||||||
determineBasalResultAMA.tempBasalRequested = false;
|
determineBasalResultAMA.setTempBasalRequested(false);
|
||||||
|
|
||||||
determineBasalResultAMA.iob = iobArray[0];
|
determineBasalResultAMA.setIob(iobArray[0]);
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
determineBasalResultAMA.json.put("timestamp", DateUtil.toISOString(now));
|
determineBasalResultAMA.getJson().put("timestamp", DateUtil.toISOString(now));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
aapsLogger.error(LTag.APS, "Unhandled exception", e);
|
aapsLogger.error(LTag.APS, "Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,97 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.openAPSSMB;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
|
||||||
import info.nightscout.androidaps.R;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
|
||||||
|
|
||||||
public class DetermineBasalResultSMB extends APSResult {
|
|
||||||
@Inject SP sp;
|
|
||||||
|
|
||||||
private double eventualBG;
|
|
||||||
private double snoozeBG;
|
|
||||||
|
|
||||||
private DetermineBasalResultSMB(HasAndroidInjector injector) {
|
|
||||||
super(injector);
|
|
||||||
hasPredictions = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
DetermineBasalResultSMB(HasAndroidInjector injector, JSONObject result) {
|
|
||||||
this(injector);
|
|
||||||
date = DateUtil.now();
|
|
||||||
json = result;
|
|
||||||
try {
|
|
||||||
if (result.has("error")) {
|
|
||||||
reason = result.getString("error");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
reason = result.getString("reason");
|
|
||||||
if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG");
|
|
||||||
if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG");
|
|
||||||
//if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq");
|
|
||||||
|
|
||||||
if (result.has("carbsReq")) carbsReq = result.getInt("carbsReq");
|
|
||||||
if (result.has("carbsReqWithin")) carbsReqWithin = result.getInt("carbsReqWithin");
|
|
||||||
|
|
||||||
|
|
||||||
if (result.has("rate") && result.has("duration")) {
|
|
||||||
tempBasalRequested = true;
|
|
||||||
rate = result.getDouble("rate");
|
|
||||||
if (rate < 0d) rate = 0d;
|
|
||||||
duration = result.getInt("duration");
|
|
||||||
} else {
|
|
||||||
rate = -1;
|
|
||||||
duration = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.has("units")) {
|
|
||||||
bolusRequested = true;
|
|
||||||
smb = result.getDouble("units");
|
|
||||||
} else {
|
|
||||||
smb = 0d;
|
|
||||||
}
|
|
||||||
if (result.has("targetBG")) {
|
|
||||||
targetBG = result.getDouble("targetBG");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.has("deliverAt")) {
|
|
||||||
String date = result.getString("deliverAt");
|
|
||||||
try {
|
|
||||||
deliverAt = DateUtil.fromISODateString(date).getTime();
|
|
||||||
} catch (Exception e) {
|
|
||||||
aapsLogger.error(LTag.APS, "Error parsing 'deliverAt' date: " + date, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error(LTag.APS, "Error parsing determine-basal result JSON", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DetermineBasalResultSMB newAndClone(HasAndroidInjector injector) {
|
|
||||||
DetermineBasalResultSMB newResult = new DetermineBasalResultSMB(injector);
|
|
||||||
doClone(newResult);
|
|
||||||
|
|
||||||
newResult.eventualBG = eventualBG;
|
|
||||||
newResult.snoozeBG = snoozeBG;
|
|
||||||
return newResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public JSONObject json() {
|
|
||||||
try {
|
|
||||||
return new JSONObject(this.json.toString());
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error(LTag.APS, "Error converting determine-basal result to JSON", e);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
package info.nightscout.androidaps.plugins.aps.openAPSSMB
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
|
||||||
|
class DetermineBasalResultSMB private constructor(injector: HasAndroidInjector) : APSResult(injector) {
|
||||||
|
|
||||||
|
private var eventualBG = 0.0
|
||||||
|
private var snoozeBG = 0.0
|
||||||
|
|
||||||
|
internal constructor(injector: HasAndroidInjector, result: JSONObject) : this(injector) {
|
||||||
|
date = DateUtil.now()
|
||||||
|
json = result
|
||||||
|
try {
|
||||||
|
if (result.has("error")) {
|
||||||
|
reason = result.getString("error")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reason = result.getString("reason")
|
||||||
|
if (result.has("eventualBG")) eventualBG = result.getDouble("eventualBG")
|
||||||
|
if (result.has("snoozeBG")) snoozeBG = result.getDouble("snoozeBG")
|
||||||
|
//if (result.has("insulinReq")) insulinReq = result.getDouble("insulinReq");
|
||||||
|
if (result.has("carbsReq")) carbsReq = result.getInt("carbsReq")
|
||||||
|
if (result.has("carbsReqWithin")) carbsReqWithin = result.getInt("carbsReqWithin")
|
||||||
|
if (result.has("rate") && result.has("duration")) {
|
||||||
|
tempBasalRequested = true
|
||||||
|
rate = result.getDouble("rate")
|
||||||
|
if (rate < 0.0) rate = 0.0
|
||||||
|
duration = result.getInt("duration")
|
||||||
|
} else {
|
||||||
|
rate = (-1).toDouble()
|
||||||
|
duration = -1
|
||||||
|
}
|
||||||
|
if (result.has("units")) {
|
||||||
|
bolusRequested = true
|
||||||
|
smb = result.getDouble("units")
|
||||||
|
} else {
|
||||||
|
smb = 0.0
|
||||||
|
}
|
||||||
|
if (result.has("targetBG")) {
|
||||||
|
targetBG = result.getDouble("targetBG")
|
||||||
|
}
|
||||||
|
if (result.has("deliverAt")) {
|
||||||
|
val date = result.getString("deliverAt")
|
||||||
|
try {
|
||||||
|
deliverAt = DateUtil.fromISODateString(date).time
|
||||||
|
} catch (e: Exception) {
|
||||||
|
aapsLogger.error(LTag.APS, "Error parsing 'deliverAt' date: $date", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error(LTag.APS, "Error parsing determine-basal result JSON", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun newAndClone(injector: HasAndroidInjector): DetermineBasalResultSMB {
|
||||||
|
val newResult = DetermineBasalResultSMB(injector)
|
||||||
|
doClone(newResult)
|
||||||
|
newResult.eventualBG = eventualBG
|
||||||
|
newResult.snoozeBG = snoozeBG
|
||||||
|
return newResult
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun json(): JSONObject? {
|
||||||
|
try {
|
||||||
|
return JSONObject(json.toString())
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error(LTag.APS, "Error converting determine-basal result to JSON", e)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
hasPredictions = true
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,20 +24,20 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader;
|
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui;
|
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui;
|
||||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui;
|
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui;
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
||||||
|
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy;
|
import info.nightscout.androidaps.utils.FabricPrivacy;
|
||||||
|
@ -291,18 +291,18 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
||||||
} else {
|
} else {
|
||||||
// TODO still needed with oref1?
|
// TODO still needed with oref1?
|
||||||
// Fix bug determine basal
|
// Fix bug determine basal
|
||||||
if (determineBasalResultSMB.rate == 0d && determineBasalResultSMB.duration == 0 && !treatmentsPlugin.isTempBasalInProgress())
|
if (determineBasalResultSMB.getRate() == 0d && determineBasalResultSMB.getDuration() == 0 && !treatmentsPlugin.isTempBasalInProgress())
|
||||||
determineBasalResultSMB.tempBasalRequested = false;
|
determineBasalResultSMB.setTempBasalRequested(false);
|
||||||
|
|
||||||
determineBasalResultSMB.iob = iobArray[0];
|
determineBasalResultSMB.setIob(iobArray[0]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
determineBasalResultSMB.json.put("timestamp", DateUtil.toISOString(now));
|
determineBasalResultSMB.getJson().put("timestamp", DateUtil.toISOString(now));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
getAapsLogger().error(LTag.APS, "Unhandled exception", e);
|
getAapsLogger().error(LTag.APS, "Unhandled exception", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
determineBasalResultSMB.inputConstraints = inputConstraints;
|
determineBasalResultSMB.setInputConstraints(inputConstraints);
|
||||||
|
|
||||||
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;
|
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS;
|
||||||
lastAPSResult = determineBasalResultSMB;
|
lastAPSResult = determineBasalResultSMB;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.db.BgReading
|
|
||||||
import info.nightscout.androidaps.events.Event
|
import info.nightscout.androidaps.events.Event
|
||||||
import info.nightscout.androidaps.events.EventExtendedBolusChange
|
import info.nightscout.androidaps.events.EventExtendedBolusChange
|
||||||
import info.nightscout.androidaps.events.EventNewBasalProfile
|
import info.nightscout.androidaps.events.EventNewBasalProfile
|
||||||
|
@ -123,13 +122,13 @@ class DataBroadcastPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bgStatus(bundle: Bundle) {
|
private fun bgStatus(bundle: Bundle) {
|
||||||
val lastBG: BgReading = iobCobCalculatorPlugin.lastBg() ?: return
|
val lastBG = iobCobCalculatorPlugin.lastBg() ?: return
|
||||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData ?: return
|
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData ?: return
|
||||||
|
|
||||||
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
|
bundle.putDouble("glucoseMgdl", lastBG.value) // last BG in mgdl
|
||||||
bundle.putLong("glucoseTimeStamp", lastBG.date) // timestamp
|
bundle.putLong("glucoseTimeStamp", lastBG.timestamp) // timestamp
|
||||||
bundle.putString("units", profileFunction.getUnits()) // units used in AAPS "mg/dl" or "mmol"
|
bundle.putString("units", profileFunction.getUnits()) // units used in AAPS "mg/dl" or "mmol"
|
||||||
bundle.putString("slopeArrow", lastBG.directionToSymbol(databaseHelper)) // direction arrow as string
|
bundle.putString("slopeArrow", lastBG.trendArrow.text) // direction arrow as string
|
||||||
bundle.putDouble("deltaMgdl", glucoseStatus.delta) // bg delta in mgdl
|
bundle.putDouble("deltaMgdl", glucoseStatus.delta) // bg delta in mgdl
|
||||||
bundle.putDouble("avgDeltaMgdl", glucoseStatus.avgdelta) // average bg delta
|
bundle.putDouble("avgDeltaMgdl", glucoseStatus.avgdelta) // average bg delta
|
||||||
bundle.putDouble("high", defaultValueHelper.determineHighLine()) // predefined top value of in range (green area)
|
bundle.putDouble("high", defaultValueHelper.determineHighLine()) // predefined top value of in range (green area)
|
||||||
|
|
|
@ -8,23 +8,36 @@ import android.view.ViewGroup
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.databinding.MaintenanceFragmentBinding
|
import info.nightscout.androidaps.databinding.MaintenanceFragmentBinding
|
||||||
|
import info.nightscout.androidaps.events.EventNewBG
|
||||||
import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface
|
import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
|
import info.nightscout.androidaps.plugins.general.food.FoodPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
|
import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import io.reactivex.Completable.fromAction
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.subscribeBy
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MaintenanceFragment : DaggerFragment() {
|
class MaintenanceFragment : DaggerFragment() {
|
||||||
|
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var maintenancePlugin: MaintenancePlugin
|
@Inject lateinit var maintenancePlugin: MaintenancePlugin
|
||||||
@Inject lateinit var mainApp: MainApp
|
@Inject lateinit var rxBus: RxBusWrapper
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||||
@Inject lateinit var foodPlugin: FoodPlugin
|
@Inject lateinit var foodPlugin: FoodPlugin
|
||||||
@Inject lateinit var importExportPrefs: ImportExportPrefsInterface
|
@Inject lateinit var importExportPrefs: ImportExportPrefsInterface
|
||||||
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
|
||||||
|
private val compositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
private var _binding: MaintenanceFragmentBinding? = null
|
private var _binding: MaintenanceFragmentBinding? = null
|
||||||
|
|
||||||
|
@ -40,25 +53,42 @@ class MaintenanceFragment : DaggerFragment() {
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
binding.logSend.setOnClickListener { maintenancePlugin.sendLogs() }
|
binding.logSend.setOnClickListener { maintenancePlugin.sendLogs() }
|
||||||
binding.logDelete.setOnClickListener { maintenancePlugin.deleteLogs() }
|
binding.logDelete.setOnClickListener {
|
||||||
|
aapsLogger.debug("USER ENTRY: DELETE LOGS")
|
||||||
|
maintenancePlugin.deleteLogs()
|
||||||
|
}
|
||||||
binding.navResetdb.setOnClickListener {
|
binding.navResetdb.setOnClickListener {
|
||||||
activity?.let { activity ->
|
activity?.let { activity ->
|
||||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.reset_db_confirm), Runnable {
|
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.maintenance), resourceHelper.gs(R.string.reset_db_confirm), Runnable {
|
||||||
|
aapsLogger.debug("USER ENTRY: RESET DATABASES")
|
||||||
|
compositeDisposable.add(
|
||||||
|
fromAction {
|
||||||
MainApp.getDbHelper().resetDatabases()
|
MainApp.getDbHelper().resetDatabases()
|
||||||
// should be handled by Plugin-Interface and
|
// should be handled by Plugin-Interface and
|
||||||
// additional service interface and plugin registry
|
// additional service interface and plugin registry
|
||||||
foodPlugin.service?.resetFood()
|
foodPlugin.service?.resetFood()
|
||||||
treatmentsPlugin.service.resetTreatments()
|
treatmentsPlugin.service.resetTreatments()
|
||||||
|
repository.clearDatabases()
|
||||||
|
}
|
||||||
|
.subscribeOn(aapsSchedulers.io)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribeBy(
|
||||||
|
onError = { aapsLogger.error("Error clearing databases", it) },
|
||||||
|
onComplete = { rxBus.send(EventNewBG(null)) }
|
||||||
|
)
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.navExport.setOnClickListener {
|
binding.navExport.setOnClickListener {
|
||||||
|
aapsLogger.debug("USER ENTRY: EXPORT SETTINGS")
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
importExportPrefs.verifyStoragePermissions(this) {
|
importExportPrefs.verifyStoragePermissions(this) {
|
||||||
importExportPrefs.exportSharedPreferences(this)
|
importExportPrefs.exportSharedPreferences(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.navImport.setOnClickListener {
|
binding.navImport.setOnClickListener {
|
||||||
|
aapsLogger.debug("USER ENTRY: IMPORT SETTINGS")
|
||||||
// start activity for checking permissions...
|
// start activity for checking permissions...
|
||||||
importExportPrefs.verifyStoragePermissions(this) {
|
importExportPrefs.verifyStoragePermissions(this) {
|
||||||
importExportPrefs.importSharedPreferences(this)
|
importExportPrefs.importSharedPreferences(this)
|
||||||
|
@ -70,6 +100,7 @@ class MaintenanceFragment : DaggerFragment() {
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
compositeDisposable.clear()
|
||||||
_binding = null
|
_binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient.data;
|
package info.nightscout.androidaps.plugins.general.nsclient.data;
|
||||||
|
|
||||||
import android.text.Html;
|
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
@ -15,7 +14,6 @@ import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.Config;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.interfaces.ConfigInterface;
|
import info.nightscout.androidaps.interfaces.ConfigInterface;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
|
@ -475,8 +473,8 @@ public class NSDeviceStatus {
|
||||||
|
|
||||||
public static APSResult getAPSResult(HasAndroidInjector injector) {
|
public static APSResult getAPSResult(HasAndroidInjector injector) {
|
||||||
APSResult result = new APSResult(injector);
|
APSResult result = new APSResult(injector);
|
||||||
result.json = deviceStatusOpenAPSData.suggested;
|
result.setJson(deviceStatusOpenAPSData.suggested);
|
||||||
result.date = deviceStatusOpenAPSData.clockSuggested;
|
result.setDate(deviceStatusOpenAPSData.clockSuggested);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.BuildConfig
|
import info.nightscout.androidaps.BuildConfig
|
||||||
import info.nightscout.androidaps.MainApp
|
import info.nightscout.androidaps.MainApp
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.db.*
|
import info.nightscout.androidaps.db.*
|
||||||
import info.nightscout.androidaps.events.EventPreferenceChange
|
import info.nightscout.androidaps.events.EventPreferenceChange
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
@ -56,7 +58,8 @@ class OpenHumansUploader @Inject constructor(
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val rxBus: RxBusWrapper,
|
private val rxBus: RxBusWrapper,
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
private val treatmentsPlugin: TreatmentsPlugin
|
private val treatmentsPlugin: TreatmentsPlugin,
|
||||||
|
val repository: AppRepository
|
||||||
) : PluginBase(
|
) : PluginBase(
|
||||||
PluginDescription()
|
PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
|
@ -161,15 +164,15 @@ class OpenHumansUploader @Inject constructor(
|
||||||
super.onStop()
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun enqueueBGReading(bgReading: BgReading?) = bgReading?.let {
|
fun enqueueBGReading(glucoseValue: GlucoseValue?) = glucoseValue?.let {
|
||||||
insertQueueItem("BgReadings") {
|
insertQueueItem("BgReadings") {
|
||||||
put("date", bgReading.date)
|
put("date", glucoseValue.timestamp)
|
||||||
put("isValid", bgReading.isValid)
|
put("isValid", glucoseValue.isValid)
|
||||||
put("value", bgReading.value)
|
put("value", glucoseValue.value)
|
||||||
put("direction", bgReading.direction)
|
put("direction", glucoseValue.trendArrow)
|
||||||
put("raw", bgReading.raw)
|
put("raw", glucoseValue.raw)
|
||||||
put("source", bgReading.source)
|
put("source", glucoseValue.sourceSensor)
|
||||||
put("nsId", bgReading._id)
|
put("nsId", glucoseValue.interfaceIDs.nightscoutId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +366,7 @@ class OpenHumansUploader @Inject constructor(
|
||||||
.flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.treatmentData) } }
|
.flatMapObservable { Observable.defer { Observable.fromIterable(treatmentsPlugin.service.treatmentData) } }
|
||||||
.map { enqueueTreatment(it); increaseCounter() }
|
.map { enqueueTreatment(it); increaseCounter() }
|
||||||
.ignoreElements()
|
.ignoreElements()
|
||||||
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allBgReadings) })
|
.andThen(Observable.defer { Observable.fromIterable(repository.compatGetBgReadingsDataFromTime(0, true).blockingGet()) })
|
||||||
.map { enqueueBGReading(it); increaseCounter() }
|
.map { enqueueBGReading(it); increaseCounter() }
|
||||||
.ignoreElements()
|
.ignoreElements()
|
||||||
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allCareportalEvents) })
|
.andThen(Observable.defer { Observable.fromIterable(MainApp.getDbHelper().allCareportalEvents) })
|
||||||
|
|
|
@ -56,6 +56,7 @@ import info.nightscout.androidaps.skins.SkinProvider
|
||||||
import info.nightscout.androidaps.utils.*
|
import info.nightscout.androidaps.utils.*
|
||||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
|
import info.nightscout.androidaps.utils.extensions.directionToIcon
|
||||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
import info.nightscout.androidaps.utils.protection.ProtectionCheck
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
@ -94,6 +95,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||||
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
||||||
|
@Inject lateinit var dexcomMediator: DexcomPlugin.DexcomMediator
|
||||||
@Inject lateinit var xdripPlugin: XdripPlugin
|
@Inject lateinit var xdripPlugin: XdripPlugin
|
||||||
@Inject lateinit var notificationStore: NotificationStore
|
@Inject lateinit var notificationStore: NotificationStore
|
||||||
@Inject lateinit var actionStringHandler: ActionStringHandler
|
@Inject lateinit var actionStringHandler: ActionStringHandler
|
||||||
|
@ -308,7 +310,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
if (xdripPlugin.isEnabled(PluginType.BGSOURCE))
|
if (xdripPlugin.isEnabled(PluginType.BGSOURCE))
|
||||||
openCgmApp("com.eveningoutpost.dexdrip")
|
openCgmApp("com.eveningoutpost.dexdrip")
|
||||||
else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
||||||
dexcomPlugin.findDexcomPackageName()?.let {
|
dexcomMediator.findDexcomPackageName()?.let {
|
||||||
openCgmApp(it)
|
openCgmApp(it)
|
||||||
}
|
}
|
||||||
?: ToastUtils.showToastInUiThread(activity, resourceHelper.gs(R.string.dexcom_app_not_installed))
|
?: ToastUtils.showToastInUiThread(activity, resourceHelper.gs(R.string.dexcom_app_not_installed))
|
||||||
|
@ -320,7 +322,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
CalibrationDialog().show(childFragmentManager, "CalibrationDialog")
|
CalibrationDialog().show(childFragmentManager, "CalibrationDialog")
|
||||||
} else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
} else if (dexcomPlugin.isEnabled(PluginType.BGSOURCE)) {
|
||||||
try {
|
try {
|
||||||
dexcomPlugin.findDexcomPackageName()?.let {
|
dexcomMediator.findDexcomPackageName()?.let {
|
||||||
startActivity(Intent("com.dexcom.cgm.activities.MeterEntryActivity").setPackage(it))
|
startActivity(Intent("com.dexcom.cgm.activities.MeterEntryActivity").setPackage(it))
|
||||||
}
|
}
|
||||||
?: ToastUtils.showToastInUiThread(activity, resourceHelper.gs(R.string.dexcom_app_not_installed))
|
?: ToastUtils.showToastInUiThread(activity, resourceHelper.gs(R.string.dexcom_app_not_installed))
|
||||||
|
@ -575,9 +577,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
else -> resourceHelper.gc(R.color.inrange)
|
else -> resourceHelper.gc(R.color.inrange)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.infoLayout.bg.text = lastBG.valueToUnitsToString(units)
|
binding.infoLayout.bg.text = lastBG.valueToUnitsString(units)
|
||||||
binding.infoLayout.bg.setTextColor(color)
|
binding.infoLayout.bg.setTextColor(color)
|
||||||
binding.infoLayout.arrow.setImageResource(lastBG.directionToIcon(databaseHelper))
|
binding.infoLayout.arrow.setImageResource(lastBG.trendArrow.directionToIcon())
|
||||||
binding.infoLayout.arrow.setColorFilter(color)
|
binding.infoLayout.arrow.setColorFilter(color)
|
||||||
|
|
||||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
||||||
|
@ -601,8 +603,8 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
|
||||||
} else flag and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
} else flag and Paint.STRIKE_THRU_TEXT_FLAG.inv()
|
||||||
overview_bg.paintFlags = flag
|
overview_bg.paintFlags = flag
|
||||||
}
|
}
|
||||||
binding.infoLayout.timeAgo.text = DateUtil.minAgo(resourceHelper, lastBG.date)
|
binding.infoLayout.timeAgo.text = DateUtil.minAgo(resourceHelper, lastBG.timestamp)
|
||||||
binding.infoLayout.timeAgoShort.text = "(" + DateUtil.minAgoShort(lastBG.date) + ")"
|
binding.infoLayout.timeAgoShort.text = "(" + DateUtil.minAgoShort(lastBG.timestamp) + ")"
|
||||||
|
|
||||||
}
|
}
|
||||||
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
|
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
|
||||||
|
|
|
@ -12,9 +12,10 @@ import dagger.android.HasAndroidInjector
|
||||||
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.GlucoseValueDataPoint
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.LoopInterface
|
import info.nightscout.androidaps.interfaces.LoopInterface
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
@ -35,7 +36,7 @@ import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class GraphData(
|
class GraphData(
|
||||||
injector: HasAndroidInjector,
|
private val injector: HasAndroidInjector,
|
||||||
private val graph: GraphView,
|
private val graph: GraphView,
|
||||||
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
private val iobCobCalculatorPlugin: IobCobCalculatorPlugin,
|
||||||
private val treatmentsPlugin: TreatmentsInterface
|
private val treatmentsPlugin: TreatmentsInterface
|
||||||
|
@ -50,7 +51,7 @@ class GraphData(
|
||||||
|
|
||||||
var maxY = Double.MIN_VALUE
|
var maxY = Double.MIN_VALUE
|
||||||
private var minY = Double.MAX_VALUE
|
private var minY = Double.MAX_VALUE
|
||||||
private var bgReadingsArray: List<BgReading>? = null
|
private var bgReadingsArray: List<GlucoseValue>? = null
|
||||||
private val units: String
|
private val units: String
|
||||||
private val series: MutableList<Series<*>> = ArrayList()
|
private val series: MutableList<Series<*>> = ArrayList()
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ class GraphData(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun addBgReadings(fromTime: Long, toTime: Long, lowLine: Double, highLine: Double, predictions: MutableList<BgReading>?) {
|
fun addBgReadings(fromTime: Long, toTime: Long, lowLine: Double, highLine: Double, predictions: MutableList<GlucoseValueDataPoint>?) {
|
||||||
var maxBgValue = Double.MIN_VALUE
|
var maxBgValue = Double.MIN_VALUE
|
||||||
bgReadingsArray = iobCobCalculatorPlugin.bgReadings
|
bgReadingsArray = iobCobCalculatorPlugin.bgReadings
|
||||||
if (bgReadingsArray?.isEmpty() != false) {
|
if (bgReadingsArray?.isEmpty() != false) {
|
||||||
|
@ -71,13 +72,13 @@ class GraphData(
|
||||||
}
|
}
|
||||||
val bgListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
val bgListArray: MutableList<DataPointWithLabelInterface> = ArrayList()
|
||||||
for (bg in bgReadingsArray!!) {
|
for (bg in bgReadingsArray!!) {
|
||||||
if (bg.date < fromTime || bg.date > toTime) continue
|
if (bg.timestamp < fromTime || bg.timestamp > toTime) continue
|
||||||
if (bg.value > maxBgValue) maxBgValue = bg.value
|
if (bg.value > maxBgValue) maxBgValue = bg.value
|
||||||
bgListArray.add(bg)
|
bgListArray.add(GlucoseValueDataPoint(injector, bg))
|
||||||
}
|
}
|
||||||
if (predictions != null) {
|
if (predictions != null) {
|
||||||
predictions.sortWith(Comparator { o1: BgReading, o2: BgReading -> o1.x.compareTo(o2.x) })
|
predictions.sortWith(Comparator { o1: GlucoseValueDataPoint, o2: GlucoseValueDataPoint -> o1.x.compareTo(o2.x) })
|
||||||
for (prediction in predictions) if (prediction.value >= 40) bgListArray.add(prediction)
|
for (prediction in predictions) if (prediction.data.value >= 40) bgListArray.add(prediction)
|
||||||
}
|
}
|
||||||
maxBgValue = Profile.fromMgdlToUnits(maxBgValue, units)
|
maxBgValue = Profile.fromMgdlToUnits(maxBgValue, units)
|
||||||
maxBgValue = addUpperChartMargin(maxBgValue)
|
maxBgValue = addUpperChartMargin(maxBgValue)
|
||||||
|
@ -212,8 +213,7 @@ class GraphData(
|
||||||
var time = fromTime
|
var time = fromTime
|
||||||
while (time < toTime) {
|
while (time < toTime) {
|
||||||
val tt = treatmentsPlugin.getTempTargetFromHistory(time)
|
val tt = treatmentsPlugin.getTempTargetFromHistory(time)
|
||||||
var value: Double
|
val value: Double = if (tt == null) {
|
||||||
value = if (tt == null) {
|
|
||||||
Profile.fromMgdlToUnits((profile.getTargetLowMgdl(time) + profile.getTargetHighMgdl(time)) / 2, units)
|
Profile.fromMgdlToUnits((profile.getTargetLowMgdl(time) + profile.getTargetHighMgdl(time)) / 2, units)
|
||||||
} else {
|
} else {
|
||||||
Profile.fromMgdlToUnits(tt.target(), units)
|
Profile.fromMgdlToUnits(tt.target(), units)
|
||||||
|
@ -282,7 +282,7 @@ class GraphData(
|
||||||
bgReadingsArray?.let { bgReadingsArray ->
|
bgReadingsArray?.let { bgReadingsArray ->
|
||||||
for (r in bgReadingsArray.indices) {
|
for (r in bgReadingsArray.indices) {
|
||||||
val reading = bgReadingsArray[r]
|
val reading = bgReadingsArray[r]
|
||||||
if (reading.date > date) continue
|
if (reading.timestamp > date) continue
|
||||||
return Profile.fromMgdlToUnits(reading.value, units)
|
return Profile.fromMgdlToUnits(reading.value, units)
|
||||||
}
|
}
|
||||||
return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].value, units) else Profile.fromMgdlToUnits(100.0, units)
|
return if (bgReadingsArray.isNotEmpty()) Profile.fromMgdlToUnits(bgReadingsArray[0].value, units) else Profile.fromMgdlToUnits(100.0, units)
|
||||||
|
|
|
@ -25,6 +25,7 @@ import info.nightscout.androidaps.utils.androidNotification.openAppIntent
|
||||||
import info.nightscout.androidaps.utils.resources.IconsProvider
|
import info.nightscout.androidaps.utils.resources.IconsProvider
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.androidaps.utils.valueToUnitsString
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -135,12 +136,12 @@ class PersistentNotificationPlugin @Inject constructor(
|
||||||
val lastBG = iobCobCalculatorPlugin.lastBg()
|
val lastBG = iobCobCalculatorPlugin.lastBg()
|
||||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
||||||
if (lastBG != null) {
|
if (lastBG != null) {
|
||||||
line1aa = lastBG.valueToUnitsToString(units)
|
line1aa = lastBG.valueToUnitsString(units)
|
||||||
line1 = line1aa
|
line1 = line1aa
|
||||||
if (glucoseStatus != null) {
|
if (glucoseStatus != null) {
|
||||||
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
|
line1 += (" Δ" + Profile.toSignedUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units)
|
||||||
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units))
|
+ " avgΔ" + Profile.toSignedUnitsString(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units))
|
||||||
line1aa += " " + lastBG.directionToSymbol(databaseHelper)
|
line1aa += " " + lastBG.trendArrow.symbol
|
||||||
} else {
|
} else {
|
||||||
line1 += " " +
|
line1 += " " +
|
||||||
resourceHelper.gs(R.string.old_data) +
|
resourceHelper.gs(R.string.old_data) +
|
||||||
|
|
|
@ -305,11 +305,11 @@ class SmsCommunicatorPlugin @Inject constructor(
|
||||||
var reply = ""
|
var reply = ""
|
||||||
val units = profileFunction.getUnits()
|
val units = profileFunction.getUnits()
|
||||||
if (actualBG != null) {
|
if (actualBG != null) {
|
||||||
reply = resourceHelper.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsToString(units) + ", "
|
reply = resourceHelper.gs(R.string.sms_actualbg) + " " + actualBG.valueToUnitsString(units) + ", "
|
||||||
} else if (lastBG != null) {
|
} else if (lastBG != null) {
|
||||||
val agoMsec = System.currentTimeMillis() - lastBG.date
|
val agoMsec = System.currentTimeMillis() - lastBG.timestamp
|
||||||
val agoMin = (agoMsec / 60.0 / 1000.0).toInt()
|
val agoMin = (agoMsec / 60.0 / 1000.0).toInt()
|
||||||
reply = resourceHelper.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsToString(units) + " " + String.format(resourceHelper.gs(R.string.sms_minago), agoMin) + ", "
|
reply = resourceHelper.gs(R.string.sms_lastbg) + " " + lastBG.valueToUnitsString(units) + " " + String.format(resourceHelper.gs(R.string.sms_minago), agoMin) + ", "
|
||||||
}
|
}
|
||||||
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
val glucoseStatus = GlucoseStatus(injector).glucoseStatusData
|
||||||
if (glucoseStatus != null) reply += resourceHelper.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
|
if (glucoseStatus != null) reply += resourceHelper.gs(R.string.sms_delta) + " " + Profile.toUnitsString(glucoseStatus.delta, glucoseStatus.delta * Constants.MGDL_TO_MMOLL, units) + " " + units + ", "
|
||||||
|
|
|
@ -93,11 +93,11 @@ class TidepoolPlugin @Inject constructor(
|
||||||
disposable += rxBus
|
disposable += rxBus
|
||||||
.toObservable(EventNewBG::class.java)
|
.toObservable(EventNewBG::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.filter { it.bgReading != null } // better would be optional in API level >24
|
.filter { it.glucoseValue != null } // better would be optional in API level >24
|
||||||
.map { it.bgReading }
|
.map { it.glucoseValue }
|
||||||
.subscribe({ bgReading ->
|
.subscribe({ bgReading ->
|
||||||
if (bgReading!!.date < uploadChunk.getLastEnd())
|
if (bgReading!!.timestamp < uploadChunk.getLastEnd())
|
||||||
uploadChunk.setLastEnd(bgReading.date)
|
uploadChunk.setLastEnd(bgReading.timestamp )
|
||||||
if (isEnabled(PluginType.GENERAL)
|
if (isEnabled(PluginType.GENERAL)
|
||||||
&& (!sp.getBoolean(R.string.key_tidepool_only_while_charging, false) || receiverStatusStore.isCharging)
|
&& (!sp.getBoolean(R.string.key_tidepool_only_while_charging, false) || receiverStatusStore.isCharging)
|
||||||
&& (!sp.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || receiverStatusStore.isWifiConnected)
|
&& (!sp.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || receiverStatusStore.isWifiConnected)
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package info.nightscout.androidaps.plugins.general.tidepool.comm
|
package info.nightscout.androidaps.plugins.general.tidepool.comm
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
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.Intervals
|
import info.nightscout.androidaps.data.Intervals
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.db.ProfileSwitch
|
import info.nightscout.androidaps.db.ProfileSwitch
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal
|
import info.nightscout.androidaps.db.TemporaryBasal
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.elements.*
|
import info.nightscout.androidaps.plugins.general.tidepool.elements.*
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
|
import info.nightscout.androidaps.plugins.general.tidepool.events.EventTidepoolStatus
|
||||||
import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance
|
import info.nightscout.androidaps.plugins.general.tidepool.utils.GsonInstance
|
||||||
|
@ -24,12 +26,14 @@ import kotlin.math.max
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class UploadChunk @Inject constructor(
|
class UploadChunk @Inject constructor(
|
||||||
|
private val injector: HasAndroidInjector,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val rxBus: RxBusWrapper,
|
private val rxBus: RxBusWrapper,
|
||||||
private val aapsLogger: AAPSLogger,
|
private val aapsLogger: AAPSLogger,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val treatmentsPlugin: TreatmentsPlugin,
|
private val treatmentsPlugin: TreatmentsPlugin,
|
||||||
private val activePlugin: ActivePluginProvider,
|
private val activePlugin: ActivePluginProvider,
|
||||||
|
private val repository: AppRepository,
|
||||||
private val dateUtil: DateUtil
|
private val dateUtil: DateUtil
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
@ -102,9 +106,10 @@ class UploadChunk @Inject constructor(
|
||||||
val start: Long = 0
|
val start: Long = 0
|
||||||
val end = DateUtil.now()
|
val end = DateUtil.now()
|
||||||
|
|
||||||
val bgReadingList = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
|
val bgReadingList = repository.compatGetBgReadingsDataFromTime(start, end, true)
|
||||||
return if (bgReadingList.size > 0)
|
.blockingGet()
|
||||||
bgReadingList[0].date
|
return if (bgReadingList.isNotEmpty())
|
||||||
|
bgReadingList[0].timestamp
|
||||||
else -1
|
else -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +136,8 @@ class UploadChunk @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBgReadings(start: Long, end: Long): List<SensorGlucoseElement> {
|
private fun getBgReadings(start: Long, end: Long): List<SensorGlucoseElement> {
|
||||||
val readings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, end, true)
|
val readings = repository.compatGetBgReadingsDataFromTime(start, end, true)
|
||||||
|
.blockingGet()
|
||||||
val selection = SensorGlucoseElement.fromBgReadings(readings)
|
val selection = SensorGlucoseElement.fromBgReadings(readings)
|
||||||
if (selection.isNotEmpty())
|
if (selection.isNotEmpty())
|
||||||
rxBus.send(EventTidepoolStatus("${selection.size} CGMs selected for upload"))
|
rxBus.send(EventTidepoolStatus("${selection.size} CGMs selected for upload"))
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
package info.nightscout.androidaps.plugins.general.tidepool.elements
|
||||||
|
|
||||||
import com.google.gson.annotations.Expose
|
import com.google.gson.annotations.Expose
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class SensorGlucoseElement(bgReading: BgReading)
|
class SensorGlucoseElement(bgReading: GlucoseValue)
|
||||||
: BaseElement(bgReading.date, UUID.nameUUIDFromBytes(("AAPS-cgm" + bgReading.date).toByteArray()).toString()) {
|
: BaseElement(bgReading.timestamp, UUID.nameUUIDFromBytes(("AAPS-cgm" + bgReading.timestamp).toByteArray()).toString()) {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
internal var units: String = "mg/dL"
|
internal var units: String = "mg/dL"
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
internal var value: Int = 0
|
internal var value: Int = 0
|
||||||
|
|
||||||
|
@ -18,7 +19,8 @@ class SensorGlucoseElement(bgReading: BgReading)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal fun fromBgReadings(bgReadingList: List<BgReading>): List<SensorGlucoseElement> {
|
|
||||||
|
internal fun fromBgReadings(bgReadingList: List<GlucoseValue>): List<SensorGlucoseElement> {
|
||||||
val results = LinkedList<SensorGlucoseElement>()
|
val results = LinkedList<SensorGlucoseElement>()
|
||||||
for (bgReading in bgReadingList) {
|
for (bgReading in bgReadingList) {
|
||||||
results.add(SensorGlucoseElement(bgReading))
|
results.add(SensorGlucoseElement(bgReading))
|
||||||
|
|
|
@ -31,11 +31,7 @@ import info.nightscout.androidaps.danaRv2.DanaRv2Plugin
|
||||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
|
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
|
||||||
import info.nightscout.androidaps.queue.Callback
|
import info.nightscout.androidaps.queue.Callback
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.*
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter
|
|
||||||
import info.nightscout.androidaps.utils.HardLimits
|
|
||||||
import info.nightscout.androidaps.utils.SafeParse
|
|
||||||
import info.nightscout.androidaps.utils.ToastUtils
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||||
|
|
|
@ -31,32 +31,33 @@ import dagger.android.AndroidInjection;
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
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.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.data.GlucoseValueDataPoint;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.database.AppRepository;
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
||||||
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
|
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
||||||
|
import info.nightscout.androidaps.utils.GlucoseValueUtilsKt;
|
||||||
import info.nightscout.androidaps.utils.ToastUtils;
|
import info.nightscout.androidaps.utils.ToastUtils;
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||||
import kotlin.Suppress;
|
|
||||||
|
|
||||||
public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
|
public class WatchUpdaterService extends WearableListenerService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
|
||||||
@Inject public HasAndroidInjector injector;
|
@Inject public HasAndroidInjector injector;
|
||||||
|
@ -72,6 +73,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
@Inject public IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
@Inject public IobCobCalculatorPlugin iobCobCalculatorPlugin;
|
||||||
@Inject public TreatmentsPlugin treatmentsPlugin;
|
@Inject public TreatmentsPlugin treatmentsPlugin;
|
||||||
@Inject public ActionStringHandler actionStringHandler;
|
@Inject public ActionStringHandler actionStringHandler;
|
||||||
|
@Inject public AppRepository repository;
|
||||||
@Inject ReceiverStatusStore receiverStatusStore;
|
@Inject ReceiverStatusStore receiverStatusStore;
|
||||||
@Inject Config config;
|
@Inject Config config;
|
||||||
|
|
||||||
|
@ -275,7 +277,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
|
|
||||||
private void sendData() {
|
private void sendData() {
|
||||||
|
|
||||||
BgReading lastBG = iobCobCalculatorPlugin.lastBg();
|
GlucoseValue lastBG = iobCobCalculatorPlugin.lastBg();
|
||||||
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
|
// Log.d(TAG, logPrefix + "LastBg=" + lastBG);
|
||||||
if (lastBG != null) {
|
if (lastBG != null) {
|
||||||
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData();
|
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData();
|
||||||
|
@ -297,25 +299,25 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private DataMap dataMapSingleBG(BgReading lastBG, GlucoseStatus glucoseStatus) {
|
private DataMap dataMapSingleBG(GlucoseValue lastBG, GlucoseStatus glucoseStatus) {
|
||||||
String units = profileFunction.getUnits();
|
String units = profileFunction.getUnits();
|
||||||
double convert2MGDL = 1.0;
|
double convert2MGDL = 1.0;
|
||||||
if (units.equals(Constants.MMOL))
|
if (units.equals(Constants.MMOL))
|
||||||
convert2MGDL = Constants.MMOLL_TO_MGDL;
|
convert2MGDL = Constants.MMOLL_TO_MGDL;
|
||||||
double lowLine = defaultValueHelper.determineLowLine()*convert2MGDL;
|
double lowLine = defaultValueHelper.determineLowLine() * convert2MGDL;
|
||||||
double highLine = defaultValueHelper.determineHighLine()*convert2MGDL;
|
double highLine = defaultValueHelper.determineHighLine() * convert2MGDL;
|
||||||
|
|
||||||
long sgvLevel = 0L;
|
long sgvLevel = 0L;
|
||||||
if (lastBG.value > highLine) {
|
if (lastBG.getValue() > highLine) {
|
||||||
sgvLevel = 1;
|
sgvLevel = 1;
|
||||||
} else if (lastBG.value < lowLine) {
|
} else if (lastBG.getValue() < lowLine) {
|
||||||
sgvLevel = -1;
|
sgvLevel = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataMap dataMap = new DataMap();
|
DataMap dataMap = new DataMap();
|
||||||
dataMap.putString("sgvString", lastBG.valueToUnitsToString(units));
|
dataMap.putString("sgvString", GlucoseValueUtilsKt.valueToUnitsString(lastBG, units));
|
||||||
dataMap.putString("glucoseUnits", units);
|
dataMap.putString("glucoseUnits", units);
|
||||||
dataMap.putLong("timestamp", lastBG.date);
|
dataMap.putLong("timestamp", lastBG.getTimestamp());
|
||||||
if (glucoseStatus == null) {
|
if (glucoseStatus == null) {
|
||||||
dataMap.putString("slopeArrow", "");
|
dataMap.putString("slopeArrow", "");
|
||||||
dataMap.putString("delta", "--");
|
dataMap.putString("delta", "--");
|
||||||
|
@ -326,7 +328,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units));
|
dataMap.putString("avgDelta", deltastring(glucoseStatus.avgdelta, glucoseStatus.avgdelta * Constants.MGDL_TO_MMOLL, units));
|
||||||
}
|
}
|
||||||
dataMap.putLong("sgvLevel", sgvLevel);
|
dataMap.putLong("sgvLevel", sgvLevel);
|
||||||
dataMap.putDouble("sgvDouble", lastBG.value);
|
dataMap.putDouble("sgvDouble", lastBG.getValue());
|
||||||
dataMap.putDouble("high", highLine);
|
dataMap.putDouble("high", highLine);
|
||||||
dataMap.putDouble("low", lowLine);
|
dataMap.putDouble("low", lowLine);
|
||||||
return dataMap;
|
return dataMap;
|
||||||
|
@ -381,11 +383,11 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
googleApiConnect();
|
googleApiConnect();
|
||||||
}
|
}
|
||||||
long startTime = System.currentTimeMillis() - (long) (60000 * 60 * 5.5);
|
long startTime = System.currentTimeMillis() - (long) (60000 * 60 * 5.5);
|
||||||
BgReading last_bg = iobCobCalculatorPlugin.lastBg();
|
GlucoseValue last_bg = iobCobCalculatorPlugin.lastBg();
|
||||||
|
|
||||||
if (last_bg == null) return;
|
if (last_bg == null) return;
|
||||||
|
|
||||||
List<BgReading> graph_bgs = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, true);
|
List<GlucoseValue> graph_bgs = repository.compatGetBgReadingsDataFromTime(startTime, true).blockingGet();
|
||||||
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData(true);
|
GlucoseStatus glucoseStatus = new GlucoseStatus(injector).getGlucoseStatusData(true);
|
||||||
|
|
||||||
if (!graph_bgs.isEmpty()) {
|
if (!graph_bgs.isEmpty()) {
|
||||||
|
@ -395,7 +397,7 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final ArrayList<DataMap> dataMaps = new ArrayList<>(graph_bgs.size());
|
final ArrayList<DataMap> dataMaps = new ArrayList<>(graph_bgs.size());
|
||||||
for (BgReading bg : graph_bgs) {
|
for (GlucoseValue bg : graph_bgs) {
|
||||||
DataMap dataMap = dataMapSingleBG(bg, glucoseStatus);
|
DataMap dataMap = dataMapSingleBG(bg, glucoseStatus);
|
||||||
if (dataMap != null) {
|
if (dataMap != null) {
|
||||||
dataMaps.add(dataMap);
|
dataMaps.add(dataMap);
|
||||||
|
@ -535,14 +537,14 @@ public class WatchUpdaterService extends WearableListenerService implements Goog
|
||||||
}
|
}
|
||||||
|
|
||||||
final LoopPlugin.LastRun finalLastRun = loopPlugin.getLastRun();
|
final LoopPlugin.LastRun finalLastRun = loopPlugin.getLastRun();
|
||||||
if (sp.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.getRequest().hasPredictions && finalLastRun.getConstraintsProcessed() != null) {
|
if (sp.getBoolean("wear_predictions", true) && finalLastRun != null && finalLastRun.getRequest().getHasPredictions() && finalLastRun.getConstraintsProcessed() != null) {
|
||||||
List<BgReading> predArray = finalLastRun.getConstraintsProcessed().getPredictions();
|
List<GlucoseValueDataPoint> predArray = finalLastRun.getConstraintsProcessed().getPredictions();
|
||||||
|
|
||||||
if (!predArray.isEmpty()) {
|
if (!predArray.isEmpty()) {
|
||||||
final String units = profileFunction.getUnits();
|
final String units = profileFunction.getUnits();
|
||||||
for (BgReading bg : predArray) {
|
for (GlucoseValueDataPoint bg : predArray) {
|
||||||
if (bg.value < 40) continue;
|
if (bg.getData().getValue() < 40) continue;
|
||||||
predictions.add(predictionMap(bg.date, bg.value, bg.getPredectionColor()));
|
predictions.add(predictionMap(bg.getData().getTimestamp(), bg.getData().getValue(), bg.getPredictionColor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import java.util.List;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.database.entities.GlucoseValue;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
@ -71,7 +71,7 @@ public class GlucoseStatus {
|
||||||
|
|
||||||
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
||||||
|
|
||||||
List<BgReading> data = iobCobCalculatorPlugin.getBgReadings();
|
List<GlucoseValue> data = iobCobCalculatorPlugin.getBgReadings();
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
aapsLogger.debug(LTag.GLUCOSE, "data=null");
|
aapsLogger.debug(LTag.GLUCOSE, "data=null");
|
||||||
|
@ -84,18 +84,18 @@ public class GlucoseStatus {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
if (data.get(0).getTimestamp() < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||||
aapsLogger.debug(LTag.GLUCOSE, "olddata");
|
aapsLogger.debug(LTag.GLUCOSE, "olddata");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
BgReading now = data.get(0);
|
GlucoseValue now = data.get(0);
|
||||||
long now_date = now.date;
|
long now_date = now.getTimestamp();
|
||||||
double change;
|
double change;
|
||||||
|
|
||||||
if (sizeRecords == 1) {
|
if (sizeRecords == 1) {
|
||||||
GlucoseStatus status = new GlucoseStatus(injector);
|
GlucoseStatus status = new GlucoseStatus(injector);
|
||||||
status.glucose = now.value;
|
status.glucose = now.getValue();
|
||||||
status.noise = 0d;
|
status.noise = 0d;
|
||||||
status.short_avgdelta = 0d;
|
status.short_avgdelta = 0d;
|
||||||
status.delta = 0d;
|
status.delta = 0d;
|
||||||
|
@ -112,18 +112,18 @@ public class GlucoseStatus {
|
||||||
ArrayList<Double> long_deltas = new ArrayList<>();
|
ArrayList<Double> long_deltas = new ArrayList<>();
|
||||||
|
|
||||||
// Use the latest sgv value in the now calculations
|
// Use the latest sgv value in the now calculations
|
||||||
now_value_list.add(now.value);
|
now_value_list.add(now.getValue());
|
||||||
|
|
||||||
for (int i = 1; i < sizeRecords; i++) {
|
for (int i = 1; i < sizeRecords; i++) {
|
||||||
if (data.get(i).value > 38) {
|
if (data.get(i).getValue() > 38) {
|
||||||
BgReading then = data.get(i);
|
GlucoseValue then = data.get(i);
|
||||||
long then_date = then.date;
|
long then_date = then.getTimestamp();
|
||||||
double avgdelta;
|
double avgdelta;
|
||||||
long minutesago;
|
long minutesago;
|
||||||
|
|
||||||
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
||||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||||
change = now.value - then.value;
|
change = now.getValue() - then.getValue();
|
||||||
avgdelta = change / minutesago * 5;
|
avgdelta = change / minutesago * 5;
|
||||||
|
|
||||||
aapsLogger.debug(LTag.GLUCOSE, then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
aapsLogger.debug(LTag.GLUCOSE, then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
||||||
|
@ -131,8 +131,8 @@ public class GlucoseStatus {
|
||||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||||
if (0 < minutesago && minutesago < 2.5) {
|
if (0 < minutesago && minutesago < 2.5) {
|
||||||
// Keep and average all values within the last 2.5 minutes
|
// Keep and average all values within the last 2.5 minutes
|
||||||
now_value_list.add(then.value);
|
now_value_list.add(then.getValue());
|
||||||
now.value = average(now_value_list);
|
now.setValue(average(now_value_list));
|
||||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||||
} else if (2.5 < minutesago && minutesago < 17.5) {
|
} else if (2.5 < minutesago && minutesago < 17.5) {
|
||||||
//console.error(minutesago, avgdelta);
|
//console.error(minutesago, avgdelta);
|
||||||
|
@ -152,7 +152,7 @@ public class GlucoseStatus {
|
||||||
}
|
}
|
||||||
|
|
||||||
GlucoseStatus status = new GlucoseStatus(injector);
|
GlucoseStatus status = new GlucoseStatus(injector);
|
||||||
status.glucose = now.value;
|
status.glucose = now.getValue();
|
||||||
status.date = now_date;
|
status.date = now_date;
|
||||||
status.noise = 0d; //for now set to nothing as not all CGMs report noise
|
status.noise = 0d; //for now set to nothing as not all CGMs report noise
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
|
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
|
||||||
class InMemoryGlucoseValue @JvmOverloads constructor(var timestamp: Long = 0L, var value: Double = 0.0, var interpolated : Boolean = false) {
|
class InMemoryGlucoseValue @JvmOverloads constructor(var timestamp: Long = 0L, var value: Double = 0.0, var interpolated: Boolean = false) {
|
||||||
|
|
||||||
constructor(gv: BgReading) : this(gv.date, gv.value)
|
constructor(gv: GlucoseValue) : this(gv.timestamp, gv.value)
|
||||||
// var generated : value doesn't correspond to real value with timestamp close to real BG
|
// var generated : value doesn't correspond to real value with timestamp close to real BG
|
||||||
}
|
}
|
|
@ -10,18 +10,19 @@ import org.json.JSONArray;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
import dagger.android.HasAndroidInjector;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
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.db.BgReading;
|
import info.nightscout.androidaps.database.AppRepository;
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue;
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
|
@ -72,6 +73,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
private final SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin;
|
private final SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin;
|
||||||
private final FabricPrivacy fabricPrivacy;
|
private final FabricPrivacy fabricPrivacy;
|
||||||
private final DateUtil dateUtil;
|
private final DateUtil dateUtil;
|
||||||
|
private final AppRepository repository;
|
||||||
|
|
||||||
private final CompositeDisposable disposable = new CompositeDisposable();
|
private final CompositeDisposable disposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
@ -80,14 +82,14 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
private LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||||
private LongSparseArray<BasalData> basalDataTable = new LongSparseArray<>(); // oldest at index 0
|
private LongSparseArray<BasalData> basalDataTable = new LongSparseArray<>(); // oldest at index 0
|
||||||
|
|
||||||
|
private volatile List<GlucoseValue> bgReadings = null; // newest at index 0
|
||||||
|
private volatile List<InMemoryGlucoseValue> bucketed_data = null;
|
||||||
|
|
||||||
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
// we need to make sure that bucketed_data will always have the same timestamp for correct use of cached values
|
||||||
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
// once referenceTime != null all bucketed data should be (x * 5min) from referenceTime
|
||||||
Long referenceTime = null;
|
Long referenceTime = null;
|
||||||
private Boolean lastUsed5minCalculation = null; // true if used 5min bucketed data
|
private Boolean lastUsed5minCalculation = null; // true if used 5min bucketed data
|
||||||
|
|
||||||
private volatile List<BgReading> bgReadings = null; // newest at index 0
|
|
||||||
private volatile List<InMemoryGlucoseValue> bucketed_data = null;
|
|
||||||
|
|
||||||
private final Object dataLock = new Object();
|
private final Object dataLock = new Object();
|
||||||
|
|
||||||
boolean stopCalculationTrigger = false;
|
boolean stopCalculationTrigger = false;
|
||||||
|
@ -108,7 +110,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
SensitivityAAPSPlugin sensitivityAAPSPlugin,
|
SensitivityAAPSPlugin sensitivityAAPSPlugin,
|
||||||
SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin,
|
SensitivityWeightedAveragePlugin sensitivityWeightedAveragePlugin,
|
||||||
FabricPrivacy fabricPrivacy,
|
FabricPrivacy fabricPrivacy,
|
||||||
DateUtil dateUtil
|
DateUtil dateUtil,
|
||||||
|
AppRepository repository
|
||||||
) {
|
) {
|
||||||
super(new PluginDescription()
|
super(new PluginDescription()
|
||||||
.mainType(PluginType.GENERAL)
|
.mainType(PluginType.GENERAL)
|
||||||
|
@ -131,6 +134,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
this.sensitivityWeightedAveragePlugin = sensitivityWeightedAveragePlugin;
|
this.sensitivityWeightedAveragePlugin = sensitivityWeightedAveragePlugin;
|
||||||
this.fabricPrivacy = fabricPrivacy;
|
this.fabricPrivacy = fabricPrivacy;
|
||||||
this.dateUtil = dateUtil;
|
this.dateUtil = dateUtil;
|
||||||
|
this.repository = repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -169,6 +173,7 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
disposable.add(rxBus
|
disposable.add(rxBus
|
||||||
.toObservable(EventNewBG.class)
|
.toObservable(EventNewBG.class)
|
||||||
.observeOn(aapsSchedulers.getIo())
|
.observeOn(aapsSchedulers.getIo())
|
||||||
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
.subscribe(event -> {
|
.subscribe(event -> {
|
||||||
stopCalculation("onEventNewBG");
|
stopCalculation("onEventNewBG");
|
||||||
runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, event);
|
runCalculation("onEventNewBG", System.currentTimeMillis(), true, true, event);
|
||||||
|
@ -227,11 +232,11 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
return autosensDataTable;
|
return autosensDataTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<BgReading> getBgReadings() {
|
public List<GlucoseValue> getBgReadings() {
|
||||||
return bgReadings;
|
return bgReadings;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBgReadings(List<BgReading> bgReadings) {
|
public void setBgReadings(List<GlucoseValue> bgReadings) {
|
||||||
this.bgReadings = bgReadings;
|
this.bgReadings = bgReadings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +277,10 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
if (DateUtil.isCloseToNow(to)) {
|
if (DateUtil.isCloseToNow(to)) {
|
||||||
// if close to now expect there can be some readings with time in close future (caused by wrong time setting)
|
// if close to now expect there can be some readings with time in close future (caused by wrong time setting)
|
||||||
// so read all records
|
// so read all records
|
||||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, false);
|
bgReadings = repository.compatGetBgReadingsDataFromTime(start, false).blockingGet();
|
||||||
getAapsLogger().debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size() + " Start date: " + dateUtil.dateAndTimeString(start));
|
getAapsLogger().debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size() + " Start date: " + dateUtil.dateAndTimeString(start));
|
||||||
} else {
|
} else {
|
||||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(start, to, false);
|
bgReadings = repository.compatGetBgReadingsDataFromTime(start, to, false).blockingGet();
|
||||||
getAapsLogger().debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size() + " Start date: " + dateUtil.dateAndTimeString(start) + " End date: " + dateUtil.dateAndTimeString(to));
|
getAapsLogger().debug(LTag.AUTOSENS, "BG data loaded. Size: " + bgReadings.size() + " Start date: " + dateUtil.dateAndTimeString(start) + " End date: " + dateUtil.dateAndTimeString(to));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -287,8 +292,8 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
}
|
}
|
||||||
long totalDiff = 0;
|
long totalDiff = 0;
|
||||||
for (int i = 1; i < bgReadings.size(); ++i) {
|
for (int i = 1; i < bgReadings.size(); ++i) {
|
||||||
long bgTime = bgReadings.get(i).date;
|
long bgTime = bgReadings.get(i).getTimestamp();
|
||||||
long lastbgTime = bgReadings.get(i - 1).date;
|
long lastbgTime = bgReadings.get(i - 1).getTimestamp();
|
||||||
long diff = lastbgTime - bgTime;
|
long diff = lastbgTime - bgTime;
|
||||||
diff %= T.mins(5).msecs();
|
diff %= T.mins(5).msecs();
|
||||||
if (diff > T.mins(2).plus(T.secs(30)).msecs())
|
if (diff > T.mins(2).plus(T.secs(30)).msecs())
|
||||||
|
@ -331,27 +336,27 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BgReading findNewer(long time) {
|
public GlucoseValue findNewer(long time) {
|
||||||
BgReading lastFound = bgReadings.get(0);
|
GlucoseValue lastFound = bgReadings.get(0);
|
||||||
if (lastFound.date < time) return null;
|
if (lastFound.getTimestamp() < time) return null;
|
||||||
for (int i = 1; i < bgReadings.size(); ++i) {
|
for (int i = 1; i < bgReadings.size(); ++i) {
|
||||||
if (bgReadings.get(i).date == time) return bgReadings.get(i);
|
if (bgReadings.get(i).getTimestamp() == time) return bgReadings.get(i);
|
||||||
if (bgReadings.get(i).date > time) continue;
|
if (bgReadings.get(i).getTimestamp() > time) continue;
|
||||||
lastFound = bgReadings.get(i - 1);
|
lastFound = bgReadings.get(i - 1);
|
||||||
if (bgReadings.get(i).date < time) break;
|
if (bgReadings.get(i).getTimestamp() < time) break;
|
||||||
}
|
}
|
||||||
return lastFound;
|
return lastFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public BgReading findOlder(long time) {
|
public GlucoseValue findOlder(long time) {
|
||||||
BgReading lastFound = bgReadings.get(bgReadings.size() - 1);
|
GlucoseValue lastFound = bgReadings.get(bgReadings.size() - 1);
|
||||||
if (lastFound.date > time) return null;
|
if (lastFound.getTimestamp() > time) return null;
|
||||||
for (int i = bgReadings.size() - 2; i >= 0; --i) {
|
for (int i = bgReadings.size() - 2; i >= 0; --i) {
|
||||||
if (bgReadings.get(i).date == time) return bgReadings.get(i);
|
if (bgReadings.get(i).getTimestamp() == time) return bgReadings.get(i);
|
||||||
if (bgReadings.get(i).date < time) continue;
|
if (bgReadings.get(i).getTimestamp() < time) continue;
|
||||||
lastFound = bgReadings.get(i + 1);
|
lastFound = bgReadings.get(i + 1);
|
||||||
if (bgReadings.get(i).date > time) break;
|
if (bgReadings.get(i).getTimestamp() > time) break;
|
||||||
}
|
}
|
||||||
return lastFound;
|
return lastFound;
|
||||||
}
|
}
|
||||||
|
@ -363,25 +368,25 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
}
|
}
|
||||||
|
|
||||||
bucketed_data = new ArrayList<>();
|
bucketed_data = new ArrayList<>();
|
||||||
long currentTime = bgReadings.get(0).date - bgReadings.get(0).date % T.mins(5).msecs();
|
long currentTime = bgReadings.get(0).getTimestamp() - bgReadings.get(0).getTimestamp() % T.mins(5).msecs();
|
||||||
currentTime = adjustToReferenceTime(currentTime);
|
currentTime = adjustToReferenceTime(currentTime);
|
||||||
getAapsLogger().debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(currentTime));
|
getAapsLogger().debug("Adjusted time " + dateUtil.dateAndTimeAndSecondsString(currentTime));
|
||||||
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
|
//log.debug("First reading: " + new Date(currentTime).toLocaleString());
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// test if current value is older than current time
|
// test if current value is older than current time
|
||||||
BgReading newer = findNewer(currentTime);
|
GlucoseValue newer = findNewer(currentTime);
|
||||||
BgReading older = findOlder(currentTime);
|
GlucoseValue older = findOlder(currentTime);
|
||||||
if (newer == null || older == null)
|
if (newer == null || older == null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (older.date == newer.date) { // direct hit
|
if (older.getTimestamp() == newer.getTimestamp()) { // direct hit
|
||||||
bucketed_data.add(new InMemoryGlucoseValue(newer));
|
bucketed_data.add(new InMemoryGlucoseValue(newer));
|
||||||
} else {
|
} else {
|
||||||
double bgDelta = newer.value - older.value;
|
double bgDelta = newer.getValue() - older.getValue();
|
||||||
long timeDiffToNew = newer.date - currentTime;
|
long timeDiffToNew = newer.getTimestamp() - currentTime;
|
||||||
|
|
||||||
double currentBg = newer.value - (double) timeDiffToNew / (newer.date - older.date) * bgDelta;
|
double currentBg = newer.getValue() - (double) timeDiffToNew / (newer.getTimestamp() - older.getTimestamp()) * bgDelta;
|
||||||
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(currentTime, Math.round(currentBg), true);
|
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(currentTime, Math.round(currentBg), true);
|
||||||
bucketed_data.add(newBgreading);
|
bucketed_data.add(newBgreading);
|
||||||
//log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
|
//log.debug("BG: " + newBgreading.value + " (" + new Date(newBgreading.date).toLocaleString() + ") Prev: " + older.value + " (" + new Date(older.date).toLocaleString() + ") Newer: " + newer.value + " (" + new Date(newer.date).toLocaleString() + ")");
|
||||||
|
@ -400,27 +405,27 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
|
|
||||||
bucketed_data = new ArrayList<>();
|
bucketed_data = new ArrayList<>();
|
||||||
bucketed_data.add(new InMemoryGlucoseValue(bgReadings.get(0)));
|
bucketed_data.add(new InMemoryGlucoseValue(bgReadings.get(0)));
|
||||||
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgReadings.get(0).date) + " lastbgTime: " + "none-first-value" + " " + bgReadings.get(0).toString());
|
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgReadings.get(0).getTimestamp()) + " lastbgTime: " + "none-first-value" + " " + bgReadings.get(0).toString());
|
||||||
int j = 0;
|
int j = 0;
|
||||||
for (int i = 1; i < bgReadings.size(); ++i) {
|
for (int i = 1; i < bgReadings.size(); ++i) {
|
||||||
long bgTime = bgReadings.get(i).date;
|
long bgTime = bgReadings.get(i).getTimestamp();
|
||||||
long lastbgTime = bgReadings.get(i - 1).date;
|
long lastbgTime = bgReadings.get(i - 1).getTimestamp();
|
||||||
//log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastbgTime).toString() + " " + bgReadings.get(i - 1).value);
|
//log.error("Processing " + i + ": " + new Date(bgTime).toString() + " " + bgReadings.get(i).value + " Previous: " + new Date(lastbgTime).toString() + " " + bgReadings.get(i - 1).value);
|
||||||
if (bgReadings.get(i).value < 39 || bgReadings.get(i - 1).value < 39) {
|
if (bgReadings.get(i).getValue() < 39 || bgReadings.get(i - 1).getValue() < 39) {
|
||||||
throw new IllegalStateException("<39");
|
throw new IllegalStateException("<39");
|
||||||
}
|
}
|
||||||
|
|
||||||
long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000);
|
long elapsed_minutes = (bgTime - lastbgTime) / (60 * 1000);
|
||||||
if (Math.abs(elapsed_minutes) > 8) {
|
if (Math.abs(elapsed_minutes) > 8) {
|
||||||
// interpolate missing data points
|
// interpolate missing data points
|
||||||
double lastbg = bgReadings.get(i - 1).value;
|
double lastbg = bgReadings.get(i - 1).getValue();
|
||||||
elapsed_minutes = Math.abs(elapsed_minutes);
|
elapsed_minutes = Math.abs(elapsed_minutes);
|
||||||
//console.error(elapsed_minutes);
|
//console.error(elapsed_minutes);
|
||||||
long nextbgTime;
|
long nextbgTime;
|
||||||
while (elapsed_minutes > 5) {
|
while (elapsed_minutes > 5) {
|
||||||
nextbgTime = lastbgTime - 5 * 60 * 1000;
|
nextbgTime = lastbgTime - 5 * 60 * 1000;
|
||||||
j++;
|
j++;
|
||||||
double gapDelta = bgReadings.get(i).value - lastbg;
|
double gapDelta = bgReadings.get(i).getValue() - lastbg;
|
||||||
//console.error(gapDelta, lastbg, elapsed_minutes);
|
//console.error(gapDelta, lastbg, elapsed_minutes);
|
||||||
double nextbg = lastbg + (5d / elapsed_minutes * gapDelta);
|
double nextbg = lastbg + (5d / elapsed_minutes * gapDelta);
|
||||||
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(nextbgTime, Math.round(nextbg), true);
|
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(nextbgTime, Math.round(nextbg), true);
|
||||||
|
@ -433,16 +438,16 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
lastbgTime = nextbgTime;
|
lastbgTime = nextbgTime;
|
||||||
}
|
}
|
||||||
j++;
|
j++;
|
||||||
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).value);
|
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).getValue());
|
||||||
bucketed_data.add(newBgreading);
|
bucketed_data.add(newBgreading);
|
||||||
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
|
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
|
||||||
} else if (Math.abs(elapsed_minutes) > 2) {
|
} else if (Math.abs(elapsed_minutes) > 2) {
|
||||||
j++;
|
j++;
|
||||||
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).value);
|
InMemoryGlucoseValue newBgreading = new InMemoryGlucoseValue(bgTime, bgReadings.get(i).getValue());
|
||||||
bucketed_data.add(newBgreading);
|
bucketed_data.add(newBgreading);
|
||||||
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
|
getAapsLogger().debug(LTag.AUTOSENS, "Adding. bgTime: " + DateUtil.toISOString(bgTime) + " lastbgTime: " + DateUtil.toISOString(lastbgTime) + " " + newBgreading.toString());
|
||||||
} else {
|
} else {
|
||||||
bucketed_data.get(j).setValue((bucketed_data.get(j).getValue() + bgReadings.get(i).value) / 2);
|
bucketed_data.get(j).setValue((bucketed_data.get(j).getValue() + bgReadings.get(i).getValue()) / 2);
|
||||||
//log.error("***** Average");
|
//log.error("***** Average");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -914,14 +919,14 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
* Return last BgReading from database or null if db is empty
|
* Return last BgReading from database or null if db is empty
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public BgReading lastBg() {
|
public GlucoseValue lastBg() {
|
||||||
List<BgReading> bgList = getBgReadings();
|
List<GlucoseValue> bgList = getBgReadings();
|
||||||
|
|
||||||
if (bgList == null)
|
if (bgList == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
for (int i = 0; i < bgList.size(); i++)
|
for (int i = 0; i < bgList.size(); i++)
|
||||||
if (bgList.get(i).value >= 39)
|
if (bgList.get(i).getValue() >= 39)
|
||||||
return bgList.get(i);
|
return bgList.get(i);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -931,13 +936,13 @@ public class IobCobCalculatorPlugin extends PluginBase implements IobCobCalculat
|
||||||
* or null if older
|
* or null if older
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public BgReading actualBg() {
|
public GlucoseValue actualBg() {
|
||||||
BgReading lastBg = lastBg();
|
GlucoseValue lastBg = lastBg();
|
||||||
|
|
||||||
if (lastBg == null)
|
if (lastBg == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
if (lastBg.date > System.currentTimeMillis() - 9 * 60 * 1000)
|
if (lastBg.getTimestamp() > System.currentTimeMillis() - 9 * 60 * 1000)
|
||||||
return lastBg;
|
return lastBg;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -18,15 +18,14 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
||||||
|
@ -35,7 +34,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutos
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
|
|
|
@ -16,15 +16,14 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
import info.nightscout.androidaps.events.Event;
|
import info.nightscout.androidaps.events.Event;
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
import info.nightscout.androidaps.logging.LTag;
|
||||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper;
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.data.AutosensData;
|
||||||
|
@ -33,7 +32,6 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutos
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||||
import info.nightscout.androidaps.db.Treatment;
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
|
|
|
@ -5,32 +5,31 @@ import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
import info.nightscout.androidaps.MainApp
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.InvalidateGlucoseValueTransaction
|
||||||
import info.nightscout.androidaps.databinding.BgsourceFragmentBinding
|
import info.nightscout.androidaps.databinding.BgsourceFragmentBinding
|
||||||
import info.nightscout.androidaps.databinding.BgsourceItemBinding
|
import info.nightscout.androidaps.databinding.BgsourceItemBinding
|
||||||
import info.nightscout.androidaps.db.BgReading
|
|
||||||
import info.nightscout.androidaps.events.EventNewBG
|
import info.nightscout.androidaps.events.EventNewBG
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventNewHistoryBgData
|
|
||||||
import info.nightscout.androidaps.plugins.source.BGSourceFragment.RecyclerViewAdapter.BgReadingsViewHolder
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.ListDiffCallback
|
|
||||||
import info.nightscout.androidaps.utils.ListUpdateCallbackHelper
|
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||||
|
import info.nightscout.androidaps.utils.extensions.directionToIcon
|
||||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
|
import info.nightscout.androidaps.utils.valueToUnitsString
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class BGSourceFragment : DaggerFragment() {
|
class BGSourceFragment : DaggerFragment() {
|
||||||
|
@ -41,6 +40,7 @@ class BGSourceFragment : DaggerFragment() {
|
||||||
@Inject lateinit var profileFunction: ProfileFunction
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
@Inject lateinit var databaseHelper: DatabaseHelperInterface
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
|
|
||||||
private val disposable = CompositeDisposable()
|
private val disposable = CompositeDisposable()
|
||||||
|
@ -60,24 +60,27 @@ class BGSourceFragment : DaggerFragment() {
|
||||||
|
|
||||||
binding.recyclerview.setHasFixedSize(true)
|
binding.recyclerview.setHasFixedSize(true)
|
||||||
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
binding.recyclerview.layoutManager = LinearLayoutManager(view.context)
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
binding.recyclerview.adapter = RecyclerViewAdapter(getBgData(now))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
disposable.add(rxBus
|
val now = System.currentTimeMillis()
|
||||||
|
disposable += repository
|
||||||
|
.compatGetBgReadingsDataFromTime(now - millsToThePast, false)
|
||||||
|
.observeOn(aapsSchedulers.main)
|
||||||
|
.subscribe { list -> binding.recyclerview.adapter = RecyclerViewAdapter(list) }
|
||||||
|
|
||||||
|
disposable += rxBus
|
||||||
.toObservable(EventNewBG::class.java)
|
.toObservable(EventNewBG::class.java)
|
||||||
|
.observeOn(aapsSchedulers.io)
|
||||||
|
.debounce(1L, TimeUnit.SECONDS)
|
||||||
|
.subscribe({
|
||||||
|
disposable += repository
|
||||||
|
.compatGetBgReadingsDataFromTime(now - millsToThePast, false)
|
||||||
.observeOn(aapsSchedulers.main)
|
.observeOn(aapsSchedulers.main)
|
||||||
.subscribe({ updateGUI() }, fabricPrivacy::logException)
|
.subscribe { list -> binding.recyclerview.swapAdapter(RecyclerViewAdapter(list), true) }
|
||||||
)
|
}, fabricPrivacy::logException)
|
||||||
disposable.add(rxBus
|
|
||||||
.toObservable(EventNewHistoryBgData::class.java)
|
|
||||||
.observeOn(aapsSchedulers.main)
|
|
||||||
.subscribe({ updateGUI() }, fabricPrivacy::logException)
|
|
||||||
)
|
|
||||||
updateGUI()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -89,87 +92,45 @@ class BGSourceFragment : DaggerFragment() {
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
_binding = null
|
|
||||||
binding.recyclerview.adapter = null // avoid leaks
|
binding.recyclerview.adapter = null // avoid leaks
|
||||||
|
_binding = null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGUI() {
|
inner class RecyclerViewAdapter internal constructor(private var glucoseValues: List<GlucoseValue>) : RecyclerView.Adapter<RecyclerViewAdapter.GlucoseValuesViewHolder>() {
|
||||||
if (_binding == null) return
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
(binding.recyclerview.adapter as? RecyclerViewAdapter)?.setData(getBgData(now))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getBgData(now: Long) = MainApp.getDbHelper()
|
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): GlucoseValuesViewHolder {
|
||||||
.getAllBgreadingsDataFromTime(now - millsToThePast, false)
|
|
||||||
|
|
||||||
inner class RecyclerViewAdapter internal constructor(bgReadings: List<BgReading>) : RecyclerView.Adapter<BgReadingsViewHolder>() {
|
|
||||||
|
|
||||||
private var callbackHelper = ListUpdateCallbackHelper(this) { binding.recyclerview.smoothScrollToPosition(0) }
|
|
||||||
|
|
||||||
private val currentData: MutableList<BgReading> = mutableListOf<BgReading>().also { it.addAll(bgReadings) }
|
|
||||||
|
|
||||||
fun setData(newList: List<BgReading>) {
|
|
||||||
val diffResult = DiffUtil.calculateDiff(getListDiffCallback(ArrayList(newList), ArrayList(currentData)))
|
|
||||||
currentData.clear()
|
|
||||||
currentData.addAll(newList)
|
|
||||||
diffResult.dispatchUpdatesTo(callbackHelper)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getListDiffCallback(newItems: List<BgReading>, oldItems: List<BgReading>): ListDiffCallback<BgReading> =
|
|
||||||
object : ListDiffCallback<BgReading>(newItems, oldItems) {
|
|
||||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
|
||||||
val new = newItems[newItemPosition]
|
|
||||||
val old = oldItems[oldItemPosition]
|
|
||||||
return new.hasValidNS == old.hasValidNS &&
|
|
||||||
new.isValid == old.isValid &&
|
|
||||||
new.date == old.date &&
|
|
||||||
new.value == old.value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean =
|
|
||||||
newItems[newItemPosition].date == oldItems[oldItemPosition].date
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): BgReadingsViewHolder {
|
|
||||||
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.bgsource_item, viewGroup, false)
|
val v = LayoutInflater.from(viewGroup.context).inflate(R.layout.bgsource_item, viewGroup, false)
|
||||||
return BgReadingsViewHolder(v)
|
return GlucoseValuesViewHolder(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: BgReadingsViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: GlucoseValuesViewHolder, position: Int) {
|
||||||
val bgReading = currentData[position]
|
val glucoseValue = glucoseValues[position]
|
||||||
holder.binding.ns.visibility = (NSUpload.isIdValid(bgReading._id)).toVisibility()
|
holder.binding.ns.visibility = (glucoseValue.interfaceIDs.nightscoutId != null).toVisibility()
|
||||||
holder.binding.invalid.visibility = bgReading.isValid.not().toVisibility()
|
holder.binding.invalid.visibility = (!glucoseValue.isValid).toVisibility()
|
||||||
holder.binding.date.text = dateUtil.dateAndTimeString(bgReading.date)
|
holder.binding.date.text = dateUtil.dateAndTimeString(glucoseValue.timestamp)
|
||||||
holder.binding.value.text = bgReading.valueToUnitsToString(profileFunction.getUnits())
|
holder.binding.value.text = glucoseValue.valueToUnitsString(profileFunction.getUnits())
|
||||||
holder.binding.direction.setImageResource(bgReading.directionToIcon(databaseHelper))
|
holder.binding.direction.setImageResource(glucoseValue.trendArrow.directionToIcon())
|
||||||
holder.binding.remove.tag = bgReading
|
holder.binding.remove.tag = glucoseValue
|
||||||
holder.binding.remove.visibility = bgReading.isValid.toVisibility()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int = glucoseValues.size
|
||||||
return currentData.size
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class BgReadingsViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
inner class GlucoseValuesViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
|
||||||
val binding = BgsourceItemBinding.bind(view)
|
val binding = BgsourceItemBinding.bind(view)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
||||||
binding.remove.setOnClickListener { v: View ->
|
binding.remove.setOnClickListener { v: View ->
|
||||||
val bgReading = v.tag as BgReading
|
val glucoseValue = v.tag as GlucoseValue
|
||||||
activity?.let { activity ->
|
activity?.let { activity ->
|
||||||
val text = dateUtil.dateAndTimeString(bgReading.date) + "\n" + bgReading.valueToUnitsToString(profileFunction.getUnits())
|
val text = dateUtil.dateAndTimeString(glucoseValue.timestamp) + "\n" + glucoseValue.valueToUnitsString(profileFunction.getUnits())
|
||||||
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable {
|
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.removerecord), text, Runnable {
|
||||||
bgReading.isValid = false
|
disposable += repository.runTransaction(InvalidateGlucoseValueTransaction(glucoseValue.id)).subscribe()
|
||||||
MainApp.getDbHelper().update(bgReading)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.remove.paintFlags = binding.remove.paintFlags or Paint.UNDERLINE_TEXT_FLAG
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val BgReading.hasValidNS
|
|
||||||
get() = NSUpload.isIdValid(this._id)
|
|
|
@ -8,34 +8,35 @@ import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
import info.nightscout.androidaps.Constants
|
|
||||||
import info.nightscout.androidaps.MainApp
|
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.activities.RequestDexcomPermissionActivity
|
import info.nightscout.androidaps.activities.RequestDexcomPermissionActivity
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
import info.nightscout.androidaps.db.CareportalEvent
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.db.Source
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.receivers.BundleStore
|
import info.nightscout.androidaps.receivers.BundleStore
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
import org.json.JSONObject
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class DexcomPlugin @Inject constructor(
|
class DexcomPlugin @Inject constructor(
|
||||||
injector: HasAndroidInjector,
|
injector: HasAndroidInjector,
|
||||||
private val mainApp: MainApp,
|
|
||||||
resourceHelper: ResourceHelper,
|
resourceHelper: ResourceHelper,
|
||||||
aapsLogger: AAPSLogger,
|
aapsLogger: AAPSLogger,
|
||||||
|
private val dexcomMediator: DexcomMediator,
|
||||||
config: Config
|
config: Config
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.BGSOURCE)
|
.mainType(PluginType.BGSOURCE)
|
||||||
|
@ -48,6 +49,8 @@ class DexcomPlugin @Inject constructor(
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), BgSourceInterface {
|
), BgSourceInterface {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (!config.NSCLIENT) {
|
if (!config.NSCLIENT) {
|
||||||
pluginDescription.setDefault()
|
pluginDescription.setDefault()
|
||||||
|
@ -60,19 +63,12 @@ class DexcomPlugin @Inject constructor(
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
if (ContextCompat.checkSelfPermission(mainApp, PERMISSION) != PackageManager.PERMISSION_GRANTED) {
|
dexcomMediator.requestPermissionIfNeeded()
|
||||||
val intent = Intent(mainApp, RequestDexcomPermissionActivity::class.java)
|
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
|
||||||
mainApp.startActivity(intent)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findDexcomPackageName(): String? {
|
override fun onStop() {
|
||||||
val packageManager = mainApp.packageManager
|
disposable.clear()
|
||||||
for (packageInfo in packageManager.getInstalledPackages(0)) {
|
super.onStop()
|
||||||
if (PACKAGE_NAMES.contains(packageInfo.packageName)) return packageInfo.packageName
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
|
@ -87,6 +83,8 @@ class DexcomPlugin @Inject constructor(
|
||||||
@Inject lateinit var nsUpload: NSUpload
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var bundleStore: BundleStore
|
@Inject lateinit var bundleStore: BundleStore
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -97,72 +95,61 @@ class DexcomPlugin @Inject constructor(
|
||||||
val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
|
val bundle = bundleStore.pickup(inputData.getLong("storeKey", -1))
|
||||||
?: return Result.failure()
|
?: return Result.failure()
|
||||||
try {
|
try {
|
||||||
val sensorType = bundle.getString("sensorType") ?: ""
|
val sourceSensor = when (bundle.getString("sensorType") ?: "") {
|
||||||
val glucoseValues = bundle.getBundle("glucoseValues") ?: return Result.failure()
|
"G6" -> GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE
|
||||||
for (i in 0 until glucoseValues.size()) {
|
"G5" -> GlucoseValue.SourceSensor.DEXCOM_G5_NATIVE
|
||||||
glucoseValues.getBundle(i.toString())?.let { glucoseValue ->
|
else -> GlucoseValue.SourceSensor.DEXCOM_NATIVE_UNKNOWN
|
||||||
val bgReading = BgReading()
|
|
||||||
bgReading.value = glucoseValue.getInt("glucoseValue").toDouble()
|
|
||||||
bgReading.direction = glucoseValue.getString("trendArrow")
|
|
||||||
bgReading.date = glucoseValue.getLong("timestamp") * 1000
|
|
||||||
bgReading.raw = 0.0
|
|
||||||
if (MainApp.getDbHelper().createIfNotExists(bgReading, "Dexcom$sensorType")) {
|
|
||||||
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
|
||||||
nsUpload.uploadBg(bgReading, "AndroidAPS-Dexcom$sensorType")
|
|
||||||
}
|
|
||||||
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
|
||||||
nsUpload.sendToXdrip(bgReading)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
val glucoseValuesBundle = bundle.getBundle("glucoseValues")
|
||||||
|
?: return Result.failure()
|
||||||
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
|
for (i in 0 until glucoseValuesBundle.size()) {
|
||||||
|
val glucoseValueBundle = glucoseValuesBundle.getBundle(i.toString())!!
|
||||||
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
|
timestamp = glucoseValueBundle.getLong("timestamp") * 1000,
|
||||||
|
value = glucoseValueBundle.getInt("glucoseValue").toDouble(),
|
||||||
|
noise = null,
|
||||||
|
raw = null,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.fromString(glucoseValueBundle.getString("trendArrow")!!),
|
||||||
|
sourceSensor = sourceSensor
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
val calibrations = mutableListOf<CgmSourceTransaction.Calibration>()
|
||||||
bundle.getBundle("meters")?.let { meters ->
|
bundle.getBundle("meters")?.let { meters ->
|
||||||
for (i in 0 until meters.size()) {
|
for (i in 0 until meters.size()) {
|
||||||
val meter = meters.getBundle(i.toString())
|
meters.getBundle(i.toString())?.let {
|
||||||
meter?.let {
|
|
||||||
val timestamp = it.getLong("timestamp") * 1000
|
val timestamp = it.getLong("timestamp") * 1000
|
||||||
val now = DateUtil.now()
|
val now = DateUtil.now()
|
||||||
if (timestamp > now - T.months(1).msecs() && timestamp < now)
|
if (timestamp > now - T.months(1).msecs() && timestamp < now) {
|
||||||
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(timestamp) == null) {
|
calibrations.add(CgmSourceTransaction.Calibration(it.getLong("timestamp") * 1000,
|
||||||
val jsonObject = JSONObject()
|
it.getInt("meterValue").toDouble()))
|
||||||
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
|
||||||
jsonObject.put("created_at", DateUtil.toISOString(timestamp))
|
|
||||||
jsonObject.put("eventType", CareportalEvent.BGCHECK)
|
|
||||||
jsonObject.put("glucoseType", "Finger")
|
|
||||||
jsonObject.put("glucose", meter.getInt("meterValue"))
|
|
||||||
jsonObject.put("units", Constants.MGDL)
|
|
||||||
|
|
||||||
val careportalEvent = CareportalEvent(injector)
|
|
||||||
careportalEvent.date = timestamp
|
|
||||||
careportalEvent.source = Source.USER
|
|
||||||
careportalEvent.eventType = CareportalEvent.BGCHECK
|
|
||||||
careportalEvent.json = jsonObject.toString()
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent)
|
|
||||||
nsUpload.uploadCareportalEntryToNS(jsonObject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && bundle.containsKey("sensorInsertionTime")) {
|
val sensorStartTime = if (sp.getBoolean(R.string.key_dexcom_lognssensorchange, false) && bundle.containsKey("sensorInsertionTime")) {
|
||||||
bundle.let {
|
bundle.getLong("sensorInsertionTime", 0) * 1000
|
||||||
val sensorInsertionTime = it.getLong("sensorInsertionTime") * 1000
|
} else {
|
||||||
val now = DateUtil.now()
|
null
|
||||||
if (sensorInsertionTime > now - T.months(1).msecs() && sensorInsertionTime < now)
|
}
|
||||||
if (MainApp.getDbHelper().getCareportalEventFromTimestamp(sensorInsertionTime) == null) {
|
dexcomPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, calibrations, sensorStartTime)).subscribe({ result ->
|
||||||
val jsonObject = JSONObject()
|
result.inserted.forEach {
|
||||||
jsonObject.put("enteredBy", "AndroidAPS-Dexcom$sensorType")
|
broadcastToXDrip(it)
|
||||||
jsonObject.put("created_at", DateUtil.toISOString(sensorInsertionTime))
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||||
jsonObject.put("eventType", CareportalEvent.SENSORCHANGE)
|
nsUpload.uploadBg(it, sourceSensor.text)
|
||||||
val careportalEvent = CareportalEvent(injector)
|
//aapsLogger.debug("XXXXX: dbAdd $it")
|
||||||
careportalEvent.date = sensorInsertionTime
|
|
||||||
careportalEvent.source = Source.USER
|
|
||||||
careportalEvent.eventType = CareportalEvent.SENSORCHANGE
|
|
||||||
careportalEvent.json = jsonObject.toString()
|
|
||||||
MainApp.getDbHelper().createOrUpdate(careportalEvent)
|
|
||||||
nsUpload.uploadCareportalEntryToNS(jsonObject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
result.updated.forEach {
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
||||||
|
nsUpload.updateBg(it, sourceSensor.text)
|
||||||
|
//aapsLogger.debug("XXXXX: dpUpdate $it")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Dexcom App", it)
|
||||||
|
})
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
aapsLogger.error("Error while processing intent from Dexcom App", e)
|
aapsLogger.error("Error while processing intent from Dexcom App", e)
|
||||||
}
|
}
|
||||||
|
@ -178,4 +165,23 @@ class DexcomPlugin @Inject constructor(
|
||||||
"com.dexcom.g6.region3.mgdl", "com.dexcom.g6.region3.mmol")
|
"com.dexcom.g6.region3.mgdl", "com.dexcom.g6.region3.mmol")
|
||||||
const val PERMISSION = "com.dexcom.cgm.EXTERNAL_PERMISSION"
|
const val PERMISSION = "com.dexcom.cgm.EXTERNAL_PERMISSION"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DexcomMediator @Inject constructor(val context: Context) {
|
||||||
|
|
||||||
|
fun requestPermissionIfNeeded() {
|
||||||
|
if (ContextCompat.checkSelfPermission(context, PERMISSION) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
val intent = Intent(context, RequestDexcomPermissionActivity::class.java)
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun findDexcomPackageName(): String? {
|
||||||
|
val packageManager = context.packageManager
|
||||||
|
for (packageInfo in packageManager.getInstalledPackages(0)) {
|
||||||
|
if (PACKAGE_NAMES.contains(packageInfo.packageName)) return packageInfo.packageName
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ import dagger.android.HasAndroidInjector
|
||||||
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.db.BgReading
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.db.CareportalEvent
|
import info.nightscout.androidaps.db.CareportalEvent
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
|
@ -18,8 +20,11 @@ import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.receivers.BundleStore
|
import info.nightscout.androidaps.receivers.BundleStore
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -44,18 +49,28 @@ class EversensePlugin @Inject constructor(
|
||||||
|
|
||||||
override var sensorBatteryLevel = -1
|
override var sensorBatteryLevel = -1
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
class EversenseWorker(
|
class EversenseWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
params: WorkerParameters
|
params: WorkerParameters
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var eversensePlugin: EversensePlugin
|
@Inject lateinit var eversensePlugin: EversensePlugin
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var nsUpload: NSUpload
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
@Inject lateinit var dateUtil: DateUtil
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
@Inject lateinit var bundleStore: BundleStore
|
@Inject lateinit var bundleStore: BundleStore
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -73,7 +88,7 @@ class EversensePlugin @Inject constructor(
|
||||||
if (bundle.containsKey("batteryLevel")) {
|
if (bundle.containsKey("batteryLevel")) {
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "batteryLevel: " + bundle.getString("batteryLevel"))
|
aapsLogger.debug(LTag.BGSOURCE, "batteryLevel: " + bundle.getString("batteryLevel"))
|
||||||
//sensorBatteryLevel = bundle.getString("batteryLevel").toInt()
|
//sensorBatteryLevel = bundle.getString("batteryLevel").toInt()
|
||||||
// TODO: Philoul: Line to check I don't have eversense so I don't know what kind of information is sent...
|
// TODO: Line to check I don't have eversense so I don't know what kind of information is sent...
|
||||||
}
|
}
|
||||||
if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
|
if (bundle.containsKey("signalStrength")) aapsLogger.debug(LTag.BGSOURCE, "signalStrength: " + bundle.getString("signalStrength"))
|
||||||
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
|
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
|
||||||
|
@ -85,6 +100,7 @@ class EversensePlugin @Inject constructor(
|
||||||
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
|
if (bundle.containsKey("transmitterVersionNumber")) aapsLogger.debug(LTag.BGSOURCE, "transmitterVersionNumber: " + bundle.getString("transmitterVersionNumber"))
|
||||||
if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState"))
|
if (bundle.containsKey("transmitterConnectionState")) aapsLogger.debug(LTag.BGSOURCE, "transmitterConnectionState: " + bundle.getString("transmitterConnectionState"))
|
||||||
if (bundle.containsKey("glucoseLevels")) {
|
if (bundle.containsKey("glucoseLevels")) {
|
||||||
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
val glucoseLevels = bundle.getIntArray("glucoseLevels")
|
val glucoseLevels = bundle.getIntArray("glucoseLevels")
|
||||||
val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers")
|
val glucoseRecordNumbers = bundle.getIntArray("glucoseRecordNumbers")
|
||||||
val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps")
|
val glucoseTimestamps = bundle.getLongArray("glucoseTimestamps")
|
||||||
|
@ -92,19 +108,24 @@ class EversensePlugin @Inject constructor(
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "glucoseLevels" + Arrays.toString(glucoseLevels))
|
aapsLogger.debug(LTag.BGSOURCE, "glucoseLevels" + Arrays.toString(glucoseLevels))
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "glucoseRecordNumbers" + Arrays.toString(glucoseRecordNumbers))
|
aapsLogger.debug(LTag.BGSOURCE, "glucoseRecordNumbers" + Arrays.toString(glucoseRecordNumbers))
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamps" + Arrays.toString(glucoseTimestamps))
|
aapsLogger.debug(LTag.BGSOURCE, "glucoseTimestamps" + Arrays.toString(glucoseTimestamps))
|
||||||
for (i in glucoseLevels.indices) {
|
for (i in glucoseLevels.indices)
|
||||||
val bgReading = BgReading()
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.value = glucoseLevels[i].toDouble()
|
timestamp = glucoseTimestamps[i],
|
||||||
bgReading.date = glucoseTimestamps[i]
|
value = glucoseLevels[i].toDouble(),
|
||||||
bgReading.raw = 0.0
|
raw = glucoseLevels[i].toDouble(),
|
||||||
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Eversense")
|
noise = null,
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
trendArrow = GlucoseValue.TrendArrow.NONE,
|
||||||
nsUpload.uploadBg(bgReading, "AndroidAPS-Eversense")
|
sourceSensor = GlucoseValue.SourceSensor.EVERSENSE
|
||||||
}
|
)
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
eversensePlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
nsUpload.sendToXdrip(bgReading)
|
savedValues.inserted.forEach {
|
||||||
}
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.EVERSENSE.text)
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Eversense App", it)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bundle.containsKey("calibrationGlucoseLevels")) {
|
if (bundle.containsKey("calibrationGlucoseLevels")) {
|
||||||
|
|
|
@ -4,16 +4,22 @@ import android.content.Context
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -32,14 +38,26 @@ class GlimpPlugin @Inject constructor(
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), BgSourceInterface {
|
), BgSourceInterface {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
class GlimpWorker(
|
class GlimpWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
params: WorkerParameters
|
params: WorkerParameters
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var glimpPlugin: GlimpPlugin
|
@Inject lateinit var glimpPlugin: GlimpPlugin
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
@Inject lateinit var sp: SP
|
||||||
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -48,12 +66,24 @@ class GlimpPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
if (!glimpPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: $inputData}")
|
aapsLogger.debug(LTag.BGSOURCE, "Received Glimp Data: $inputData}")
|
||||||
val bgReading = BgReading()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
bgReading.value = inputData.getDouble("mySGV", 0.0)
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.direction = inputData.getString("myTrend")
|
timestamp = inputData.getLong("myTimestamp", 0),
|
||||||
bgReading.date = inputData.getLong("myTimestamp", 0)
|
value = inputData.getDouble("mySGV", 0.0),
|
||||||
bgReading.raw = 0.0
|
raw = inputData.getDouble("mySGV", 0.0),
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "GLIMP")
|
noise = null,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.fromString(inputData.getString("myTrend")),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.GLIMP
|
||||||
|
)
|
||||||
|
glimpPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.inserted.forEach {
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.GLIMP.text)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Glimp App", it)
|
||||||
|
})
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,24 @@ import android.content.Context
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.receivers.BundleStore
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -33,6 +41,13 @@ class MM640gPlugin @Inject constructor(
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), BgSourceInterface {
|
), BgSourceInterface {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
class MM640gWorker(
|
class MM640gWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -40,7 +55,14 @@ class MM640gPlugin @Inject constructor(
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
@Inject lateinit var mM640gPlugin: MM640gPlugin
|
@Inject lateinit var mM640gPlugin: MM640gPlugin
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var sp: SP
|
||||||
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var bundleStore: BundleStore
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -54,22 +76,32 @@ class MM640gPlugin @Inject constructor(
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
|
aapsLogger.debug(LTag.BGSOURCE, "Received MM640g Data: $data")
|
||||||
if (data != null && data.isNotEmpty()) {
|
if (data != null && data.isNotEmpty()) {
|
||||||
try {
|
try {
|
||||||
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
val jsonArray = JSONArray(data)
|
val jsonArray = JSONArray(data)
|
||||||
for (i in 0 until jsonArray.length()) {
|
for (i in 0 until jsonArray.length()) {
|
||||||
val jsonObject = jsonArray.getJSONObject(i)
|
val jsonObject = jsonArray.getJSONObject(i)
|
||||||
when (val type = jsonObject.getString("type")) {
|
when (val type = jsonObject.getString("type")) {
|
||||||
"sgv" -> {
|
"sgv" ->
|
||||||
val bgReading = BgReading()
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.value = jsonObject.getDouble("sgv")
|
timestamp = jsonObject.getLong("sgv"),
|
||||||
bgReading.direction = jsonObject.getString("direction")
|
value = jsonObject.getDouble("sgv"),
|
||||||
bgReading.date = jsonObject.getLong("date")
|
raw = jsonObject.getDouble("sgv"),
|
||||||
bgReading.raw = jsonObject.getDouble("sgv")
|
noise = null,
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "MM640g")
|
trendArrow = GlucoseValue.TrendArrow.fromString(jsonObject.getString("direction")),
|
||||||
}
|
sourceSensor = GlucoseValue.SourceSensor.MM_600_SERIES
|
||||||
|
)
|
||||||
else -> aapsLogger.debug(LTag.BGSOURCE, "Unknown entries type: $type")
|
else -> aapsLogger.debug(LTag.BGSOURCE, "Unknown entries type: $type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mM640gPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.all().forEach {
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.MM_600_SERIES.text)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Eversense App", it)
|
||||||
|
})
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
aapsLogger.error("Exception: ", e)
|
aapsLogger.error("Exception: ", e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,20 +5,25 @@ import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
import info.nightscout.androidaps.interfaces.PluginType
|
import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
|
||||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
|
import info.nightscout.androidaps.receivers.BundleStore
|
||||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -50,21 +55,27 @@ class NSClientSourcePlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
override fun advancedFilteringSupported(): Boolean {
|
override fun advancedFilteringSupported(): Boolean {
|
||||||
return isAdvancedFilteringEnabled
|
return isAdvancedFilteringEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storeSgv(sgvJson: JSONObject) {
|
private fun detectSource(glucoseValue: GlucoseValue) {
|
||||||
val nsSgv = NSSgv(sgvJson)
|
if (glucoseValue.timestamp > lastBGTimeStamp) {
|
||||||
val bgReading = BgReading(injector, nsSgv)
|
isAdvancedFilteringEnabled = arrayOf(
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "NS")
|
GlucoseValue.SourceSensor.DEXCOM_NATIVE_UNKNOWN,
|
||||||
detectSource(safeGetString(sgvJson, "device", "none"), safeGetLong(sgvJson, "mills"))
|
GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
}
|
GlucoseValue.SourceSensor.DEXCOM_G5_NATIVE,
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE_XDRIP,
|
||||||
private fun detectSource(source: String, timeStamp: Long) {
|
GlucoseValue.SourceSensor.DEXCOM_G5_NATIVE_XDRIP
|
||||||
if (timeStamp > lastBGTimeStamp) {
|
).any { it == glucoseValue.sourceSensor }
|
||||||
isAdvancedFilteringEnabled = source.contains("G5 Native") || source.contains("G6 Native") || source.contains("AndroidAPS-DexcomG5") || source.contains("AndroidAPS-DexcomG6")
|
lastBGTimeStamp = glucoseValue.timestamp
|
||||||
lastBGTimeStamp = timeStamp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,29 +86,61 @@ class NSClientSourcePlugin @Inject constructor(
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
|
@Inject lateinit var nsClientSourcePlugin: NSClientSourcePlugin
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
@Inject lateinit var bundleStore: BundleStore
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
@Inject lateinit var dexcomPlugin: DexcomPlugin
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun toGv(jsonObject: JSONObject): CgmSourceTransaction.TransactionGlucoseValue {
|
||||||
|
val sgv = NSSgv(jsonObject)
|
||||||
|
return CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
|
timestamp = sgv.mills,
|
||||||
|
value = sgv.mgdl.toDouble(),
|
||||||
|
noise = null,
|
||||||
|
raw = if (sgv.filtered != null) sgv.filtered.toDouble() else sgv.mgdl.toDouble(),
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.fromString(sgv.direction),
|
||||||
|
nightscoutId = sgv.id,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.fromString(sgv.device)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
if (!nsClientSourcePlugin.isEnabled(PluginType.BGSOURCE) && !sp.getBoolean(R.string.key_ns_autobackfill, true)) return Result.failure()
|
if (!nsClientSourcePlugin.isEnabled() && !sp.getBoolean(R.string.key_ns_autobackfill, true) && !dexcomPlugin.isEnabled()) return Result.failure()
|
||||||
try {
|
try {
|
||||||
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
inputData.getString("sgv")?.let { sgvString ->
|
inputData.getString("sgv")?.let { sgvString ->
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
|
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
|
||||||
val sgvJson = JSONObject(sgvString)
|
glucoseValues += toGv(JSONObject(sgvString))
|
||||||
nsClientSourcePlugin.storeSgv(sgvJson)
|
|
||||||
}
|
}
|
||||||
inputData.getString("sgvs")?.let { sgvString ->
|
inputData.getString("sgvs")?.let { sgvString ->
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
|
aapsLogger.debug(LTag.BGSOURCE, "Received NS Data: $sgvString")
|
||||||
val jsonArray = JSONArray(sgvString)
|
val jsonArray = JSONArray(sgvString)
|
||||||
for (i in 0 until jsonArray.length()) {
|
for (i in 0 until jsonArray.length())
|
||||||
val sgvJson = jsonArray.getJSONObject(i)
|
glucoseValues += toGv(jsonArray.getJSONObject(i))
|
||||||
nsClientSourcePlugin.storeSgv(sgvJson)
|
|
||||||
}
|
}
|
||||||
|
nsClientSourcePlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null, !nsClientSourcePlugin.isEnabled())).subscribe({ result ->
|
||||||
|
result.updated.forEach {
|
||||||
|
//aapsLogger.debug("XXXXX: Updated $it")
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
nsClientSourcePlugin.detectSource(it)
|
||||||
}
|
}
|
||||||
|
result.inserted.forEach {
|
||||||
|
//aapsLogger.debug("XXXXX: Inserted $it")
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
nsClientSourcePlugin.detectSource(it)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from NSClient App", it)
|
||||||
|
})
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
aapsLogger.error("Unhandled exception", e)
|
aapsLogger.error("Unhandled exception", e)
|
||||||
return Result.failure()
|
return Result.failure()
|
||||||
|
|
|
@ -5,9 +5,10 @@ import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
@ -16,8 +17,11 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -38,16 +42,26 @@ class PoctechPlugin @Inject constructor(
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), BgSourceInterface {
|
), BgSourceInterface {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
class PoctechWorker(
|
class PoctechWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
params: WorkerParameters
|
params: WorkerParameters
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var poctechPlugin: PoctechPlugin
|
@Inject lateinit var poctechPlugin: PoctechPlugin
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var nsUpload: NSUpload
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -57,24 +71,30 @@ class PoctechPlugin @Inject constructor(
|
||||||
if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
if (!poctechPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
|
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data $inputData")
|
||||||
try {
|
try {
|
||||||
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
val jsonArray = JSONArray(inputData.getString("data"))
|
val jsonArray = JSONArray(inputData.getString("data"))
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
|
aapsLogger.debug(LTag.BGSOURCE, "Received Poctech Data size:" + jsonArray.length())
|
||||||
for (i in 0 until jsonArray.length()) {
|
for (i in 0 until jsonArray.length()) {
|
||||||
val json = jsonArray.getJSONObject(i)
|
val json = jsonArray.getJSONObject(i)
|
||||||
val bgReading = BgReading()
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.value = json.getDouble("current")
|
timestamp = json.getLong("date"),
|
||||||
bgReading.direction = json.getString("direction")
|
value = if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") json.getDouble("current")
|
||||||
bgReading.date = json.getLong("date")
|
else json.getDouble("current") * Constants.MMOLL_TO_MGDL,
|
||||||
bgReading.raw = json.getDouble("raw")
|
raw = json.getDouble("raw"),
|
||||||
if (safeGetString(json, "units", Constants.MGDL) == "mmol/L") bgReading.value = bgReading.value * Constants.MMOLL_TO_MGDL
|
noise = null,
|
||||||
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Poctech")
|
trendArrow = GlucoseValue.TrendArrow.fromString(json.getString("direction")),
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
sourceSensor = GlucoseValue.SourceSensor.POCTECH_NATIVE
|
||||||
nsUpload.uploadBg(bgReading, "AndroidAPS-Poctech")
|
)
|
||||||
}
|
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
|
||||||
nsUpload.sendToXdrip(bgReading)
|
|
||||||
}
|
}
|
||||||
|
poctechPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.inserted.forEach {
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.POCTECH_NATIVE.text)
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Poctech App", it)
|
||||||
|
})
|
||||||
} catch (e: JSONException) {
|
} catch (e: JSONException) {
|
||||||
aapsLogger.error("Exception: ", e)
|
aapsLogger.error("Exception: ", e)
|
||||||
return Result.failure()
|
return Result.failure()
|
||||||
|
|
|
@ -3,9 +3,10 @@ package info.nightscout.androidaps.plugins.source
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.HandlerThread
|
import android.os.HandlerThread
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
@ -16,10 +17,13 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||||
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
import info.nightscout.androidaps.utils.extensions.isRunningTest
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
@ -34,7 +38,10 @@ class RandomBgPlugin @Inject constructor(
|
||||||
private val virtualPumpPlugin: VirtualPumpPlugin,
|
private val virtualPumpPlugin: VirtualPumpPlugin,
|
||||||
private val buildHelper: BuildHelper,
|
private val buildHelper: BuildHelper,
|
||||||
private val sp: SP,
|
private val sp: SP,
|
||||||
private val nsUpload: NSUpload
|
private val nsUpload: NSUpload,
|
||||||
|
private val dateUtil: DateUtil,
|
||||||
|
private val repository: AppRepository,
|
||||||
|
private val xDripBroadcast: XDripBroadcast
|
||||||
) : PluginBase(PluginDescription()
|
) : PluginBase(PluginDescription()
|
||||||
.mainType(PluginType.BGSOURCE)
|
.mainType(PluginType.BGSOURCE)
|
||||||
.fragmentClass(BGSourceFragment::class.java.name)
|
.fragmentClass(BGSourceFragment::class.java.name)
|
||||||
|
@ -61,6 +68,8 @@ class RandomBgPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
override fun advancedFilteringSupported(): Boolean {
|
override fun advancedFilteringSupported(): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -68,6 +77,7 @@ class RandomBgPlugin @Inject constructor(
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
loopHandler.postDelayed(refreshLoop, T.mins(interval).msecs())
|
loopHandler.postDelayed(refreshLoop, T.mins(interval).msecs())
|
||||||
|
disposable.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
|
@ -88,16 +98,24 @@ class RandomBgPlugin @Inject constructor(
|
||||||
val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60
|
val currentMinute = cal.get(Calendar.MINUTE) + (cal.get(Calendar.HOUR_OF_DAY) % 2) * 60
|
||||||
val bgMgdl = min + ((max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI)) / 2
|
val bgMgdl = min + ((max - min) + (max - min) * sin(currentMinute / 120.0 * 2 * PI)) / 2
|
||||||
|
|
||||||
val bgReading = BgReading()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
bgReading.value = bgMgdl
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.date = DateUtil.now()
|
timestamp = dateUtil._now(),
|
||||||
bgReading.raw = bgMgdl
|
value = bgMgdl,
|
||||||
if (MainApp.getDbHelper().createIfNotExists(bgReading, "RandomBG")) {
|
raw = 0.0,
|
||||||
|
noise = null,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.RANDOM
|
||||||
|
)
|
||||||
|
disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.inserted.forEach {
|
||||||
|
xDripBroadcast(it)
|
||||||
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
nsUpload.uploadBg(bgReading, "AndroidAPS-RandomBG")
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.RANDOM.text)
|
||||||
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false))
|
|
||||||
nsUpload.sendToXdrip(bgReading)
|
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Generated BG: $bgReading")
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Random plugin", it)
|
||||||
|
})
|
||||||
|
aapsLogger.debug(LTag.BGSOURCE, "Generated BG: $bgMgdl ${Date()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,10 @@ import android.content.Context
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
@ -14,8 +15,11 @@ import info.nightscout.androidaps.interfaces.PluginType
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
|
||||||
|
import info.nightscout.androidaps.utils.XDripBroadcast
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -35,16 +39,26 @@ class TomatoPlugin @Inject constructor(
|
||||||
aapsLogger, resourceHelper, injector
|
aapsLogger, resourceHelper, injector
|
||||||
), BgSourceInterface {
|
), BgSourceInterface {
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
class TomatoWorker(
|
class TomatoWorker(
|
||||||
context: Context,
|
context: Context,
|
||||||
params: WorkerParameters
|
params: WorkerParameters
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
|
@Inject lateinit var injector: HasAndroidInjector
|
||||||
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
@Inject lateinit var tomatoPlugin: TomatoPlugin
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
@Inject lateinit var sp: SP
|
@Inject lateinit var sp: SP
|
||||||
@Inject lateinit var nsUpload: NSUpload
|
@Inject lateinit var nsUpload: NSUpload
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
@Inject lateinit var broadcastToXDrip: XDripBroadcast
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -52,17 +66,24 @@ class TomatoPlugin @Inject constructor(
|
||||||
|
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
if (!tomatoPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
||||||
val bgReading = BgReading()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
aapsLogger.debug(LTag.BGSOURCE, "Received Tomato Data")
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.value = inputData.getDouble("com.fanqies.tomatofn.Extras.BgEstimate", 0.0)
|
timestamp = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0),
|
||||||
bgReading.date = inputData.getLong("com.fanqies.tomatofn.Extras.Time", 0)
|
value = inputData.getDouble("com.fanqies.tomatofn.Extras.BgEstimate", 0.0),
|
||||||
val isNew = MainApp.getDbHelper().createIfNotExists(bgReading, "Tomato")
|
raw = 0.0,
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_nsupload, false)) {
|
noise = null,
|
||||||
nsUpload.uploadBg(bgReading, "AndroidAPS-Tomato")
|
trendArrow = GlucoseValue.TrendArrow.NONE,
|
||||||
}
|
sourceSensor = GlucoseValue.SourceSensor.LIBRE_1_TOMATO
|
||||||
if (isNew && sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
)
|
||||||
nsUpload.sendToXdrip(bgReading)
|
tomatoPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.inserted.forEach {
|
||||||
|
broadcastToXDrip(it)
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_nsupload, false))
|
||||||
|
nsUpload.uploadBg(it, GlucoseValue.SourceSensor.LIBRE_1_TOMATO.text)
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Tomato App", it)
|
||||||
|
})
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,9 +4,10 @@ import android.content.Context
|
||||||
import androidx.work.Worker
|
import androidx.work.Worker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.database.transactions.CgmSourceTransaction
|
||||||
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
import info.nightscout.androidaps.interfaces.BgSourceInterface
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase
|
import info.nightscout.androidaps.interfaces.PluginBase
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription
|
import info.nightscout.androidaps.interfaces.PluginDescription
|
||||||
|
@ -15,6 +16,8 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.services.Intents
|
import info.nightscout.androidaps.services.Intents
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
@ -39,8 +42,21 @@ class XdripPlugin @Inject constructor(
|
||||||
return advancedFiltering
|
return advancedFiltering
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setSource(source: String) {
|
private fun detectSource(glucoseValue: GlucoseValue) {
|
||||||
advancedFiltering = source.contains("G5 Native") || source.contains("G6 Native")
|
advancedFiltering = arrayOf(
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_NATIVE_UNKNOWN,
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE,
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_G5_NATIVE,
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_G6_NATIVE_XDRIP,
|
||||||
|
GlucoseValue.SourceSensor.DEXCOM_G5_NATIVE_XDRIP
|
||||||
|
).any { it == glucoseValue.sourceSensor }
|
||||||
|
}
|
||||||
|
|
||||||
|
private val disposable = CompositeDisposable()
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
disposable.clear()
|
||||||
|
super.onStop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// cannot be inner class because of needed injection
|
// cannot be inner class because of needed injection
|
||||||
|
@ -50,6 +66,7 @@ class XdripPlugin @Inject constructor(
|
||||||
) : Worker(context, params) {
|
) : Worker(context, params) {
|
||||||
|
|
||||||
@Inject lateinit var xdripPlugin: XdripPlugin
|
@Inject lateinit var xdripPlugin: XdripPlugin
|
||||||
|
@Inject lateinit var repository: AppRepository
|
||||||
|
|
||||||
init {
|
init {
|
||||||
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
|
||||||
|
@ -58,15 +75,24 @@ class XdripPlugin @Inject constructor(
|
||||||
override fun doWork(): Result {
|
override fun doWork(): Result {
|
||||||
if (!xdripPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
if (!xdripPlugin.isEnabled(PluginType.BGSOURCE)) return Result.failure()
|
||||||
xdripPlugin.aapsLogger.debug(LTag.BGSOURCE, "Received xDrip data: $inputData")
|
xdripPlugin.aapsLogger.debug(LTag.BGSOURCE, "Received xDrip data: $inputData")
|
||||||
val bgReading = BgReading()
|
val glucoseValues = mutableListOf<CgmSourceTransaction.TransactionGlucoseValue>()
|
||||||
bgReading.value = inputData.getDouble(Intents.EXTRA_BG_ESTIMATE, 0.0)
|
glucoseValues += CgmSourceTransaction.TransactionGlucoseValue(
|
||||||
bgReading.direction = inputData.getString(Intents.EXTRA_BG_SLOPE_NAME)
|
timestamp = inputData.getLong(Intents.EXTRA_TIMESTAMP, 0),
|
||||||
bgReading.date = inputData.getLong(Intents.EXTRA_TIMESTAMP, 0)
|
value = inputData.getDouble(Intents.EXTRA_BG_ESTIMATE, 0.0),
|
||||||
bgReading.raw = inputData.getDouble(Intents.EXTRA_RAW, 0.0)
|
raw = inputData.getDouble(Intents.EXTRA_RAW, 0.0),
|
||||||
|
noise = null,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.fromString(inputData.getString(Intents.EXTRA_BG_SLOPE_NAME)),
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.fromString(inputData.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION)
|
||||||
|
?: "")
|
||||||
|
)
|
||||||
|
xdripPlugin.disposable += repository.runTransactionForResult(CgmSourceTransaction(glucoseValues, emptyList(), null)).subscribe({ savedValues ->
|
||||||
|
savedValues.all().forEach {
|
||||||
|
xdripPlugin.detectSource(it)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
xdripPlugin.aapsLogger.error(LTag.BGSOURCE, "Error while saving values from Eversense App", it)
|
||||||
|
})
|
||||||
xdripPlugin.sensorBatteryLevel = inputData.getInt(Intents.EXTRA_SENSOR_BATTERY, -1)
|
xdripPlugin.sensorBatteryLevel = inputData.getInt(Intents.EXTRA_SENSOR_BATTERY, -1)
|
||||||
val source = inputData.getString(Intents.XDRIP_DATA_SOURCE_DESCRIPTION) ?: ""
|
|
||||||
xdripPlugin.setSource(source)
|
|
||||||
MainApp.getDbHelper().createIfNotExists(bgReading, "XDRIP")
|
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package info.nightscout.androidaps.utils
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
|
||||||
|
fun GlucoseValue.valueToUnits(units: String): Double =
|
||||||
|
if (units == Constants.MGDL) value
|
||||||
|
else value * Constants.MGDL_TO_MMOLL
|
||||||
|
|
||||||
|
fun GlucoseValue.valueToUnitsString(units: String): String =
|
||||||
|
if (units == Constants.MGDL) DecimalFormatter.to0Decimal(value)
|
||||||
|
else DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL)
|
|
@ -3,7 +3,6 @@ package info.nightscout.androidaps.utils
|
||||||
import info.nightscout.androidaps.Config
|
import info.nightscout.androidaps.Config
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.db.BgReading
|
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
@ -106,9 +105,9 @@ class LocalAlertUtils @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkStaleBGAlert() {
|
fun checkStaleBGAlert() {
|
||||||
val bgReading: BgReading? = iobCobCalculatorPlugin.lastBg()
|
val bgReading = iobCobCalculatorPlugin.lastBg()
|
||||||
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)
|
||||||
&& bgReading != null && bgReading.date + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
|
&& bgReading != null && bgReading.timestamp + missedReadingsThreshold() < System.currentTimeMillis() && sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
|
||||||
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
|
val n = Notification(Notification.BG_READINGS_MISSED, resourceHelper.gs(R.string.missed_bg_readings), Notification.URGENT)
|
||||||
n.soundId = R.raw.alarm
|
n.soundId = R.raw.alarm
|
||||||
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold())
|
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + missedReadingsThreshold())
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package info.nightscout.androidaps.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import info.nightscout.androidaps.R
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class XDripBroadcast @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val aapsLogger: AAPSLogger,
|
||||||
|
private val sp: SP
|
||||||
|
) {
|
||||||
|
|
||||||
|
operator fun invoke(glucoseValue: GlucoseValue) {
|
||||||
|
if (sp.getBoolean(R.string.key_dexcomg5_xdripupload, false)) {
|
||||||
|
val format = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US)
|
||||||
|
try {
|
||||||
|
val entriesBody = JSONArray()
|
||||||
|
val json = JSONObject()
|
||||||
|
json.put("sgv", glucoseValue.value)
|
||||||
|
json.put("direction", glucoseValue.trendArrow.text)
|
||||||
|
json.put("device", "G5")
|
||||||
|
json.put("type", "sgv")
|
||||||
|
json.put("date", glucoseValue.timestamp)
|
||||||
|
json.put("dateString", format.format(glucoseValue.timestamp))
|
||||||
|
entriesBody.put(json)
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.putString("action", "add")
|
||||||
|
bundle.putString("collection", "entries")
|
||||||
|
bundle.putString("data", entriesBody.toString())
|
||||||
|
val intent = Intent(XDRIP_PLUS_NS_EMULATOR)
|
||||||
|
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES)
|
||||||
|
context.sendBroadcast(intent)
|
||||||
|
val receivers = context.packageManager.queryBroadcastReceivers(intent, 0)
|
||||||
|
if (receivers.size < 1) {
|
||||||
|
//NSUpload.log.debug("No xDrip receivers found. ")
|
||||||
|
aapsLogger.debug(LTag.BGSOURCE, "No xDrip receivers found.")
|
||||||
|
} else {
|
||||||
|
aapsLogger.debug(LTag.BGSOURCE, "${receivers.size} xDrip receivers")
|
||||||
|
}
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error(LTag.BGSOURCE, "Unhandled exception", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR"
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,9 @@ package info.nightscout.androidaps.utils.stats
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.util.LongSparseArray
|
import android.util.LongSparseArray
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
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.database.AppRepository
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.HtmlHelper
|
import info.nightscout.androidaps.utils.HtmlHelper
|
||||||
|
@ -19,18 +19,20 @@ import javax.inject.Singleton
|
||||||
class TirCalculator @Inject constructor(
|
class TirCalculator @Inject constructor(
|
||||||
private val resourceHelper: ResourceHelper,
|
private val resourceHelper: ResourceHelper,
|
||||||
private val profileFunction: ProfileFunction,
|
private val profileFunction: ProfileFunction,
|
||||||
private val dateUtil: DateUtil
|
private val dateUtil: DateUtil,
|
||||||
){
|
private val repository: AppRepository
|
||||||
|
) {
|
||||||
|
|
||||||
fun calculate(days: Long, lowMgdl: Double, highMgdl: Double): LongSparseArray<TIR> {
|
fun calculate(days: Long, lowMgdl: Double, highMgdl: Double): LongSparseArray<TIR> {
|
||||||
if (lowMgdl < 39) throw RuntimeException("Low below 39")
|
if (lowMgdl < 39) throw RuntimeException("Low below 39")
|
||||||
if (lowMgdl > highMgdl) throw RuntimeException("Low > High")
|
if (lowMgdl > highMgdl) throw RuntimeException("Low > High")
|
||||||
val startTime = MidnightTime.calc(DateUtil.now() - T.days(days).msecs())
|
val startTime = MidnightTime.calc(DateUtil.now() - T.days(days).msecs())
|
||||||
val endTime = MidnightTime.calc(DateUtil.now())
|
val endTime = MidnightTime.calc(DateUtil.now())
|
||||||
|
|
||||||
val bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, endTime, true)
|
val bgReadings = repository.compatGetBgReadingsDataFromTime(startTime, endTime, true).blockingGet()
|
||||||
val result = LongSparseArray<TIR>()
|
val result = LongSparseArray<TIR>()
|
||||||
for (bg in bgReadings) {
|
for (bg in bgReadings) {
|
||||||
val midnight = MidnightTime.calc(bg.date)
|
val midnight = MidnightTime.calc(bg.timestamp)
|
||||||
var tir = result[midnight]
|
var tir = result[midnight]
|
||||||
if (tir == null) {
|
if (tir == null) {
|
||||||
tir = TIR(midnight, lowMgdl, highMgdl)
|
tir = TIR(midnight, lowMgdl, highMgdl)
|
||||||
|
|
|
@ -3,10 +3,10 @@ package info.nightscout.androidaps.utils.wizard
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
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.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||||
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
||||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import info.nightscout.androidaps.utils.valueToUnits
|
||||||
import org.json.JSONException
|
import org.json.JSONException
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -71,7 +72,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
|
||||||
|
|
||||||
fun isActive(): Boolean = Profile.secondsFromMidnight() >= validFrom() && Profile.secondsFromMidnight() <= validTo()
|
fun isActive(): Boolean = Profile.secondsFromMidnight() >= validFrom() && Profile.secondsFromMidnight() <= validTo()
|
||||||
|
|
||||||
fun doCalc(profile: Profile, profileName: String, lastBG: BgReading, _synchronized: Boolean): BolusWizard {
|
fun doCalc(profile: Profile, profileName: String, lastBG: GlucoseValue, _synchronized: Boolean): BolusWizard {
|
||||||
val tempTarget = treatmentsPlugin.tempTargetFromHistory
|
val tempTarget = treatmentsPlugin.tempTargetFromHistory
|
||||||
//BG
|
//BG
|
||||||
var bg = 0.0
|
var bg = 0.0
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
package info.nightscout.androidaps.db
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import dagger.android.AndroidInjector
|
|
||||||
import dagger.android.HasAndroidInjector
|
|
||||||
import info.nightscout.androidaps.TestBase
|
|
||||||
import info.nightscout.androidaps.Constants
|
|
||||||
import info.nightscout.androidaps.MainApp
|
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
|
|
||||||
import info.nightscout.androidaps.logging.L
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
|
||||||
import info.nightscout.androidaps.core.R
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
|
||||||
import info.nightscout.androidaps.utils.DefaultValueHelper
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
|
||||||
import org.junit.Assert
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
import org.mockito.ArgumentMatchers
|
|
||||||
import org.mockito.Mock
|
|
||||||
import org.mockito.Mockito
|
|
||||||
import org.mockito.Mockito.`when`
|
|
||||||
import org.powermock.api.mockito.PowerMockito
|
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest
|
|
||||||
import org.powermock.modules.junit4.PowerMockRunner
|
|
||||||
import java.util.*
|
|
||||||
import java.util.logging.Logger
|
|
||||||
|
|
||||||
@RunWith(PowerMockRunner::class)
|
|
||||||
@PrepareForTest(MainApp::class, Logger::class, L::class, GlucoseStatus::class)
|
|
||||||
class BgReadingTest : TestBase() {
|
|
||||||
|
|
||||||
@Mock lateinit var defaultValueHelper: DefaultValueHelper
|
|
||||||
@Mock lateinit var profileFunction: ProfileFunction
|
|
||||||
@Mock lateinit var resourceHelper: ResourceHelper
|
|
||||||
@Mock lateinit var databaseHelper: DatabaseHelperInterface
|
|
||||||
|
|
||||||
var injector: HasAndroidInjector = HasAndroidInjector {
|
|
||||||
AndroidInjector {
|
|
||||||
if (it is BgReading) {
|
|
||||||
it.aapsLogger = aapsLogger
|
|
||||||
it.resourceHelper = resourceHelper
|
|
||||||
it.defaultValueHelper = defaultValueHelper
|
|
||||||
it.profileFunction = profileFunction
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun valueToUnits() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
bgReading.value = 18.0
|
|
||||||
Assert.assertEquals(18.0, bgReading.valueToUnits(Constants.MGDL) * 1, 0.01)
|
|
||||||
Assert.assertEquals(1.0, bgReading.valueToUnits(Constants.MMOL) * 1, 0.01)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun directionToSymbol() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
bgReading.direction = "DoubleDown"
|
|
||||||
Assert.assertEquals("\u21ca", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "SingleDown"
|
|
||||||
Assert.assertEquals("\u2193", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "FortyFiveDown"
|
|
||||||
Assert.assertEquals("\u2198", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "Flat"
|
|
||||||
Assert.assertEquals("\u2192", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "FortyFiveUp"
|
|
||||||
Assert.assertEquals("\u2197", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "SingleUp"
|
|
||||||
Assert.assertEquals("\u2191", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "DoubleUp"
|
|
||||||
Assert.assertEquals("\u21c8", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
bgReading.direction = "OUT OF RANGE"
|
|
||||||
Assert.assertEquals("??", bgReading.directionToSymbol(databaseHelper))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun directionToIcon() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
bgReading.direction = "DoubleDown"
|
|
||||||
Assert.assertEquals(R.drawable.ic_doubledown, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "SingleDown"
|
|
||||||
Assert.assertEquals(R.drawable.ic_singledown, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "FortyFiveDown"
|
|
||||||
Assert.assertEquals(R.drawable.ic_fortyfivedown, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "Flat"
|
|
||||||
Assert.assertEquals(R.drawable.ic_flat, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "FortyFiveUp"
|
|
||||||
Assert.assertEquals(R.drawable.ic_fortyfiveup, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "SingleUp"
|
|
||||||
Assert.assertEquals(R.drawable.ic_singleup, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "DoubleUp"
|
|
||||||
Assert.assertEquals(R.drawable.ic_doubleup, bgReading.directionToIcon(databaseHelper))
|
|
||||||
bgReading.direction = "OUT OF RANGE"
|
|
||||||
Assert.assertEquals(R.drawable.ic_invalid, bgReading.directionToIcon(databaseHelper))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test fun dateTest() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
bgReading.date = now
|
|
||||||
val nowDate = Date(now)
|
|
||||||
Assert.assertEquals(now, bgReading.date(now).date)
|
|
||||||
Assert.assertEquals(now, bgReading.date(nowDate).date)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test fun valueTest() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
val valueToSet = 81.0 // 4.5 mmol
|
|
||||||
Assert.assertEquals(81.0, bgReading.value(valueToSet).value, 0.01)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test fun copyFromTest() {
|
|
||||||
// val databaseHelper = Mockito.mock(DatabaseHelper::class.java)
|
|
||||||
// `when`(MainApp.getDbHelper()).thenReturn(databaseHelper)
|
|
||||||
setReadings(72, 0)
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
val copy = BgReading(injector)
|
|
||||||
bgReading.value = 81.0
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
bgReading.date = now
|
|
||||||
copy.date = now
|
|
||||||
copy.copyFrom(bgReading)
|
|
||||||
Assert.assertEquals(81.0, copy.value, 0.1)
|
|
||||||
Assert.assertEquals(now, copy.date)
|
|
||||||
Assert.assertEquals(bgReading.directionToSymbol(databaseHelper), copy.directionToSymbol(databaseHelper))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun isEqualTest() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
val copy = BgReading(injector)
|
|
||||||
bgReading.value = 81.0
|
|
||||||
val now = System.currentTimeMillis()
|
|
||||||
bgReading.date = now
|
|
||||||
copy.date = now
|
|
||||||
copy.copyFrom(bgReading)
|
|
||||||
Assert.assertTrue(copy.isEqual(bgReading))
|
|
||||||
Assert.assertFalse(copy.isEqual(BgReading(injector)))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test fun calculateDirection() {
|
|
||||||
val bgReading = BgReading(injector)
|
|
||||||
val bgReadingsList: List<BgReading>? = null
|
|
||||||
// val databaseHelper = Mockito.mock(DatabaseHelper::class.java)
|
|
||||||
// `when`(MainApp.getDbHelper()).thenReturn(databaseHelper)
|
|
||||||
`when`(databaseHelper.getAllBgreadingsDataFromTime(ArgumentMatchers.anyLong(), ArgumentMatchers.anyBoolean())).thenReturn(bgReadingsList)
|
|
||||||
Assert.assertEquals("NONE", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(72, 0)
|
|
||||||
Assert.assertEquals("DoubleUp", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(76, 60)
|
|
||||||
Assert.assertEquals("SingleUp", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(74, 65)
|
|
||||||
Assert.assertEquals("FortyFiveUp", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(72, 72)
|
|
||||||
Assert.assertEquals("Flat", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(0, 72)
|
|
||||||
Assert.assertEquals("DoubleDown", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(60, 76)
|
|
||||||
Assert.assertEquals("SingleDown", bgReading.calculateDirection(databaseHelper))
|
|
||||||
setReadings(65, 74)
|
|
||||||
Assert.assertEquals("FortyFiveDown", bgReading.calculateDirection(databaseHelper))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun prepareMock() {
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setReadings(current_value: Int, previous_value: Int) {
|
|
||||||
val now = BgReading(injector)
|
|
||||||
now.value = current_value.toDouble()
|
|
||||||
now.date = System.currentTimeMillis()
|
|
||||||
val previous = BgReading(injector)
|
|
||||||
previous.value = previous_value.toDouble()
|
|
||||||
previous.date = System.currentTimeMillis() - 6 * 60 * 1000L
|
|
||||||
val bgReadings: MutableList<BgReading> = mutableListOf()
|
|
||||||
bgReadings.add(now)
|
|
||||||
bgReadings.add(previous)
|
|
||||||
`when`(databaseHelper.getAllBgreadingsDataFromTime(ArgumentMatchers.anyLong(), ArgumentMatchers.anyBoolean())).thenReturn(bgReadings)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -188,7 +188,7 @@ class APSResultTest : TestBaseWithProfile() {
|
||||||
apsResult.rate(20.0).tempBasalRequested(true)
|
apsResult.rate(20.0).tempBasalRequested(true)
|
||||||
Assert.assertEquals(20.0, safeGetDouble(apsResult.json(), "rate"), 0.0)
|
Assert.assertEquals(20.0, safeGetDouble(apsResult.json(), "rate"), 0.0)
|
||||||
apsResult.rate(20.0).tempBasalRequested(false)
|
apsResult.rate(20.0).tempBasalRequested(false)
|
||||||
Assert.assertEquals(false, apsResult.json().has("rate"))
|
Assert.assertEquals(false, apsResult.json()?.has("rate"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
|
@ -3,10 +3,9 @@ package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||||
import com.google.common.base.Optional
|
import com.google.common.base.Optional
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
@ -93,9 +92,16 @@ class TriggerBgTest : TriggerTestBase() {
|
||||||
Assert.assertEquals(Optional.of(R.drawable.ic_cp_bgcheck), TriggerBg(injector).icon())
|
Assert.assertEquals(Optional.of(R.drawable.ic_cp_bgcheck), TriggerBg(injector).icon())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateOneCurrentRecordBgData(): List<BgReading> {
|
private fun generateOneCurrentRecordBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":214,\"mills\":" + (now - 1) + ",\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = 214.0,
|
||||||
|
timestamp = now - 1,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.UNKNOWN,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.FLAT
|
||||||
|
))
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,11 +3,10 @@ package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||||
import com.google.common.base.Optional
|
import com.google.common.base.Optional
|
||||||
import info.nightscout.androidaps.Constants
|
import info.nightscout.androidaps.Constants
|
||||||
import info.nightscout.androidaps.R
|
import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta.DeltaType
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta.DeltaType
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
@ -101,16 +100,16 @@ class TriggerDeltaTest : TriggerTestBase() {
|
||||||
Assert.assertTrue(t.units == Constants.MGDL)
|
Assert.assertTrue(t.units == Constants.MGDL)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateValidBgData(): List<BgReading> {
|
private fun generateValidBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 214.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}")))) // +2
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 216.0, timestamp = 1514766600000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":219,\"mills\":1514766300000,\"direction\":\"Flat\"}")))) // +3
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 219.0, timestamp = 1514766300000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":223,\"mills\":1514766000000,\"direction\":\"Flat\"}")))) // +4
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 223.0, timestamp = 1514766000000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":222,\"mills\":1514765700000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 222.0, timestamp = 1514765700000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":224,\"mills\":1514765400000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 224.0, timestamp = 1514765400000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 226.0, timestamp = 1514765100000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 228.0, timestamp = 1514764800000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,9 +4,7 @@ import android.content.Context
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBaseWithProfile
|
import info.nightscout.androidaps.TestBaseWithProfile
|
||||||
import info.nightscout.androidaps.db.BgReading
|
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputBg
|
import info.nightscout.androidaps.plugins.general.automation.elements.InputBg
|
||||||
|
@ -83,9 +81,6 @@ open class TriggerTestBase : TestBaseWithProfile() {
|
||||||
if (it is StaticLabel) {
|
if (it is StaticLabel) {
|
||||||
it.resourceHelper = resourceHelper
|
it.resourceHelper = resourceHelper
|
||||||
}
|
}
|
||||||
if (it is BgReading) {
|
|
||||||
it.dateUtil = dateUtil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import info.nightscout.androidaps.R
|
||||||
import info.nightscout.androidaps.TestBaseWithProfile
|
import info.nightscout.androidaps.TestBaseWithProfile
|
||||||
import info.nightscout.androidaps.data.IobTotal
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult
|
import info.nightscout.androidaps.data.PumpEnactResult
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
import info.nightscout.androidaps.interfaces.CommandQueueProvider
|
||||||
import info.nightscout.androidaps.interfaces.Constraint
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
@ -39,9 +39,6 @@ import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentMatchers
|
import org.mockito.ArgumentMatchers
|
||||||
import org.mockito.ArgumentMatchers.any
|
|
||||||
import org.mockito.ArgumentMatchers.anyString
|
|
||||||
import org.mockito.ArgumentMatchers.eq
|
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
@ -75,12 +72,6 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.resourceHelper = resourceHelper
|
it.resourceHelper = resourceHelper
|
||||||
}
|
}
|
||||||
if (it is BgReading) {
|
|
||||||
it.aapsLogger = aapsLogger
|
|
||||||
it.defaultValueHelper = defaultValueHelper
|
|
||||||
it.resourceHelper = resourceHelper
|
|
||||||
it.profileFunction = profileFunction
|
|
||||||
}
|
|
||||||
if (it is AuthRequest) {
|
if (it is AuthRequest) {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.smsCommunicatorPlugin = smsCommunicatorPlugin
|
it.smsCommunicatorPlugin = smsCommunicatorPlugin
|
||||||
|
@ -98,9 +89,8 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
private var hasBeenRun = false
|
private var hasBeenRun = false
|
||||||
|
|
||||||
@Before fun prepareTests() {
|
@Before fun prepareTests() {
|
||||||
val reading = BgReading(injector)
|
val reading = GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT)
|
||||||
reading.value = 100.0
|
val bgList: MutableList<GlucoseValue> = ArrayList()
|
||||||
val bgList: MutableList<BgReading> = ArrayList()
|
|
||||||
bgList.add(reading)
|
bgList.add(reading)
|
||||||
|
|
||||||
`when`(iobCobCalculatorPlugin.dataLock).thenReturn(Unit)
|
`when`(iobCobCalculatorPlugin.dataLock).thenReturn(Unit)
|
||||||
|
@ -176,7 +166,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
|
`when`(profileFunction.getUnits()).thenReturn(Constants.MGDL)
|
||||||
|
|
||||||
`when`(otp.name()).thenReturn("User")
|
`when`(otp.name()).thenReturn("User")
|
||||||
`when`(otp.checkOTP(anyString())).thenReturn(OneTimePasswordValidationResult.OK)
|
`when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.OK)
|
||||||
|
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed")
|
`when`(resourceHelper.gs(R.string.smscommunicator_remotecommandnotallowed)).thenReturn("Remote command is not allowed")
|
||||||
`when`(resourceHelper.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.")
|
`when`(resourceHelper.gs(R.string.sms_wrongcode)).thenReturn("Wrong code. Command cancelled.")
|
||||||
|
@ -195,7 +185,7 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_loopisdisabled)).thenReturn("Loop is disabled")
|
`when`(resourceHelper.gs(R.string.smscommunicator_loopisdisabled)).thenReturn("Loop is disabled")
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled")
|
`when`(resourceHelper.gs(R.string.smscommunicator_loopisenabled)).thenReturn("Loop is enabled")
|
||||||
`when`(resourceHelper.gs(R.string.wrongformat)).thenReturn("Wrong format")
|
`when`(resourceHelper.gs(R.string.wrongformat)).thenReturn("Wrong format")
|
||||||
`when`(resourceHelper.gs(eq(R.string.wrongTbrDuration), any())).thenAnswer({ i: InvocationOnMock -> "TBR duration must be a multiple of " + i.getArguments()[1] + " minutes and greater than 0."})
|
`when`(resourceHelper.gs(ArgumentMatchers.eq(R.string.wrongTbrDuration), ArgumentMatchers.any())).thenAnswer({ i: InvocationOnMock -> "TBR duration must be a multiple of " + i.getArguments()[1] + " minutes and greater than 0." })
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_loophasbeendisabled)).thenReturn("Loop has been disabled")
|
`when`(resourceHelper.gs(R.string.smscommunicator_loophasbeendisabled)).thenReturn("Loop has been disabled")
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_loophasbeenenabled)).thenReturn("Loop has been enabled")
|
`when`(resourceHelper.gs(R.string.smscommunicator_loophasbeenenabled)).thenReturn("Loop has been enabled")
|
||||||
`when`(resourceHelper.gs(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled")
|
`when`(resourceHelper.gs(R.string.smscommunicator_tempbasalcanceled)).thenReturn("Temp basal canceled")
|
||||||
|
@ -450,9 +440,9 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
|
||||||
passCode = smsCommunicatorPlugin.messageToConfirm?.confirmCode!!
|
passCode = smsCommunicatorPlugin.messageToConfirm?.confirmCode!!
|
||||||
// ignore from other number
|
// ignore from other number
|
||||||
smsCommunicatorPlugin.processSms(Sms("5678", passCode))
|
smsCommunicatorPlugin.processSms(Sms("5678", passCode))
|
||||||
`when`(otp.checkOTP(anyString())).thenReturn(OneTimePasswordValidationResult.ERROR_WRONG_OTP)
|
`when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.ERROR_WRONG_OTP)
|
||||||
smsCommunicatorPlugin.processSms(Sms("1234", "XXXX"))
|
smsCommunicatorPlugin.processSms(Sms("1234", "XXXX"))
|
||||||
`when`(otp.checkOTP(anyString())).thenReturn(OneTimePasswordValidationResult.OK)
|
`when`(otp.checkOTP(ArgumentMatchers.anyString())).thenReturn(OneTimePasswordValidationResult.OK)
|
||||||
Assert.assertEquals("XXXX", smsCommunicatorPlugin.messages[3].text)
|
Assert.assertEquals("XXXX", smsCommunicatorPlugin.messages[3].text)
|
||||||
Assert.assertEquals("Wrong code. Command cancelled.", smsCommunicatorPlugin.messages[4].text)
|
Assert.assertEquals("Wrong code. Command cancelled.", smsCommunicatorPlugin.messages[4].text)
|
||||||
//then correct code should not work
|
//then correct code should not work
|
||||||
|
|
|
@ -3,12 +3,9 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
import info.nightscout.androidaps.utils.T
|
import info.nightscout.androidaps.utils.T
|
||||||
import org.json.JSONException
|
|
||||||
import org.json.JSONObject
|
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
@ -36,9 +33,6 @@ class GlucoseStatusTest : TestBase() {
|
||||||
it.aapsLogger = aapsLogger
|
it.aapsLogger = aapsLogger
|
||||||
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
|
it.iobCobCalculatorPlugin = iobCobCalculatorPlugin
|
||||||
}
|
}
|
||||||
if (it is BgReading) {
|
|
||||||
it.dateUtil = dateUtil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,78 +121,57 @@ class GlucoseStatusTest : TestBase() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// [{"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}]
|
// [{"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}]
|
||||||
private fun generateValidBgData(): List<BgReading> {
|
private fun generateValidBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
try {
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 214.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 216.0, timestamp = 1514766600000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}")))) // +2
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 219.0, timestamp = 1514766300000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":219,\"mills\":1514766300000,\"direction\":\"Flat\"}")))) // +3
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 223.0, timestamp = 1514766000000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":223,\"mills\":1514766000000,\"direction\":\"Flat\"}")))) // +4
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 222.0, timestamp = 1514765700000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":222,\"mills\":1514765700000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 224.0, timestamp = 1514765400000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":224,\"mills\":1514765400000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 226.0, timestamp = 1514765100000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":226,\"mills\":1514765100000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 228.0, timestamp = 1514764800000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))))
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateMostRecentBgData(): List<BgReading> {
|
private fun generateMostRecentBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
try {
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 214.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 216.0, timestamp = 1514766800000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":216,\"mills\":1514766800000,\"direction\":\"Flat\"}")))) // +2
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 216.0, timestamp = 1514766600000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":216,\"mills\":1514766600000,\"direction\":\"Flat\"}"))))
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInsufficientBgData(): List<BgReading> {
|
private fun generateInsufficientBgData(): List<GlucoseValue> {
|
||||||
return ArrayList()
|
return ArrayList()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateOldBgData(): List<BgReading> {
|
private fun generateOldBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
try {
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 228.0, timestamp = 1514764800000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":228,\"mills\":1514764800000,\"direction\":\"Flat\"}"))))
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateOneCurrentRecordBgData(): List<BgReading> {
|
private fun generateOneCurrentRecordBgData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
try {
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 214.0, timestamp = 1514766900000, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))))
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateLibreTestData(): List<BgReading> {
|
private fun generateLibreTestData(): List<GlucoseValue> {
|
||||||
val list: MutableList<BgReading> = ArrayList()
|
val list: MutableList<GlucoseValue> = ArrayList()
|
||||||
try {
|
|
||||||
val endTime = 1514766900000L
|
val endTime = 1514766900000L
|
||||||
val latestReading = 100.0
|
val latestReading = 100.0
|
||||||
// Now
|
// Now
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":$latestReading,\"mills\":$endTime,\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
// One minute ago
|
// One minute ago
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":" + latestReading + ",\"mills\":" + (endTime - 1000 * 60 * 1) + ",\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime - 1000 * 60 * 1, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
// Two minutes ago
|
// Two minutes ago
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":" + latestReading + ",\"mills\":" + (endTime - 1000 * 60 * 2) + ",\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading, timestamp = endTime - 1000 * 60 * 2, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
|
|
||||||
// Three minutes and beyond at constant rate
|
// Three minutes and beyond at constant rate
|
||||||
for (i in 3..49) {
|
for (i in 3..49)
|
||||||
list.add(BgReading(injector, NSSgv(JSONObject("{\"mgdl\":" + (latestReading + i * 2) + ",\"mills\":" + (endTime - 1000 * 60 * i) + ",\"direction\":\"Flat\"}"))))
|
list.add(GlucoseValue(raw = 0.0, noise = 0.0, value = latestReading + i * 2, timestamp = endTime - 1000 * 60 * i, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
}
|
|
||||||
} catch (e: JSONException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
}
|
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,10 +3,11 @@ package info.nightscout.androidaps.plugins.iob.iobCobCalculator
|
||||||
import dagger.android.AndroidInjector
|
import dagger.android.AndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
import info.nightscout.androidaps.TestBase
|
import info.nightscout.androidaps.TestBase
|
||||||
import info.nightscout.androidaps.db.BgReading
|
import info.nightscout.androidaps.database.AppRepository
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin
|
||||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin
|
||||||
|
@ -27,7 +28,7 @@ import org.powermock.modules.junit4.PowerMockRunner
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@RunWith(PowerMockRunner::class)
|
@RunWith(PowerMockRunner::class)
|
||||||
@PrepareForTest(FabricPrivacy::class)
|
@PrepareForTest(FabricPrivacy::class, AppRepository::class)
|
||||||
class IobCobCalculatorPluginTest : TestBase() {
|
class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
@Mock lateinit var sp: SP
|
@Mock lateinit var sp: SP
|
||||||
|
@ -42,129 +43,123 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
@Mock lateinit var defaultValueHelper: DefaultValueHelper
|
@Mock lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
@Mock lateinit var fabricPrivacy: FabricPrivacy
|
||||||
@Mock lateinit var dateUtil: DateUtil
|
@Mock lateinit var dateUtil: DateUtil
|
||||||
|
@Mock lateinit var repository: AppRepository
|
||||||
|
|
||||||
lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||||
|
|
||||||
val injector = HasAndroidInjector {
|
val injector = HasAndroidInjector {
|
||||||
AndroidInjector {
|
AndroidInjector {
|
||||||
if (it is BgReading) {
|
|
||||||
it.aapsLogger = aapsLogger
|
|
||||||
it.defaultValueHelper = defaultValueHelper
|
|
||||||
it.resourceHelper = resourceHelper
|
|
||||||
it.profileFunction = profileFunction
|
|
||||||
it.dateUtil = dateUtil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun mock() {
|
fun mock() {
|
||||||
iobCobCalculatorPlugin = IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction, activePlugin, treatmentsPlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil)
|
iobCobCalculatorPlugin = IobCobCalculatorPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, resourceHelper, profileFunction, activePlugin, treatmentsPlugin, sensitivityOref1Plugin, sensitivityAAPSPlugin, sensitivityWeightedAveragePlugin, fabricPrivacy, dateUtil, repository)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun isAbout5minDataTest() {
|
fun isAbout5minDataTest() {
|
||||||
val bgReadingList: MutableList<BgReading> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
|
|
||||||
// Super data should not be touched
|
// Super data should not be touched
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
|
||||||
// too much shifted data should return false
|
// too much shifted data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(9).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
|
||||||
// too much shifted and missing data should return false
|
// too much shifted and missing data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(9).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(9).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
|
||||||
// too much shifted and missing data should return false
|
// too much shifted and missing data should return false
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(83).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(83).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(78).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(78).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(73).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(73).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(68).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(68).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(63).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(63).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(58).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(58).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(53).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(53).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(48).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(48).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(43).plus(T.secs(40)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(43).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(38).plus(T.secs(33)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(38).plus(T.secs(40)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(33).plus(T.secs(1)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(33).plus(T.secs(1)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(28).plus(T.secs(0)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(28).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(23).plus(T.secs(0)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(23).plus(T.secs(0)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(16).plus(T.secs(36)).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(16).plus(T.secs(36)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
|
||||||
// slightly shifted data should return true
|
// slightly shifted data should return true
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs() - T.secs(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
|
||||||
// slightly shifted and missing data should return true
|
// slightly shifted and missing data should return true
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs() - T.secs(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun createBucketedData5minTest() {
|
fun createBucketedData5minTest() {
|
||||||
val bgReadingList: MutableList<BgReading> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
|
|
||||||
// Super data should not be touched
|
// Super data should not be touched
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
Assert.assertEquals(bgReadingList[0].date, iobCobCalculatorPlugin.bucketedData[0].timestamp)
|
Assert.assertEquals(bgReadingList[0].timestamp, iobCobCalculatorPlugin.bucketedData[0].timestamp)
|
||||||
Assert.assertEquals(bgReadingList[3].date, iobCobCalculatorPlugin.bucketedData[3].timestamp)
|
Assert.assertEquals(bgReadingList[3].timestamp, iobCobCalculatorPlugin.bucketedData[3].timestamp)
|
||||||
Assert.assertEquals(bgReadingList.size.toLong(), iobCobCalculatorPlugin.bucketedData.size.toLong())
|
Assert.assertEquals(bgReadingList.size.toLong(), iobCobCalculatorPlugin.bucketedData.size.toLong())
|
||||||
|
|
||||||
// Missing value should be replaced
|
// Missing value should be replaced
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).plus(T.secs(10)).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
Assert.assertEquals(bgReadingList[0].date, iobCobCalculatorPlugin.bucketedData[0].timestamp)
|
Assert.assertEquals(bgReadingList[0].timestamp, iobCobCalculatorPlugin.bucketedData[0].timestamp)
|
||||||
Assert.assertEquals(bgReadingList[2].date, iobCobCalculatorPlugin.bucketedData[3].timestamp)
|
Assert.assertEquals(bgReadingList[2].timestamp, iobCobCalculatorPlugin.bucketedData[3].timestamp)
|
||||||
Assert.assertEquals(bgReadingList.size + 1.toLong(), iobCobCalculatorPlugin.bucketedData.size.toLong())
|
Assert.assertEquals(bgReadingList.size + 1.toLong(), iobCobCalculatorPlugin.bucketedData.size.toLong())
|
||||||
|
|
||||||
// drift should be cleared
|
// drift should be cleared
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs() + T.secs(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs() + T.secs(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs() - T.secs(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs() + T.secs(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(0).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(0).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
|
@ -176,8 +171,8 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
// bucketed data should return null if not enough bg data
|
// bucketed data should return null if not enough bg data
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(30).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(30).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
|
@ -185,9 +180,9 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
// data should be reconstructed
|
// data should be reconstructed
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(50).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(45).msecs()).value(90.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 90.0, timestamp = T.mins(45).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(40.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
|
@ -201,9 +196,9 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
// non 5min data should be reconstructed
|
// non 5min data should be reconstructed
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(50).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(50).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(48).msecs()).value(96.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 96.0, timestamp = T.mins(48).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(40.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 40.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
|
@ -222,122 +217,34 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
// real data gap test
|
// real data gap test
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T13:34:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T13:34:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T13:14:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T13:14:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T13:09:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T13:09:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T13:04:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T13:04:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:59:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:59:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:54:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:54:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:49:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:49:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:44:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:44:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:39:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:39:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:34:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:34:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:29:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:29:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:24:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:24:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:19:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:19:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:14:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:14:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:09:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:09:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T12:04:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T12:04:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:59:55Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T11:59:55Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:49:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:29:57Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:44:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:24:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:39:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:19:57Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:34:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:14:57Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:29:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:10:03Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:24:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T04:04:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:19:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T03:59:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:14:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T03:54:56Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:09:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T03:50:03Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T11:04:56Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-09-05T03:44:57Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:34:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:29:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:24:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:14:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:09:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T10:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:35:05Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:30:17Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:24:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:14:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:09:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T09:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:40:02Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:34:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:29:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:24:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:14:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:09:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T08:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:34:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:30:03Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:25:17Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:14:58Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:09:58Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T07:04:58Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:59:58Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:54:58Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:34:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:29:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:24:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:14:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:10:03Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T06:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:49:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:34:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:29:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:24:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:19:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:14:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:09:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T05:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:50:03Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:44:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:39:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:34:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:29:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:24:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:19:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:14:57Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:10:03Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T04:04:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T03:59:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T03:54:56Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T03:50:03Z")).value(100.0))
|
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-09-05T03:44:57Z")).value(100.0))
|
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.referenceTime = null
|
iobCobCalculatorPlugin.referenceTime = null
|
||||||
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(true, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
|
@ -347,34 +254,34 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
// 5min 4sec data
|
// 5min 4sec data
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:33:40Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:33:40Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:28:36Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:28:36Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:23:32Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:23:32Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:18:28Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:18:28Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:13:24Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:13:24Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:08:19Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:08:19Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T06:03:16Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T06:03:16Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:58:11Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:58:11Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:53:07Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:53:07Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:48:03Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:48:03Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:42:58Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:42:58Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:37:54Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:37:54Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:32:51Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:32:51Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:27:46Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:27:46Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:22:42Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:22:42Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:17:38Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:17:38Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:12:33Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:12:33Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:07:29Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:07:29Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T05:02:26Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T05:02:26Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T04:57:21Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T04:57:21Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(DateUtil.fromISODateString("2018-10-05T04:52:17Z")).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = DateUtil.fromISODateString("2018-10-05T04:52:17Z").time, sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
Assert.assertEquals(false, iobCobCalculatorPlugin.isAbout5minData)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun bgReadingsTest() {
|
fun bgReadingsTest() {
|
||||||
val bgReadingList: List<BgReading> = ArrayList()
|
val bgReadingList: List<GlucoseValue> = ArrayList()
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(bgReadingList, iobCobCalculatorPlugin.bgReadings)
|
Assert.assertEquals(bgReadingList, iobCobCalculatorPlugin.bgReadings)
|
||||||
}
|
}
|
||||||
|
@ -386,47 +293,47 @@ class IobCobCalculatorPluginTest : TestBase() {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun findNewerTest() {
|
fun findNewerTest() {
|
||||||
val bgReadingList: MutableList<BgReading> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(8).msecs())!!.date)
|
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(8).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(5).msecs())!!.date)
|
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(5).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(10).msecs())!!.date)
|
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(10).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(20).msecs())!!.date)
|
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findNewer(T.mins(20).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findNewer(T.mins(22).msecs()))
|
Assert.assertEquals(null, iobCobCalculatorPlugin.findNewer(T.mins(22).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun findOlderTest() {
|
fun findOlderTest() {
|
||||||
val bgReadingList: MutableList<BgReading> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(8).msecs())!!.date)
|
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(8).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(5).msecs())!!.date)
|
Assert.assertEquals(T.mins(5).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(5).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(10).msecs())!!.date)
|
Assert.assertEquals(T.mins(10).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(10).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(20).msecs())!!.date)
|
Assert.assertEquals(T.mins(20).msecs(), iobCobCalculatorPlugin.findOlder(T.mins(20).msecs())!!.timestamp)
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findOlder(T.mins(4).msecs()))
|
Assert.assertEquals(null, iobCobCalculatorPlugin.findOlder(T.mins(4).msecs()))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun findPreviousTimeFromBucketedDataTest() {
|
fun findPreviousTimeFromBucketedDataTest() {
|
||||||
val bgReadingList: MutableList<BgReading> = ArrayList()
|
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(1000))
|
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(1000))
|
||||||
|
|
||||||
// Super data should not be touched
|
// Super data should not be touched
|
||||||
bgReadingList.clear()
|
bgReadingList.clear()
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(20).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(20).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(15).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(15).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(10).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(10).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
bgReadingList.add(BgReading(injector).date(T.mins(5).msecs()).value(100.0))
|
bgReadingList.add(GlucoseValue(raw = 0.0, noise = 0.0, value = 100.0, timestamp = T.mins(5).msecs(), sourceSensor = GlucoseValue.SourceSensor.UNKNOWN, trendArrow = GlucoseValue.TrendArrow.FLAT))
|
||||||
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
iobCobCalculatorPlugin.bgReadings = bgReadingList
|
||||||
iobCobCalculatorPlugin.createBucketedData()
|
iobCobCalculatorPlugin.createBucketedData()
|
||||||
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
|
Assert.assertEquals(null, iobCobCalculatorPlugin.findPreviousTimeFromBucketedData(T.mins(4).msecs()))
|
||||||
|
|
|
@ -42,4 +42,8 @@ android {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':database')
|
||||||
|
}
|
||||||
|
|
||||||
apply from: 'core_dependencies.gradle'
|
apply from: 'core_dependencies.gradle'
|
|
@ -42,7 +42,9 @@ dependencies {
|
||||||
api 'com.google.firebase:firebase-database-ktx'
|
api 'com.google.firebase:firebase-database-ktx'
|
||||||
|
|
||||||
//RxBus
|
//RxBus
|
||||||
api "io.reactivex.rxjava2:rxandroid:${rxandroid_version}"
|
api "io.reactivex.rxjava2:rxjava:$rxjava_version"
|
||||||
|
api "io.reactivex.rxjava2:rxkotlin:$rxkotlin_version"
|
||||||
|
api "io.reactivex.rxjava2:rxandroid:$rxandroid_version"
|
||||||
api "org.apache.commons:commons-lang3:$commonslang3_version"
|
api "org.apache.commons:commons-lang3:$commonslang3_version"
|
||||||
|
|
||||||
//CryptoUtil
|
//CryptoUtil
|
||||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.core.di
|
||||||
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
|
import info.nightscout.androidaps.data.GlucoseValueDataPoint
|
||||||
import info.nightscout.androidaps.data.Profile
|
import info.nightscout.androidaps.data.Profile
|
||||||
import info.nightscout.androidaps.data.PumpEnactResult
|
import info.nightscout.androidaps.data.PumpEnactResult
|
||||||
import info.nightscout.androidaps.db.*
|
import info.nightscout.androidaps.db.*
|
||||||
|
@ -19,7 +20,7 @@ abstract class CoreDataClassesModule {
|
||||||
|
|
||||||
@ContributesAndroidInjector abstract fun profileInjector(): Profile
|
@ContributesAndroidInjector abstract fun profileInjector(): Profile
|
||||||
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStore
|
@ContributesAndroidInjector abstract fun profileStoreInjector(): ProfileStore
|
||||||
@ContributesAndroidInjector abstract fun bgReadingInjector(): BgReading
|
@ContributesAndroidInjector abstract fun glucoseValueDataPointInjector(): GlucoseValueDataPoint
|
||||||
@ContributesAndroidInjector abstract fun treatmentInjector(): Treatment
|
@ContributesAndroidInjector abstract fun treatmentInjector(): Treatment
|
||||||
@ContributesAndroidInjector abstract fun profileSwitchInjector(): ProfileSwitch
|
@ContributesAndroidInjector abstract fun profileSwitchInjector(): ProfileSwitch
|
||||||
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
|
@ContributesAndroidInjector abstract fun temporaryBasalInjector(): TemporaryBasal
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package info.nightscout.androidaps.data
|
||||||
|
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.Constants
|
||||||
|
import info.nightscout.androidaps.core.R
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||||
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||||
|
import info.nightscout.androidaps.utils.DefaultValueHelper
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class GlucoseValueDataPoint @Inject constructor(
|
||||||
|
val injector: HasAndroidInjector,
|
||||||
|
val data: GlucoseValue
|
||||||
|
) : DataPointWithLabelInterface {
|
||||||
|
|
||||||
|
@Inject lateinit var defaultValueHelper: DefaultValueHelper
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
|
|
||||||
|
init {
|
||||||
|
injector.androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun valueToUnits(units: String): Double =
|
||||||
|
if (units == Constants.MGDL) data.value else data.value * Constants.MGDL_TO_MMOLL
|
||||||
|
|
||||||
|
override fun getX(): Double {
|
||||||
|
return data.timestamp.toDouble()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getY(): Double {
|
||||||
|
return valueToUnits(profileFunction.getUnits())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setY(y: Double) {}
|
||||||
|
override fun getLabel(): String? = null
|
||||||
|
override fun getDuration(): Long = 0
|
||||||
|
override fun getShape(): PointsWithLabelGraphSeries.Shape =
|
||||||
|
if (isPrediction) PointsWithLabelGraphSeries.Shape.PREDICTION
|
||||||
|
else PointsWithLabelGraphSeries.Shape.BG
|
||||||
|
|
||||||
|
override fun getSize(): Float = 1f
|
||||||
|
|
||||||
|
override fun getColor(): Int {
|
||||||
|
val units = profileFunction.getUnits()
|
||||||
|
val lowLine = defaultValueHelper.determineLowLine()
|
||||||
|
val highLine = defaultValueHelper.determineHighLine()
|
||||||
|
return when {
|
||||||
|
isPrediction -> predictionColor
|
||||||
|
valueToUnits(units) < lowLine -> resourceHelper.gc(R.color.low)
|
||||||
|
valueToUnits(units) > highLine -> resourceHelper.gc(R.color.high)
|
||||||
|
else -> resourceHelper.gc(R.color.inrange)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val predictionColor: Int
|
||||||
|
get() {
|
||||||
|
return when (data.sourceSensor) {
|
||||||
|
GlucoseValue.SourceSensor.IOB_PREDICTION -> resourceHelper.gc(R.color.iob)
|
||||||
|
GlucoseValue.SourceSensor.COB_PREDICTION -> resourceHelper.gc(R.color.cob)
|
||||||
|
GlucoseValue.SourceSensor.aCOB_PREDICTION -> -0x7f000001 and resourceHelper.gc(R.color.cob)
|
||||||
|
GlucoseValue.SourceSensor.UAM_PREDICTION -> resourceHelper.gc(R.color.uam)
|
||||||
|
GlucoseValue.SourceSensor.ZT_PREDICTION -> resourceHelper.gc(R.color.zt)
|
||||||
|
else -> R.color.white
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isPrediction: Boolean
|
||||||
|
get() = data.sourceSensor == GlucoseValue.SourceSensor.IOB_PREDICTION ||
|
||||||
|
data.sourceSensor == GlucoseValue.SourceSensor.COB_PREDICTION ||
|
||||||
|
data.sourceSensor == GlucoseValue.SourceSensor.aCOB_PREDICTION ||
|
||||||
|
data.sourceSensor == GlucoseValue.SourceSensor.UAM_PREDICTION ||
|
||||||
|
data.sourceSensor == GlucoseValue.SourceSensor.ZT_PREDICTION
|
||||||
|
|
||||||
|
}
|
|
@ -1,334 +0,0 @@
|
||||||
package info.nightscout.androidaps.db;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import com.j256.ormlite.field.DatabaseField;
|
|
||||||
import com.j256.ormlite.table.DatabaseTable;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
|
||||||
import info.nightscout.androidaps.Constants;
|
|
||||||
import info.nightscout.androidaps.core.R;
|
|
||||||
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface;
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.DefaultValueHelper;
|
|
||||||
import info.nightscout.androidaps.utils.T;
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
|
||||||
|
|
||||||
@DatabaseTable(tableName = "BgReadings")
|
|
||||||
public class BgReading implements DataPointWithLabelInterface {
|
|
||||||
@Inject public AAPSLogger aapsLogger;
|
|
||||||
@Inject public DefaultValueHelper defaultValueHelper;
|
|
||||||
@Inject public ProfileFunction profileFunction;
|
|
||||||
@Inject public ResourceHelper resourceHelper;
|
|
||||||
@Inject public DateUtil dateUtil;
|
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
|
||||||
public long date;
|
|
||||||
|
|
||||||
@DatabaseField
|
|
||||||
public boolean isValid = true;
|
|
||||||
|
|
||||||
@DatabaseField
|
|
||||||
public double value;
|
|
||||||
@DatabaseField
|
|
||||||
public String direction;
|
|
||||||
@DatabaseField
|
|
||||||
public double raw;
|
|
||||||
|
|
||||||
@DatabaseField
|
|
||||||
public int source = Source.NONE;
|
|
||||||
@DatabaseField
|
|
||||||
public String _id = null; // NS _id
|
|
||||||
|
|
||||||
public boolean isCOBPrediction = false; // true when drawing predictions as bg points (COB)
|
|
||||||
public boolean isaCOBPrediction = false; // true when drawing predictions as bg points (aCOB)
|
|
||||||
public boolean isIOBPrediction = false; // true when drawing predictions as bg points (IOB)
|
|
||||||
public boolean isUAMPrediction = false; // true when drawing predictions as bg points (UAM)
|
|
||||||
public boolean isZTPrediction = false; // true when drawing predictions as bg points (ZT)
|
|
||||||
|
|
||||||
public BgReading() {
|
|
||||||
StaticInjector.Companion.getInstance().androidInjector().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgReading(HasAndroidInjector injector) {
|
|
||||||
injector.androidInjector().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgReading(HasAndroidInjector injector, NSSgv sgv) {
|
|
||||||
injector.androidInjector().inject(this);
|
|
||||||
date = sgv.getMills();
|
|
||||||
value = sgv.getMgdl();
|
|
||||||
raw = sgv.getFiltered() != null ? sgv.getFiltered() : value;
|
|
||||||
direction = sgv.getDirection();
|
|
||||||
_id = sgv.getId();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Double valueToUnits(String units) {
|
|
||||||
if (units.equals(Constants.MGDL))
|
|
||||||
return value;
|
|
||||||
else
|
|
||||||
return value * Constants.MGDL_TO_MMOLL;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String valueToUnitsToString(String units) {
|
|
||||||
if (units.equals(Constants.MGDL)) return DecimalFormatter.to0Decimal(value);
|
|
||||||
else return DecimalFormatter.to1Decimal(value * Constants.MGDL_TO_MMOLL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String directionToSymbol(DatabaseHelperInterface databaseHelper) {
|
|
||||||
String symbol = "";
|
|
||||||
if (direction == null)
|
|
||||||
direction = calculateDirection(databaseHelper);
|
|
||||||
|
|
||||||
if (direction.compareTo("DoubleDown") == 0) {
|
|
||||||
symbol = "\u21ca";
|
|
||||||
} else if (direction.compareTo("SingleDown") == 0) {
|
|
||||||
symbol = "\u2193";
|
|
||||||
} else if (direction.compareTo("FortyFiveDown") == 0) {
|
|
||||||
symbol = "\u2198";
|
|
||||||
} else if (direction.compareTo("Flat") == 0) {
|
|
||||||
symbol = "\u2192";
|
|
||||||
} else if (direction.compareTo("FortyFiveUp") == 0) {
|
|
||||||
symbol = "\u2197";
|
|
||||||
} else if (direction.compareTo("SingleUp") == 0) {
|
|
||||||
symbol = "\u2191";
|
|
||||||
} else if (direction.compareTo("DoubleUp") == 0) {
|
|
||||||
symbol = "\u21c8";
|
|
||||||
} else if (isSlopeNameInvalid(direction)) {
|
|
||||||
symbol = "??";
|
|
||||||
}
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int directionToIcon(DatabaseHelperInterface databaseHelper) {
|
|
||||||
int symbol = 0;
|
|
||||||
if (direction == null)
|
|
||||||
direction = calculateDirection(databaseHelper);
|
|
||||||
|
|
||||||
if (direction.compareTo("DoubleDown") == 0) {
|
|
||||||
symbol = R.drawable.ic_doubledown;
|
|
||||||
} else if (direction.compareTo("SingleDown") == 0) {
|
|
||||||
symbol = R.drawable.ic_singledown;
|
|
||||||
} else if (direction.compareTo("FortyFiveDown") == 0) {
|
|
||||||
symbol = R.drawable.ic_fortyfivedown;;
|
|
||||||
} else if (direction.compareTo("Flat") == 0) {
|
|
||||||
symbol = R.drawable.ic_flat;;
|
|
||||||
} else if (direction.compareTo("FortyFiveUp") == 0) {
|
|
||||||
symbol = R.drawable.ic_fortyfiveup;
|
|
||||||
} else if (direction.compareTo("SingleUp") == 0) {
|
|
||||||
symbol = R.drawable.ic_singleup;
|
|
||||||
} else if (direction.compareTo("DoubleUp") == 0) {
|
|
||||||
symbol = R.drawable.ic_doubleup;
|
|
||||||
} else if (isSlopeNameInvalid(direction)) {
|
|
||||||
symbol = R.drawable.ic_invalid;
|
|
||||||
}
|
|
||||||
return symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isSlopeNameInvalid(String direction) {
|
|
||||||
return direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
|
||||||
direction.compareTo("NOT COMPUTABLE") == 0 ||
|
|
||||||
direction.compareTo("OUT_OF_RANGE") == 0 ||
|
|
||||||
direction.compareTo("OUT OF RANGE") == 0 ||
|
|
||||||
direction.compareTo("NONE") == 0 ||
|
|
||||||
direction.compareTo("NotComputable") == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@NonNull @Override
|
|
||||||
public String toString() {
|
|
||||||
return "BgReading{" +
|
|
||||||
"date=" + date +
|
|
||||||
", date=" + dateUtil.dateAndTimeString(date) +
|
|
||||||
", value=" + value +
|
|
||||||
", direction=" + direction +
|
|
||||||
", raw=" + raw +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDataChanging(BgReading other) {
|
|
||||||
if (date != other.date) {
|
|
||||||
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value != other.value)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEqual(BgReading other) {
|
|
||||||
if (date != other.date) {
|
|
||||||
aapsLogger.debug(LTag.GLUCOSE, "Comparing different");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (value != other.value)
|
|
||||||
return false;
|
|
||||||
if (raw != other.raw)
|
|
||||||
return false;
|
|
||||||
if (!Objects.equals(direction, other.direction))
|
|
||||||
return false;
|
|
||||||
if (!Objects.equals(_id, other._id))
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void copyFrom(BgReading other) {
|
|
||||||
if (date != other.date) {
|
|
||||||
aapsLogger.error(LTag.GLUCOSE, "Copying different");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
value = other.value;
|
|
||||||
raw = other.raw;
|
|
||||||
direction = other.direction;
|
|
||||||
_id = other._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgReading date(long date) {
|
|
||||||
this.date = date;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgReading date(Date date) {
|
|
||||||
this.date = date.getTime();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BgReading value(double value) {
|
|
||||||
this.value = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------ DataPointWithLabelInterface ------------------
|
|
||||||
@Override
|
|
||||||
public double getX() {
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getY() {
|
|
||||||
return valueToUnits(profileFunction.getUnits());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setY(double y) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getLabel() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getDuration() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PointsWithLabelGraphSeries.Shape getShape() {
|
|
||||||
if (isPrediction())
|
|
||||||
return PointsWithLabelGraphSeries.Shape.PREDICTION;
|
|
||||||
else
|
|
||||||
return PointsWithLabelGraphSeries.Shape.BG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float getSize() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getColor() {
|
|
||||||
String units = profileFunction.getUnits();
|
|
||||||
Double lowLine = defaultValueHelper.determineLowLine();
|
|
||||||
Double highLine = defaultValueHelper.determineHighLine();
|
|
||||||
int color = resourceHelper.gc(R.color.inrange);
|
|
||||||
if (isPrediction())
|
|
||||||
return getPredectionColor();
|
|
||||||
else if (valueToUnits(units) < lowLine)
|
|
||||||
color = resourceHelper.gc(R.color.low);
|
|
||||||
else if (valueToUnits(units) > highLine)
|
|
||||||
color = resourceHelper.gc(R.color.high);
|
|
||||||
return color;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPredectionColor() {
|
|
||||||
if (isIOBPrediction)
|
|
||||||
return resourceHelper.gc(R.color.iob);
|
|
||||||
if (isCOBPrediction)
|
|
||||||
return resourceHelper.gc(R.color.cob);
|
|
||||||
if (isaCOBPrediction)
|
|
||||||
return 0x80FFFFFF & resourceHelper.gc(R.color.cob);
|
|
||||||
if (isUAMPrediction)
|
|
||||||
return resourceHelper.gc(R.color.uam);
|
|
||||||
if (isZTPrediction)
|
|
||||||
return resourceHelper.gc(R.color.zt);
|
|
||||||
return R.color.white;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPrediction() {
|
|
||||||
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Copied from xDrip+
|
|
||||||
String calculateDirection(DatabaseHelperInterface databasehelper) {
|
|
||||||
// Rework to get bgreaings from internal DB and calculate on that base
|
|
||||||
|
|
||||||
List<BgReading> bgReadingsList = databasehelper.getAllBgreadingsDataFromTime(this.date - T.mins(10).msecs(), false);
|
|
||||||
if (bgReadingsList == null || bgReadingsList.size() < 2)
|
|
||||||
return "NONE";
|
|
||||||
BgReading current = bgReadingsList.get(1);
|
|
||||||
BgReading previous = bgReadingsList.get(0);
|
|
||||||
|
|
||||||
if (bgReadingsList.get(1).date < bgReadingsList.get(0).date) {
|
|
||||||
current = bgReadingsList.get(0);
|
|
||||||
previous = bgReadingsList.get(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
double slope;
|
|
||||||
|
|
||||||
// Avoid division by 0
|
|
||||||
if (current.date == previous.date)
|
|
||||||
slope = 0;
|
|
||||||
else
|
|
||||||
slope = (previous.value - current.value) / (previous.date - current.date);
|
|
||||||
|
|
||||||
aapsLogger.error(LTag.GLUCOSE, "Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date));
|
|
||||||
|
|
||||||
double slope_by_minute = slope * 60000;
|
|
||||||
String arrow = "NONE";
|
|
||||||
|
|
||||||
if (slope_by_minute <= (-3.5)) {
|
|
||||||
arrow = "DoubleDown";
|
|
||||||
} else if (slope_by_minute <= (-2)) {
|
|
||||||
arrow = "SingleDown";
|
|
||||||
} else if (slope_by_minute <= (-1)) {
|
|
||||||
arrow = "FortyFiveDown";
|
|
||||||
} else if (slope_by_minute <= (1)) {
|
|
||||||
arrow = "Flat";
|
|
||||||
} else if (slope_by_minute <= (2)) {
|
|
||||||
arrow = "FortyFiveUp";
|
|
||||||
} else if (slope_by_minute <= (3.5)) {
|
|
||||||
arrow = "SingleUp";
|
|
||||||
} else if (slope_by_minute <= (40)) {
|
|
||||||
arrow = "DoubleUp";
|
|
||||||
}
|
|
||||||
aapsLogger.error(LTag.GLUCOSE, "Direction set to: " + arrow);
|
|
||||||
return arrow;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import info.nightscout.androidaps.db.*
|
||||||
|
|
||||||
interface DatabaseHelperInterface {
|
interface DatabaseHelperInterface {
|
||||||
|
|
||||||
fun getAllBgreadingsDataFromTime(mills: Long, ascending: Boolean): List<BgReading>
|
|
||||||
fun createOrUpdate(careportalEvent: CareportalEvent)
|
fun createOrUpdate(careportalEvent: CareportalEvent)
|
||||||
fun createOrUpdate(record: DanaRHistoryRecord)
|
fun createOrUpdate(record: DanaRHistoryRecord)
|
||||||
fun createOrUpdate(record: OmnipodHistoryRecord)
|
fun createOrUpdate(record: OmnipodHistoryRecord)
|
||||||
|
|
|
@ -1,436 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.aps.loop;
|
|
||||||
|
|
||||||
import android.text.Spanned;
|
|
||||||
|
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import dagger.android.HasAndroidInjector;
|
|
||||||
import info.nightscout.androidaps.core.R;
|
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
|
||||||
import info.nightscout.androidaps.data.Profile;
|
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
|
||||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
|
||||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider;
|
|
||||||
import info.nightscout.androidaps.interfaces.Constraint;
|
|
||||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
|
||||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
|
||||||
import info.nightscout.androidaps.logging.LTag;
|
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.HtmlHelper;
|
|
||||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
|
||||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 09.06.2016.
|
|
||||||
*/
|
|
||||||
public class APSResult {
|
|
||||||
@Inject HasAndroidInjector injector;
|
|
||||||
@Inject public AAPSLogger aapsLogger;
|
|
||||||
@Inject ConstraintChecker constraintChecker;
|
|
||||||
@Inject SP sp;
|
|
||||||
@Inject ActivePluginProvider activePlugin;
|
|
||||||
@Inject TreatmentsInterface treatmentsPlugin;
|
|
||||||
@Inject ProfileFunction profileFunction;
|
|
||||||
@Inject ResourceHelper resourceHelper;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public APSResult(HasAndroidInjector injector) {
|
|
||||||
injector.androidInjector().inject(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long date = 0;
|
|
||||||
public String reason;
|
|
||||||
public double rate;
|
|
||||||
public int percent;
|
|
||||||
public boolean usePercent = false;
|
|
||||||
public int duration;
|
|
||||||
public boolean tempBasalRequested = false;
|
|
||||||
public boolean bolusRequested = false;
|
|
||||||
public IobTotal iob;
|
|
||||||
public JSONObject json = new JSONObject();
|
|
||||||
public boolean hasPredictions = false;
|
|
||||||
public double smb = 0d; // super micro bolus in units
|
|
||||||
public long deliverAt = 0;
|
|
||||||
public double targetBG = 0d;
|
|
||||||
|
|
||||||
public int carbsReq = 0;
|
|
||||||
public int carbsReqWithin = 0;
|
|
||||||
|
|
||||||
public Constraint<Double> inputConstraints;
|
|
||||||
|
|
||||||
public Constraint<Double> rateConstraint;
|
|
||||||
public Constraint<Integer> percentConstraint;
|
|
||||||
public Constraint<Double> smbConstraint;
|
|
||||||
|
|
||||||
public APSResult rate(double rate) {
|
|
||||||
this.rate = rate;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult duration(int duration) {
|
|
||||||
this.duration = duration;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult percent(int percent) {
|
|
||||||
this.percent = percent;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult tempBasalRequested(boolean tempBasalRequested) {
|
|
||||||
this.tempBasalRequested = tempBasalRequested;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult usePercent(boolean usePercent) {
|
|
||||||
this.usePercent = usePercent;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult json(JSONObject json) {
|
|
||||||
this.json = json;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCarbsRequiredText() {
|
|
||||||
return String.format(resourceHelper.gs(R.string.carbsreq), carbsReq, carbsReqWithin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
final PumpInterface pump = activePlugin.getActivePump();
|
|
||||||
if (isChangeRequested()) {
|
|
||||||
String ret;
|
|
||||||
// rate
|
|
||||||
if (rate == 0 && duration == 0)
|
|
||||||
ret = resourceHelper.gs(R.string.canceltemp) + "\n";
|
|
||||||
else if (rate == -1)
|
|
||||||
ret = resourceHelper.gs(R.string.let_temp_basal_run) + "\n";
|
|
||||||
else if (usePercent)
|
|
||||||
ret = resourceHelper.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(percent) + "% " +
|
|
||||||
"(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)\n" +
|
|
||||||
resourceHelper.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min\n";
|
|
||||||
else
|
|
||||||
ret = resourceHelper.gs(R.string.rate) + ": " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
|
||||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100) + "%) \n" +
|
|
||||||
resourceHelper.gs(R.string.duration) + ": " + DecimalFormatter.to2Decimal(duration) + " min\n";
|
|
||||||
|
|
||||||
// smb
|
|
||||||
if (smb != 0)
|
|
||||||
ret += ("SMB: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.getActivePump(), resourceHelper) + "\n");
|
|
||||||
|
|
||||||
if (isCarbsRequired()) {
|
|
||||||
ret += getCarbsRequiredText()+"\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
// reason
|
|
||||||
ret += resourceHelper.gs(R.string.reason) + ": " + reason;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCarbsRequired()) {
|
|
||||||
return getCarbsRequiredText();
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceHelper.gs(R.string.nochangerequested);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Spanned toSpanned() {
|
|
||||||
final PumpInterface pump = activePlugin.getActivePump();
|
|
||||||
if (isChangeRequested()) {
|
|
||||||
String ret;
|
|
||||||
// rate
|
|
||||||
if (rate == 0 && duration == 0)
|
|
||||||
ret = resourceHelper.gs(R.string.canceltemp) + "<br>";
|
|
||||||
else if (rate == -1)
|
|
||||||
ret = resourceHelper.gs(R.string.let_temp_basal_run) + "<br>";
|
|
||||||
else if (usePercent)
|
|
||||||
ret = "<b>" + resourceHelper.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(percent) + "% " +
|
|
||||||
"(" + DecimalFormatter.to2Decimal(percent * pump.getBaseBasalRate() / 100d) + " U/h)<br>" +
|
|
||||||
"<b>" + resourceHelper.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
|
|
||||||
else
|
|
||||||
ret = "<b>" + resourceHelper.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
|
||||||
"(" + DecimalFormatter.to2Decimal(rate / pump.getBaseBasalRate() * 100d) + "%) <br>" +
|
|
||||||
"<b>" + resourceHelper.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration) + " min<br>";
|
|
||||||
|
|
||||||
// smb
|
|
||||||
if (smb != 0)
|
|
||||||
ret += ("<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.getActivePump(), resourceHelper) + "<br>");
|
|
||||||
|
|
||||||
if (isCarbsRequired()) {
|
|
||||||
ret += getCarbsRequiredText()+"<br>";
|
|
||||||
}
|
|
||||||
|
|
||||||
// reason
|
|
||||||
ret += "<b>" + resourceHelper.gs(R.string.reason) + "</b>: " + reason.replace("<", "<").replace(">", ">");
|
|
||||||
return HtmlHelper.INSTANCE.fromHtml(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCarbsRequired()) {
|
|
||||||
return HtmlHelper.INSTANCE.fromHtml(getCarbsRequiredText());
|
|
||||||
}
|
|
||||||
|
|
||||||
return HtmlHelper.INSTANCE.fromHtml(resourceHelper.gs(R.string.nochangerequested));
|
|
||||||
}
|
|
||||||
|
|
||||||
public APSResult newAndClone(HasAndroidInjector injector) {
|
|
||||||
APSResult newResult = new APSResult(injector);
|
|
||||||
doClone(newResult);
|
|
||||||
return newResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doClone(APSResult newResult) {
|
|
||||||
newResult.date = date;
|
|
||||||
newResult.reason = reason != null ? reason : null;
|
|
||||||
newResult.rate = rate;
|
|
||||||
newResult.duration = duration;
|
|
||||||
newResult.tempBasalRequested = tempBasalRequested;
|
|
||||||
newResult.bolusRequested = bolusRequested;
|
|
||||||
newResult.iob = iob;
|
|
||||||
try {
|
|
||||||
newResult.json = new JSONObject(json.toString());
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
newResult.hasPredictions = hasPredictions;
|
|
||||||
newResult.smb = smb;
|
|
||||||
newResult.deliverAt = deliverAt;
|
|
||||||
newResult.rateConstraint = rateConstraint;
|
|
||||||
newResult.smbConstraint = smbConstraint;
|
|
||||||
newResult.percent = percent;
|
|
||||||
newResult.usePercent = usePercent;
|
|
||||||
newResult.carbsReq = carbsReq;
|
|
||||||
newResult.carbsReqWithin = carbsReqWithin;
|
|
||||||
newResult.targetBG = targetBG;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public JSONObject json() {
|
|
||||||
JSONObject json = new JSONObject();
|
|
||||||
try {
|
|
||||||
if (isChangeRequested()) {
|
|
||||||
json.put("rate", rate);
|
|
||||||
json.put("duration", duration);
|
|
||||||
json.put("reason", reason);
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<BgReading> getPredictions() {
|
|
||||||
List<BgReading> array = new ArrayList<>();
|
|
||||||
try {
|
|
||||||
long startTime = date;
|
|
||||||
if (json != null && json.has("predBGs")) {
|
|
||||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
|
||||||
if (predBGs.has("IOB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
|
||||||
for (int i = 1; i < iob.length(); i++) {
|
|
||||||
BgReading bg = new BgReading();
|
|
||||||
bg.value = iob.getInt(i);
|
|
||||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
|
||||||
bg.isIOBPrediction = true;
|
|
||||||
array.add(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (predBGs.has("aCOB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
|
||||||
for (int i = 1; i < iob.length(); i++) {
|
|
||||||
BgReading bg = new BgReading();
|
|
||||||
bg.value = iob.getInt(i);
|
|
||||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
|
||||||
bg.isaCOBPrediction = true;
|
|
||||||
array.add(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (predBGs.has("COB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("COB");
|
|
||||||
for (int i = 1; i < iob.length(); i++) {
|
|
||||||
BgReading bg = new BgReading();
|
|
||||||
bg.value = iob.getInt(i);
|
|
||||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
|
||||||
bg.isCOBPrediction = true;
|
|
||||||
array.add(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (predBGs.has("UAM")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("UAM");
|
|
||||||
for (int i = 1; i < iob.length(); i++) {
|
|
||||||
BgReading bg = new BgReading();
|
|
||||||
bg.value = iob.getInt(i);
|
|
||||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
|
||||||
bg.isUAMPrediction = true;
|
|
||||||
array.add(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (predBGs.has("ZT")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("ZT");
|
|
||||||
for (int i = 1; i < iob.length(); i++) {
|
|
||||||
BgReading bg = new BgReading();
|
|
||||||
bg.value = iob.getInt(i);
|
|
||||||
bg.date = startTime + i * 5 * 60 * 1000L;
|
|
||||||
bg.isZTPrediction = true;
|
|
||||||
array.add(bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLatestPredictionsTime() {
|
|
||||||
long latest = 0;
|
|
||||||
try {
|
|
||||||
long startTime = date;
|
|
||||||
if (json != null && json.has("predBGs")) {
|
|
||||||
JSONObject predBGs = json.getJSONObject("predBGs");
|
|
||||||
if (predBGs.has("IOB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("IOB");
|
|
||||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
|
||||||
}
|
|
||||||
if (predBGs.has("aCOB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("aCOB");
|
|
||||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
|
||||||
}
|
|
||||||
if (predBGs.has("COB")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("COB");
|
|
||||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
|
||||||
}
|
|
||||||
if (predBGs.has("UAM")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("UAM");
|
|
||||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
|
||||||
}
|
|
||||||
if (predBGs.has("ZT")) {
|
|
||||||
JSONArray iob = predBGs.getJSONArray("ZT");
|
|
||||||
latest = Math.max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return latest;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isCarbsRequired() {
|
|
||||||
return carbsReq > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isChangeRequested() {
|
|
||||||
Constraint<Boolean> closedLoopEnabled = constraintChecker.isClosedLoopAllowed();
|
|
||||||
// closed loop mode: handle change at driver level
|
|
||||||
if (closedLoopEnabled.value()) {
|
|
||||||
aapsLogger.debug(LTag.APS, "DEFAULT: Closed mode");
|
|
||||||
return tempBasalRequested || bolusRequested;
|
|
||||||
}
|
|
||||||
|
|
||||||
// open loop mode: try to limit request
|
|
||||||
if (!tempBasalRequested && !bolusRequested) {
|
|
||||||
aapsLogger.debug(LTag.APS, "FALSE: No request");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
TemporaryBasal activeTemp = treatmentsPlugin.getTempBasalFromHistory(now);
|
|
||||||
PumpInterface pump = activePlugin.getActivePump();
|
|
||||||
Profile profile = profileFunction.getProfile();
|
|
||||||
|
|
||||||
if (profile == null) {
|
|
||||||
aapsLogger.error("FALSE: No Profile");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (usePercent) {
|
|
||||||
if (activeTemp == null && percent == 100) {
|
|
||||||
aapsLogger.debug(LTag.APS, "FALSE: No temp running, asking cancel temp");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (activeTemp != null && Math.abs(percent - activeTemp.tempBasalConvertedToPercent(now, profile)) < pump.getPumpDescription().basalStep) {
|
|
||||||
aapsLogger.debug(LTag.APS, "FALSE: Temp equal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// always report zerotemp
|
|
||||||
if (percent == 0) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Zero temp");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// always report hightemp
|
|
||||||
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.PERCENT) {
|
|
||||||
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
|
|
||||||
if (percent == pumpLimit) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Pump limit");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// report change bigger than 30%
|
|
||||||
double percentMinChangeChange = sp.getDouble(R.string.key_loop_openmode_min_change, 30d);
|
|
||||||
percentMinChangeChange /= 100d;
|
|
||||||
double lowThreshold = 1 - percentMinChangeChange;
|
|
||||||
double highThreshold = 1 + percentMinChangeChange;
|
|
||||||
double change = percent / 100d;
|
|
||||||
if (activeTemp != null)
|
|
||||||
change = percent / (double) activeTemp.tempBasalConvertedToPercent(now, profile);
|
|
||||||
|
|
||||||
if (change < lowThreshold || change > highThreshold) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Outside allowed range " + (change * 100d) + "%");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Inside allowed range " + (change * 100d) + "%");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (activeTemp == null && rate == pump.getBaseBasalRate()) {
|
|
||||||
aapsLogger.debug(LTag.APS, "FALSE: No temp running, asking cancel temp");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (activeTemp != null && Math.abs(rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.getPumpDescription().basalStep) {
|
|
||||||
aapsLogger.debug(LTag.APS, "FALSE: Temp equal");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// always report zerotemp
|
|
||||||
if (rate == 0) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Zero temp");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// always report hightemp
|
|
||||||
if (pump.getPumpDescription().tempBasalStyle == PumpDescription.ABSOLUTE) {
|
|
||||||
double pumpLimit = pump.getPumpDescription().pumpType.getTbrSettings().getMaxDose();
|
|
||||||
if (rate == pumpLimit) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Pump limit");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// report change bigger than 30%
|
|
||||||
double percentMinChangeChange = sp.getDouble(R.string.key_loop_openmode_min_change, 30d);
|
|
||||||
percentMinChangeChange /= 100d;
|
|
||||||
double lowThreshold = 1 - percentMinChangeChange;
|
|
||||||
double highThreshold = 1 + percentMinChangeChange;
|
|
||||||
double change = rate / profile.getBasal();
|
|
||||||
if (activeTemp != null)
|
|
||||||
change = rate / activeTemp.tempBasalConvertedToAbsolute(now, profile);
|
|
||||||
|
|
||||||
if (change < lowThreshold || change > highThreshold) {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Outside allowed range " + (change * 100d) + "%");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
aapsLogger.debug(LTag.APS, "TRUE: Inside allowed range " + (change * 100d) + "%");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
package info.nightscout.androidaps.plugins.aps.loop
|
||||||
|
|
||||||
|
import android.text.Spanned
|
||||||
|
import dagger.android.HasAndroidInjector
|
||||||
|
import info.nightscout.androidaps.core.R
|
||||||
|
import info.nightscout.androidaps.data.GlucoseValueDataPoint
|
||||||
|
import info.nightscout.androidaps.data.IobTotal
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||||
|
import info.nightscout.androidaps.interfaces.Constraint
|
||||||
|
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpDescription
|
||||||
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter
|
||||||
|
import info.nightscout.androidaps.utils.HtmlHelper.fromHtml
|
||||||
|
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
|
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||||
|
import org.json.JSONException
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 09.06.2016.
|
||||||
|
*/
|
||||||
|
open class APSResult @Inject constructor(val injector: HasAndroidInjector) {
|
||||||
|
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||||
|
@Inject lateinit var sp: SP
|
||||||
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
|
@Inject lateinit var treatmentsPlugin: TreatmentsInterface
|
||||||
|
@Inject lateinit var profileFunction: ProfileFunction
|
||||||
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
|
|
||||||
|
var date: Long = 0
|
||||||
|
var reason: String? = null
|
||||||
|
var rate = 0.0
|
||||||
|
var percent = 0
|
||||||
|
var usePercent = false
|
||||||
|
var duration = 0
|
||||||
|
var tempBasalRequested = false
|
||||||
|
var bolusRequested = false
|
||||||
|
var iob: IobTotal? = null
|
||||||
|
var json: JSONObject? = JSONObject()
|
||||||
|
var hasPredictions = false
|
||||||
|
var smb = 0.0 // super micro bolus in units
|
||||||
|
var deliverAt: Long = 0
|
||||||
|
var targetBG = 0.0
|
||||||
|
var carbsReq = 0
|
||||||
|
var carbsReqWithin = 0
|
||||||
|
var inputConstraints: Constraint<Double>? = null
|
||||||
|
var rateConstraint: Constraint<Double>? = null
|
||||||
|
var percentConstraint: Constraint<Int>? = null
|
||||||
|
var smbConstraint: Constraint<Double>? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
injector.androidInjector().inject(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rate(rate: Double): APSResult {
|
||||||
|
this.rate = rate
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun duration(duration: Int): APSResult {
|
||||||
|
this.duration = duration
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun percent(percent: Int): APSResult {
|
||||||
|
this.percent = percent
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tempBasalRequested(tempBasalRequested: Boolean): APSResult {
|
||||||
|
this.tempBasalRequested = tempBasalRequested
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun usePercent(usePercent: Boolean): APSResult {
|
||||||
|
this.usePercent = usePercent
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun json(json: JSONObject?): APSResult {
|
||||||
|
this.json = json
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
val carbsRequiredText: String
|
||||||
|
get() = String.format(resourceHelper.gs(R.string.carbsreq), carbsReq, carbsReqWithin)
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
val pump = activePlugin.activePump
|
||||||
|
if (isChangeRequested) {
|
||||||
|
// rate
|
||||||
|
var ret: String = if (rate == 0.0 && duration == 0) "${resourceHelper.gs(R.string.canceltemp)}\n"
|
||||||
|
else if (rate == -1.0) "${resourceHelper.gs(R.string.let_temp_basal_run)}\n"
|
||||||
|
else if (usePercent) "${resourceHelper.gs(R.string.rate)}: ${DecimalFormatter.to2Decimal(percent.toDouble())}% (${DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0)} U/h)\n" +
|
||||||
|
"${resourceHelper.gs(R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min\n"
|
||||||
|
else "${resourceHelper.gs(R.string.rate)}: ${DecimalFormatter.to2Decimal(rate)} U/h (${DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100)}%)" +
|
||||||
|
"${resourceHelper.gs(R.string.duration)}: ${DecimalFormatter.to2Decimal(duration.toDouble())} min\n"
|
||||||
|
// smb
|
||||||
|
if (smb != 0.0) ret += "SMB: ${DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, resourceHelper)}\n"
|
||||||
|
if (isCarbsRequired) {
|
||||||
|
ret += "$carbsRequiredText\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
// reason
|
||||||
|
ret += resourceHelper.gs(R.string.reason) + ": " + reason
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return if (isCarbsRequired) {
|
||||||
|
carbsRequiredText
|
||||||
|
} else resourceHelper.gs(R.string.nochangerequested)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toSpanned(): Spanned {
|
||||||
|
val pump = activePlugin.activePump
|
||||||
|
if (isChangeRequested) {
|
||||||
|
// rate
|
||||||
|
var ret: String = if (rate == 0.0 && duration == 0) resourceHelper.gs(R.string.canceltemp) + "<br>" else if (rate == -1.0) resourceHelper.gs(R.string.let_temp_basal_run) + "<br>" else if (usePercent) "<b>" + resourceHelper.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(percent.toDouble()) + "% " +
|
||||||
|
"(" + DecimalFormatter.to2Decimal(percent * pump.baseBasalRate / 100.0) + " U/h)<br>" +
|
||||||
|
"<b>" + resourceHelper.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>" else "<b>" + resourceHelper.gs(R.string.rate) + "</b>: " + DecimalFormatter.to2Decimal(rate) + " U/h " +
|
||||||
|
"(" + DecimalFormatter.to2Decimal(rate / pump.baseBasalRate * 100.0) + "%) <br>" +
|
||||||
|
"<b>" + resourceHelper.gs(R.string.duration) + "</b>: " + DecimalFormatter.to2Decimal(duration.toDouble()) + " min<br>"
|
||||||
|
|
||||||
|
// smb
|
||||||
|
if (smb != 0.0) ret += "<b>" + "SMB" + "</b>: " + DecimalFormatter.toPumpSupportedBolus(smb, activePlugin.activePump, resourceHelper) + "<br>"
|
||||||
|
if (isCarbsRequired) {
|
||||||
|
ret += "$carbsRequiredText<br>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// reason
|
||||||
|
ret += "<b>" + resourceHelper.gs(R.string.reason) + "</b>: " + reason!!.replace("<", "<").replace(">", ">")
|
||||||
|
return fromHtml(ret)
|
||||||
|
}
|
||||||
|
return if (isCarbsRequired) {
|
||||||
|
fromHtml(carbsRequiredText)
|
||||||
|
} else fromHtml(resourceHelper.gs(R.string.nochangerequested))
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun newAndClone(injector: HasAndroidInjector): APSResult {
|
||||||
|
val newResult = APSResult(injector)
|
||||||
|
doClone(newResult)
|
||||||
|
return newResult
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun doClone(newResult: APSResult) {
|
||||||
|
newResult.date = date
|
||||||
|
newResult.reason = if (reason != null) reason else null
|
||||||
|
newResult.rate = rate
|
||||||
|
newResult.duration = duration
|
||||||
|
newResult.tempBasalRequested = tempBasalRequested
|
||||||
|
newResult.bolusRequested = bolusRequested
|
||||||
|
newResult.iob = iob
|
||||||
|
newResult.json = JSONObject(json.toString())
|
||||||
|
newResult.hasPredictions = hasPredictions
|
||||||
|
newResult.smb = smb
|
||||||
|
newResult.deliverAt = deliverAt
|
||||||
|
newResult.rateConstraint = rateConstraint
|
||||||
|
newResult.smbConstraint = smbConstraint
|
||||||
|
newResult.percent = percent
|
||||||
|
newResult.usePercent = usePercent
|
||||||
|
newResult.carbsReq = carbsReq
|
||||||
|
newResult.carbsReqWithin = carbsReqWithin
|
||||||
|
newResult.targetBG = targetBG
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun json(): JSONObject? {
|
||||||
|
val json = JSONObject()
|
||||||
|
if (isChangeRequested) {
|
||||||
|
json.put("rate", rate)
|
||||||
|
json.put("duration", duration)
|
||||||
|
json.put("reason", reason)
|
||||||
|
}
|
||||||
|
return json
|
||||||
|
}
|
||||||
|
|
||||||
|
val predictions: MutableList<GlucoseValueDataPoint>
|
||||||
|
get() {
|
||||||
|
val array: MutableList<GlucoseValueDataPoint> = ArrayList()
|
||||||
|
val startTime = date
|
||||||
|
json?.let { json ->
|
||||||
|
if (json.has("predBGs")) {
|
||||||
|
val predBGs = json.getJSONObject("predBGs")
|
||||||
|
if (predBGs.has("IOB")) {
|
||||||
|
val iob = predBGs.getJSONArray("IOB")
|
||||||
|
for (i in 1 until iob.length()) {
|
||||||
|
val gv = GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = iob.getInt(i).toDouble(),
|
||||||
|
timestamp = startTime + i * 5 * 60 * 1000L,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.IOB_PREDICTION,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||||
|
)
|
||||||
|
array.add(GlucoseValueDataPoint(injector, gv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (predBGs.has("aCOB")) {
|
||||||
|
val iob = predBGs.getJSONArray("aCOB")
|
||||||
|
for (i in 1 until iob.length()) {
|
||||||
|
val gv = GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = iob.getInt(i).toDouble(),
|
||||||
|
timestamp = startTime + i * 5 * 60 * 1000L,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.aCOB_PREDICTION,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||||
|
)
|
||||||
|
array.add(GlucoseValueDataPoint(injector, gv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (predBGs.has("COB")) {
|
||||||
|
val iob = predBGs.getJSONArray("COB")
|
||||||
|
for (i in 1 until iob.length()) {
|
||||||
|
val gv = GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = iob.getInt(i).toDouble(),
|
||||||
|
timestamp = startTime + i * 5 * 60 * 1000L,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.COB_PREDICTION,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||||
|
)
|
||||||
|
array.add(GlucoseValueDataPoint(injector, gv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (predBGs.has("UAM")) {
|
||||||
|
val iob = predBGs.getJSONArray("UAM")
|
||||||
|
for (i in 1 until iob.length()) {
|
||||||
|
val gv = GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = iob.getInt(i).toDouble(),
|
||||||
|
timestamp = startTime + i * 5 * 60 * 1000L,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.UAM_PREDICTION,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||||
|
)
|
||||||
|
array.add(GlucoseValueDataPoint(injector, gv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (predBGs.has("ZT")) {
|
||||||
|
val iob = predBGs.getJSONArray("ZT")
|
||||||
|
for (i in 1 until iob.length()) {
|
||||||
|
val gv = GlucoseValue(
|
||||||
|
raw = 0.0,
|
||||||
|
noise = 0.0,
|
||||||
|
value = iob.getInt(i).toDouble(),
|
||||||
|
timestamp = startTime + i * 5 * 60 * 1000L,
|
||||||
|
sourceSensor = GlucoseValue.SourceSensor.ZT_PREDICTION,
|
||||||
|
trendArrow = GlucoseValue.TrendArrow.NONE
|
||||||
|
)
|
||||||
|
array.add(GlucoseValueDataPoint(injector, gv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array
|
||||||
|
}
|
||||||
|
val latestPredictionsTime: Long
|
||||||
|
get() {
|
||||||
|
var latest: Long = 0
|
||||||
|
try {
|
||||||
|
val startTime = date
|
||||||
|
if (json != null && json!!.has("predBGs")) {
|
||||||
|
val predBGs = json!!.getJSONObject("predBGs")
|
||||||
|
if (predBGs.has("IOB")) {
|
||||||
|
val iob = predBGs.getJSONArray("IOB")
|
||||||
|
latest = max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
if (predBGs.has("aCOB")) {
|
||||||
|
val iob = predBGs.getJSONArray("aCOB")
|
||||||
|
latest = max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
if (predBGs.has("COB")) {
|
||||||
|
val iob = predBGs.getJSONArray("COB")
|
||||||
|
latest = max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
if (predBGs.has("UAM")) {
|
||||||
|
val iob = predBGs.getJSONArray("UAM")
|
||||||
|
latest = max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
if (predBGs.has("ZT")) {
|
||||||
|
val iob = predBGs.getJSONArray("ZT")
|
||||||
|
latest = max(latest, startTime + (iob.length() - 1) * 5 * 60 * 1000L)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: JSONException) {
|
||||||
|
aapsLogger.error("Unhandled exception", e)
|
||||||
|
}
|
||||||
|
return latest
|
||||||
|
}
|
||||||
|
val isCarbsRequired: Boolean
|
||||||
|
get() = carbsReq > 0
|
||||||
|
|
||||||
|
val isChangeRequested: Boolean
|
||||||
|
get() {
|
||||||
|
val closedLoopEnabled = constraintChecker.isClosedLoopAllowed()
|
||||||
|
// closed loop mode: handle change at driver level
|
||||||
|
if (closedLoopEnabled.value()) {
|
||||||
|
aapsLogger.debug(LTag.APS, "DEFAULT: Closed mode")
|
||||||
|
return tempBasalRequested || bolusRequested
|
||||||
|
}
|
||||||
|
|
||||||
|
// open loop mode: try to limit request
|
||||||
|
if (!tempBasalRequested && !bolusRequested) {
|
||||||
|
aapsLogger.debug(LTag.APS, "FALSE: No request")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
val activeTemp = treatmentsPlugin.getTempBasalFromHistory(now)
|
||||||
|
val pump = activePlugin.activePump
|
||||||
|
val profile = profileFunction.getProfile()
|
||||||
|
if (profile == null) {
|
||||||
|
aapsLogger.error("FALSE: No Profile")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return if (usePercent) {
|
||||||
|
if (activeTemp == null && percent == 100) {
|
||||||
|
aapsLogger.debug(LTag.APS, "FALSE: No temp running, asking cancel temp")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (activeTemp != null && abs(percent - activeTemp.tempBasalConvertedToPercent(now, profile)) < pump.pumpDescription.basalStep) {
|
||||||
|
aapsLogger.debug(LTag.APS, "FALSE: Temp equal")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// always report zerotemp
|
||||||
|
if (percent == 0) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Zero temp")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// always report hightemp
|
||||||
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.PERCENT) {
|
||||||
|
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose
|
||||||
|
if (percent.toDouble() == pumpLimit) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Pump limit")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// report change bigger than 30%
|
||||||
|
var percentMinChangeChange = sp.getDouble(R.string.key_loop_openmode_min_change, 30.0)
|
||||||
|
percentMinChangeChange /= 100.0
|
||||||
|
val lowThreshold = 1 - percentMinChangeChange
|
||||||
|
val highThreshold = 1 + percentMinChangeChange
|
||||||
|
var change = percent / 100.0
|
||||||
|
if (activeTemp != null) change = percent / activeTemp.tempBasalConvertedToPercent(now, profile).toDouble()
|
||||||
|
if (change < lowThreshold || change > highThreshold) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Outside allowed range " + change * 100.0 + "%")
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Inside allowed range " + change * 100.0 + "%")
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (activeTemp == null && rate == pump.baseBasalRate) {
|
||||||
|
aapsLogger.debug(LTag.APS, "FALSE: No temp running, asking cancel temp")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (activeTemp != null && abs(rate - activeTemp.tempBasalConvertedToAbsolute(now, profile)) < pump.pumpDescription.basalStep) {
|
||||||
|
aapsLogger.debug(LTag.APS, "FALSE: Temp equal")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// always report zerotemp
|
||||||
|
if (rate == 0.0) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Zero temp")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// always report hightemp
|
||||||
|
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||||
|
val pumpLimit = pump.pumpDescription.pumpType.tbrSettings.maxDose
|
||||||
|
if (rate == pumpLimit) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Pump limit")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// report change bigger than 30%
|
||||||
|
var percentMinChangeChange = sp.getDouble(R.string.key_loop_openmode_min_change, 30.0)
|
||||||
|
percentMinChangeChange /= 100.0
|
||||||
|
val lowThreshold = 1 - percentMinChangeChange
|
||||||
|
val highThreshold = 1 + percentMinChangeChange
|
||||||
|
var change = rate / profile.basal
|
||||||
|
if (activeTemp != null) change = rate / activeTemp.tempBasalConvertedToAbsolute(now, profile)
|
||||||
|
if (change < lowThreshold || change > highThreshold) {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Outside allowed range " + change * 100.0 + "%")
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
aapsLogger.debug(LTag.APS, "TRUE: Inside allowed range " + change * 100.0 + "%")
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,15 @@
|
||||||
package info.nightscout.androidaps.plugins.general.nsclient;
|
package info.nightscout.androidaps.plugins.general.nsclient;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.json.JSONArray;
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
@ -26,7 +19,7 @@ import info.nightscout.androidaps.core.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.database.entities.GlucoseValue;
|
||||||
import info.nightscout.androidaps.db.CareportalEvent;
|
import info.nightscout.androidaps.db.CareportalEvent;
|
||||||
import info.nightscout.androidaps.db.DbRequest;
|
import info.nightscout.androidaps.db.DbRequest;
|
||||||
import info.nightscout.androidaps.db.ExtendedBolus;
|
import info.nightscout.androidaps.db.ExtendedBolus;
|
||||||
|
@ -211,7 +204,7 @@ public class NSUpload {
|
||||||
apsResult.json().put("timestamp", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
apsResult.json().put("timestamp", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
||||||
deviceStatus.suggested = apsResult.json();
|
deviceStatus.suggested = apsResult.json();
|
||||||
|
|
||||||
deviceStatus.iob = lastRun.getRequest().iob.json();
|
deviceStatus.iob = lastRun.getRequest().getIob().json();
|
||||||
deviceStatus.iob.put("time", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
deviceStatus.iob.put("time", DateUtil.toISOString(lastRun.getLastAPSRun()));
|
||||||
|
|
||||||
JSONObject requested = new JSONObject();
|
JSONObject requested = new JSONObject();
|
||||||
|
@ -221,8 +214,8 @@ public class NSUpload {
|
||||||
deviceStatus.enacted.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate"));
|
deviceStatus.enacted.put("rate", lastRun.getTbrSetByPump().json(profile).get("rate"));
|
||||||
deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration"));
|
deviceStatus.enacted.put("duration", lastRun.getTbrSetByPump().json(profile).get("duration"));
|
||||||
deviceStatus.enacted.put("recieved", true);
|
deviceStatus.enacted.put("recieved", true);
|
||||||
requested.put("duration", lastRun.getRequest().duration);
|
requested.put("duration", lastRun.getRequest().getDuration());
|
||||||
requested.put("rate", lastRun.getRequest().rate);
|
requested.put("rate", lastRun.getRequest().getRate());
|
||||||
requested.put("temp", "absolute");
|
requested.put("temp", "absolute");
|
||||||
deviceStatus.enacted.put("requested", requested);
|
deviceStatus.enacted.put("requested", requested);
|
||||||
}
|
}
|
||||||
|
@ -231,7 +224,7 @@ public class NSUpload {
|
||||||
deviceStatus.enacted = lastRun.getRequest().json();
|
deviceStatus.enacted = lastRun.getRequest().json();
|
||||||
}
|
}
|
||||||
deviceStatus.enacted.put("smb", lastRun.getTbrSetByPump().bolusDelivered);
|
deviceStatus.enacted.put("smb", lastRun.getTbrSetByPump().bolusDelivered);
|
||||||
requested.put("smb", lastRun.getRequest().smb);
|
requested.put("smb", lastRun.getRequest().getSmb());
|
||||||
deviceStatus.enacted.put("requested", requested);
|
deviceStatus.enacted.put("requested", requested);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -402,14 +395,14 @@ public class NSUpload {
|
||||||
uploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
uploadQueue.add(new DbRequest("dbAdd", "treatments", data));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uploadBg(BgReading reading, String source) {
|
public void uploadBg(GlucoseValue reading, String source) {
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("device", source);
|
data.put("device", source);
|
||||||
data.put("date", reading.date);
|
data.put("date", reading.getTimestamp());
|
||||||
data.put("dateString", DateUtil.toISOString(reading.date));
|
data.put("dateString", DateUtil.toISOString(reading.getTimestamp()));
|
||||||
data.put("sgv", reading.value);
|
data.put("sgv", reading.getValue());
|
||||||
data.put("direction", reading.direction);
|
data.put("direction", reading.getTrendArrow().getText());
|
||||||
data.put("type", "sgv");
|
data.put("type", "sgv");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
aapsLogger.error("Unhandled exception", e);
|
aapsLogger.error("Unhandled exception", e);
|
||||||
|
@ -417,6 +410,24 @@ public class NSUpload {
|
||||||
uploadQueue.add(new DbRequest("dbAdd", "entries", data));
|
uploadQueue.add(new DbRequest("dbAdd", "entries", data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateBg(GlucoseValue reading, String source) {
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
try {
|
||||||
|
data.put("device", source);
|
||||||
|
data.put("date", reading.getTimestamp());
|
||||||
|
data.put("dateString", DateUtil.toISOString(reading.getTimestamp()));
|
||||||
|
data.put("sgv", reading.getValue());
|
||||||
|
data.put("direction", reading.getTrendArrow().getText());
|
||||||
|
data.put("type", "sgv");
|
||||||
|
if (reading.getInterfaceIDs() != null)
|
||||||
|
if (reading.getInterfaceIDs().getNightscoutId() != null) {
|
||||||
|
uploadQueue.add(new DbRequest("dbUpdate", "entries", reading.getInterfaceIDs().getNightscoutId(), data));
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
aapsLogger.error("Unhandled exception", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void uploadAppStart() {
|
public void uploadAppStart() {
|
||||||
if (sp.getBoolean(R.string.key_ns_logappstartedevent, true)) {
|
if (sp.getBoolean(R.string.key_ns_logappstartedevent, true)) {
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
|
@ -461,46 +472,6 @@ public class NSUpload {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendToXdrip(BgReading bgReading) {
|
|
||||||
final String XDRIP_PLUS_NS_EMULATOR = "com.eveningoutpost.dexdrip.NS_EMULATOR";
|
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", Locale.US);
|
|
||||||
|
|
||||||
try {
|
|
||||||
final JSONArray entriesBody = new JSONArray();
|
|
||||||
JSONObject json = new JSONObject();
|
|
||||||
json.put("sgv", bgReading.value);
|
|
||||||
if (bgReading.direction == null) {
|
|
||||||
json.put("direction", "NONE");
|
|
||||||
} else {
|
|
||||||
json.put("direction", bgReading.direction);
|
|
||||||
}
|
|
||||||
json.put("device", "G5");
|
|
||||||
json.put("type", "sgv");
|
|
||||||
json.put("date", bgReading.date);
|
|
||||||
json.put("dateString", format.format(bgReading.date));
|
|
||||||
entriesBody.put(json);
|
|
||||||
|
|
||||||
final Bundle bundle = new Bundle();
|
|
||||||
bundle.putString("action", "add");
|
|
||||||
bundle.putString("collection", "entries");
|
|
||||||
bundle.putString("data", entriesBody.toString());
|
|
||||||
final Intent intent = new Intent(XDRIP_PLUS_NS_EMULATOR);
|
|
||||||
intent.putExtras(bundle).addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
|
||||||
context.sendBroadcast(intent);
|
|
||||||
List<ResolveInfo> receivers = context.getPackageManager().queryBroadcastReceivers(intent, 0);
|
|
||||||
if (receivers.size() < 1) {
|
|
||||||
aapsLogger.debug("No xDrip receivers found. ");
|
|
||||||
} else {
|
|
||||||
aapsLogger.debug(receivers.size() + " xDrip receivers");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} catch (JSONException e) {
|
|
||||||
aapsLogger.error("Unhandled exception", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createNSTreatment(JSONObject data, ProfileStore profileStore, ProfileFunction profileFunction, long eventTime) {
|
public void createNSTreatment(JSONObject data, ProfileStore profileStore, ProfileFunction profileFunction, long eventTime) {
|
||||||
if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
|
if (JsonHelper.safeGetString(data, "eventType", "").equals(CareportalEvent.PROFILESWITCH)) {
|
||||||
ProfileSwitch profileSwitch = profileFunction.prepareProfileSwitch(
|
ProfileSwitch profileSwitch = profileFunction.prepareProfileSwitch(
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package info.nightscout.androidaps.utils.extensions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.core.R
|
||||||
|
import info.nightscout.androidaps.database.entities.GlucoseValue
|
||||||
|
|
||||||
|
fun GlucoseValue.TrendArrow.directionToIcon(): Int {
|
||||||
|
return when {
|
||||||
|
this == GlucoseValue.TrendArrow.DOUBLE_DOWN -> R.drawable.ic_doubledown
|
||||||
|
this == GlucoseValue.TrendArrow.SINGLE_DOWN -> R.drawable.ic_singledown
|
||||||
|
this == GlucoseValue.TrendArrow.FORTY_FIVE_DOWN -> R.drawable.ic_fortyfivedown
|
||||||
|
this == GlucoseValue.TrendArrow.FLAT -> R.drawable.ic_flat
|
||||||
|
this == GlucoseValue.TrendArrow.FORTY_FIVE_UP -> R.drawable.ic_fortyfiveup
|
||||||
|
this == GlucoseValue.TrendArrow.SINGLE_UP -> R.drawable.ic_singleup
|
||||||
|
this == GlucoseValue.TrendArrow.DOUBLE_UP -> R.drawable.ic_doubleup
|
||||||
|
this == GlucoseValue.TrendArrow.NONE -> R.drawable.ic_invalid
|
||||||
|
else -> R.drawable.ic_invalid
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||||
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
|
||||||
import info.nightscout.androidaps.queue.Callback
|
import info.nightscout.androidaps.queue.Callback
|
||||||
import info.nightscout.androidaps.utils.FabricPrivacy
|
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||||
import info.nightscout.androidaps.utils.extensions.plusAssign
|
import io.reactivex.rxkotlin.plusAssign
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
|
|
@ -60,12 +60,12 @@ class AppRepository @Inject internal constructor(
|
||||||
fun clearDatabases() = database.clearAllTables()
|
fun clearDatabases() = database.clearAllTables()
|
||||||
|
|
||||||
//BG READINGS -- only valid records
|
//BG READINGS -- only valid records
|
||||||
fun compatGetBgReadingsDataFromTime(timestamp: Long, ascending: Boolean) =
|
fun compatGetBgReadingsDataFromTime(timestamp: Long, ascending: Boolean): Single<List<GlucoseValue>> =
|
||||||
database.glucoseValueDao.compatGetBgReadingsDataFromTime(timestamp)
|
database.glucoseValueDao.compatGetBgReadingsDataFromTime(timestamp)
|
||||||
.map { if (!ascending) it.reversed() else it }
|
.map { if (!ascending) it.reversed() else it }
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
fun compatGetBgReadingsDataFromTime(start: Long, end: Long, ascending: Boolean) =
|
fun compatGetBgReadingsDataFromTime(start: Long, end: Long, ascending: Boolean): Single<List<GlucoseValue>> =
|
||||||
database.glucoseValueDao.compatGetBgReadingsDataFromTime(start, end)
|
database.glucoseValueDao.compatGetBgReadingsDataFromTime(start, end)
|
||||||
.map { if (!ascending) it.reversed() else it }
|
.map { if (!ascending) it.reversed() else it }
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
@ -74,23 +74,23 @@ class AppRepository @Inject internal constructor(
|
||||||
fun findBgReadingByNSIdSingle(nsId: String): Single<ValueWrapper<GlucoseValue>> =
|
fun findBgReadingByNSIdSingle(nsId: String): Single<ValueWrapper<GlucoseValue>> =
|
||||||
database.glucoseValueDao.findByNSIdMaybe(nsId).toWrappedSingle()
|
database.glucoseValueDao.findByNSIdMaybe(nsId).toWrappedSingle()
|
||||||
|
|
||||||
fun getModifiedBgReadingsDataFromId(lastId: Long) =
|
fun getModifiedBgReadingsDataFromId(lastId: Long): Single<List<GlucoseValue>> =
|
||||||
database.glucoseValueDao.getModifiedFrom(lastId)
|
database.glucoseValueDao.getModifiedFrom(lastId)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
fun getBgReadingsCorrespondingLastHistoryRecord(lastId: Long) =
|
fun getBgReadingsCorrespondingLastHistoryRecord(lastId: Long): GlucoseValue? =
|
||||||
database.glucoseValueDao.getLastHistoryRecord(lastId)
|
database.glucoseValueDao.getLastHistoryRecord(lastId)
|
||||||
|
|
||||||
@Suppress("unused") // debug purpose only
|
@Suppress("unused") // debug purpose only
|
||||||
fun getAllBgReadingsStartingFrom(lastId: Long) =
|
fun getAllBgReadingsStartingFrom(lastId: Long): Single<List<GlucoseValue>> =
|
||||||
database.glucoseValueDao.getAllStartingFrom(lastId)
|
database.glucoseValueDao.getAllStartingFrom(lastId)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
// TEMP TARGETS
|
// TEMP TARGETS
|
||||||
fun compatGetTemporaryTargetData() =
|
fun compatGetTemporaryTargetData(): List<TemporaryTarget> =
|
||||||
database.temporaryTargetDao.compatGetTemporaryTargetData()
|
database.temporaryTargetDao.compatGetTemporaryTargetData()
|
||||||
|
|
||||||
fun compatGetTemporaryTargetDataFromTime(timestamp: Long, ascending: Boolean) =
|
fun compatGetTemporaryTargetDataFromTime(timestamp: Long, ascending: Boolean): Single<List<TemporaryTarget>> =
|
||||||
database.temporaryTargetDao.compatGetTemporaryTargetDataFromTime(timestamp)
|
database.temporaryTargetDao.compatGetTemporaryTargetDataFromTime(timestamp)
|
||||||
.map { if (!ascending) it.reversed() else it }
|
.map { if (!ascending) it.reversed() else it }
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
@ -98,16 +98,16 @@ class AppRepository @Inject internal constructor(
|
||||||
fun findTemporaryTargetByNSIdSingle(nsId: String): Single<ValueWrapper<TemporaryTarget>> =
|
fun findTemporaryTargetByNSIdSingle(nsId: String): Single<ValueWrapper<TemporaryTarget>> =
|
||||||
database.temporaryTargetDao.findByNSIdMaybe(nsId).toWrappedSingle()
|
database.temporaryTargetDao.findByNSIdMaybe(nsId).toWrappedSingle()
|
||||||
|
|
||||||
fun getModifiedTemporaryTargetsDataFromId(lastId: Long) =
|
fun getModifiedTemporaryTargetsDataFromId(lastId: Long): Single<List<TemporaryTarget>> =
|
||||||
database.temporaryTargetDao.getModifiedFrom(lastId)
|
database.temporaryTargetDao.getModifiedFrom(lastId)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
|
|
||||||
fun getTemporaryTargetsCorrespondingLastHistoryRecord(lastId: Long) =
|
fun getTemporaryTargetsCorrespondingLastHistoryRecord(lastId: Long): TemporaryTarget? =
|
||||||
database.temporaryTargetDao.getLastHistoryRecord(lastId)
|
database.temporaryTargetDao.getLastHistoryRecord(lastId)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@Suppress("USELESS_CAST")
|
||||||
inline fun <reified T> Maybe<T>.toWrappedSingle(): Single<ValueWrapper<T>> =
|
inline fun <reified T : Any> Maybe<T>.toWrappedSingle(): Single<ValueWrapper<T>> =
|
||||||
this.map { ValueWrapper.Existing(it) as ValueWrapper<T> }
|
this.map { ValueWrapper.Existing(it) as ValueWrapper<T> }
|
||||||
.switchIfEmpty(Maybe.just(ValueWrapper.Absent()))
|
.switchIfEmpty(Maybe.just(ValueWrapper.Absent()))
|
||||||
.toSingle()
|
.toSingle()
|
||||||
|
|
|
@ -90,11 +90,18 @@ data class GlucoseValue(
|
||||||
@SerializedName("MM600Series") MM_600_SERIES("MM600Series"),
|
@SerializedName("MM600Series") MM_600_SERIES("MM600Series"),
|
||||||
@SerializedName("Eversense") EVERSENSE("Eversense"),
|
@SerializedName("Eversense") EVERSENSE("Eversense"),
|
||||||
@SerializedName("Random") RANDOM("Random"),
|
@SerializedName("Random") RANDOM("Random"),
|
||||||
@SerializedName("Unknown") UNKNOWN("Unknown")
|
@SerializedName("Unknown") UNKNOWN("Unknown"),
|
||||||
|
|
||||||
|
@SerializedName("IOBPrediction") IOB_PREDICTION("IOBPrediction"),
|
||||||
|
@SerializedName("aCOBPrediction") aCOB_PREDICTION("aCOBPrediction"),
|
||||||
|
@SerializedName("COBPrediction") COB_PREDICTION("COBPrediction"),
|
||||||
|
@SerializedName("UAMPrediction") UAM_PREDICTION("UAMPrediction"),
|
||||||
|
@SerializedName("ZTPrediction") ZT_PREDICTION("ZTPrediction")
|
||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromString(source : String?) = values().firstOrNull {it.text == source} ?: UNKNOWN
|
|
||||||
|
fun fromString(source: String?) = values().firstOrNull { it.text == source } ?: UNKNOWN
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,11 +9,14 @@ import info.nightscout.androidaps.database.entities.TherapyEvent
|
||||||
class CgmSourceTransaction(
|
class CgmSourceTransaction(
|
||||||
private val glucoseValues: List<TransactionGlucoseValue>,
|
private val glucoseValues: List<TransactionGlucoseValue>,
|
||||||
private val calibrations: List<Calibration>,
|
private val calibrations: List<Calibration>,
|
||||||
private val sensorInsertionTime: Long?
|
private val sensorInsertionTime: Long?,
|
||||||
) : Transaction<List<GlucoseValue>>() {
|
private val syncer: Boolean = false // caller is not native source ie. NS
|
||||||
|
// syncer is allowed create records
|
||||||
|
// update synchronization ID
|
||||||
|
) : Transaction<CgmSourceTransaction.TransactionResult>() {
|
||||||
|
|
||||||
override fun run(): List<GlucoseValue> {
|
override fun run(): TransactionResult {
|
||||||
val insertedGlucoseValues = mutableListOf<GlucoseValue>()
|
val result = TransactionResult()
|
||||||
glucoseValues.forEach {
|
glucoseValues.forEach {
|
||||||
val current = database.glucoseValueDao.findByTimestampAndSensor(it.timestamp, it.sourceSensor)
|
val current = database.glucoseValueDao.findByTimestampAndSensor(it.timestamp, it.sourceSensor)
|
||||||
val glucoseValue = GlucoseValue(
|
val glucoseValue = GlucoseValue(
|
||||||
|
@ -25,15 +28,26 @@ class CgmSourceTransaction(
|
||||||
sourceSensor = it.sourceSensor
|
sourceSensor = it.sourceSensor
|
||||||
)
|
)
|
||||||
glucoseValue.interfaceIDs.nightscoutId = it.nightscoutId
|
glucoseValue.interfaceIDs.nightscoutId = it.nightscoutId
|
||||||
|
// if nsId is not provided in new record, copy from current if exists
|
||||||
|
if (glucoseValue.interfaceIDs.nightscoutId == null)
|
||||||
|
current?.let { existing -> glucoseValue.interfaceIDs.nightscoutId = existing.interfaceIDs.nightscoutId }
|
||||||
when {
|
when {
|
||||||
|
// new record, create new
|
||||||
current == null -> {
|
current == null -> {
|
||||||
database.glucoseValueDao.insertNewEntry(glucoseValue)
|
database.glucoseValueDao.insertNewEntry(glucoseValue)
|
||||||
insertedGlucoseValues.add(glucoseValue)
|
result.inserted.add(glucoseValue)
|
||||||
}
|
}
|
||||||
|
// different record, update
|
||||||
!current.contentEqualsTo(glucoseValue) -> {
|
!current.contentEqualsTo(glucoseValue) && !syncer -> {
|
||||||
glucoseValue.id = current.id
|
glucoseValue.id = current.id
|
||||||
database.glucoseValueDao.updateExistingEntry(glucoseValue)
|
database.glucoseValueDao.updateExistingEntry(glucoseValue)
|
||||||
|
result.updated.add(glucoseValue)
|
||||||
|
}
|
||||||
|
// update NS id if didn't exist and now provided
|
||||||
|
current.interfaceIDs.nightscoutId == null && it.nightscoutId != null && syncer -> {
|
||||||
|
glucoseValue.id = current.id
|
||||||
|
database.glucoseValueDao.updateExistingEntry(glucoseValue)
|
||||||
|
result.updated.add(glucoseValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,7 +68,7 @@ class CgmSourceTransaction(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return insertedGlucoseValues
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
data class TransactionGlucoseValue(
|
data class TransactionGlucoseValue(
|
||||||
|
@ -71,4 +85,16 @@ class CgmSourceTransaction(
|
||||||
val timestamp: Long,
|
val timestamp: Long,
|
||||||
val value: Double
|
val value: Double
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class TransactionResult {
|
||||||
|
|
||||||
|
val inserted = mutableListOf<GlucoseValue>()
|
||||||
|
val updated = mutableListOf<GlucoseValue>()
|
||||||
|
|
||||||
|
fun all(): MutableList<GlucoseValue> =
|
||||||
|
mutableListOf<GlucoseValue>().also { result ->
|
||||||
|
result.addAll(inserted)
|
||||||
|
result.addAll(updated)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue